You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1720 lines
55 KiB
1720 lines
55 KiB
/* file: mbftsend.cpp */
|
|
|
|
#include "mbftpch.h"
|
|
|
|
#include "mbftsend.hpp"
|
|
#include "fileio.hpp"
|
|
#include "messages.hpp"
|
|
#include "mbftapi.hpp"
|
|
|
|
#define _MAX_SEND_PACKETS 1
|
|
|
|
ULONG g_nSendDisbandDelay = 5000; // Previous: Twenty seconds!
|
|
ULONG g_nChannelResponseDelay = 60000;
|
|
|
|
|
|
MBFTPrivateSend::MBFTPrivateSend
|
|
(
|
|
LPMBFTENGINE lpParentEngine,
|
|
MBFTEVENTHANDLE EventHandle,
|
|
T120ChannelID wMBFTUserID,
|
|
ULONG MaxDataLength
|
|
)
|
|
:
|
|
MBFTSession(lpParentEngine, EventHandle, MBFT_PRIVATE_SEND_TYPE),
|
|
m_PrivateMBFTControlChannel(0),
|
|
m_PrivateMBFTDataChannel(0),
|
|
|
|
m_lpUserArray(NULL),
|
|
m_lpAcceptedUsersArray(NULL),
|
|
|
|
m_iUserCount(0),
|
|
|
|
m_MBFTChannelID(wMBFTUserID),
|
|
m_MaxDataLength(MaxDataLength),
|
|
|
|
m_LastUserCount(0),
|
|
m_ResponseCount(0),
|
|
m_AcceptCount(0),
|
|
m_RejectCount(0),
|
|
m_AbortedCount(0),
|
|
m_AcknowledgeCount(0),
|
|
|
|
m_CurrentFileSize(0),
|
|
m_lTotalBytesRead(0),
|
|
m_lpDataBuffer(NULL),
|
|
|
|
m_bProshareTransfer(FALSE),
|
|
m_bEOFAcknowledge(FALSE),
|
|
|
|
m_lpFile(NULL),
|
|
m_pszCurrentFilePath(NULL),
|
|
m_CurrentFileHandle(0),
|
|
m_AcceptedIndex(0),
|
|
|
|
m_bSentFileOfferPDU(FALSE),
|
|
m_bUnInitializing(FALSE),
|
|
m_bAbortAllFiles(FALSE),
|
|
m_bSendingFile(FALSE),
|
|
m_bAbortFileSend(FALSE),
|
|
m_SentFileStartPDU(FALSE),
|
|
m_TimeOutValue(0),
|
|
m_bCompressFiles(FALSE),
|
|
m_bOKToDisbandChannel(TRUE),
|
|
|
|
m_lpV42bisPointer(NULL),
|
|
m_bFlushv42Compression(FALSE),
|
|
m_bEventEndPosted(FALSE),
|
|
|
|
m_State(EnumIdleNotInitialized)
|
|
{
|
|
}
|
|
|
|
MBFTPrivateSend::~MBFTPrivateSend(void)
|
|
{
|
|
delete m_pszCurrentFilePath;
|
|
delete m_lpUserArray;
|
|
delete m_lpAcceptedUsersArray;
|
|
delete m_lpDataBuffer;
|
|
delete m_lpFile;
|
|
}
|
|
|
|
void MBFTPrivateSend::ConveneControlChannel(void)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelConveneRequest())
|
|
{
|
|
m_State = EnumWaitConveneControlChannel;
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::ConveneDataChannel(void)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelConveneRequest())
|
|
{
|
|
m_State = EnumWaitConveneDataChannel;
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::JoinControlChannel(void)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelJoinRequest(m_PrivateMBFTControlChannel))
|
|
{
|
|
m_State = EnumWaitJoinControlChannel;
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnMCSChannelJoinConfirm
|
|
(
|
|
T120ChannelID wChannelId,
|
|
BOOL bSuccess
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(wChannelId == m_PrivateMBFTControlChannel)
|
|
{
|
|
if(m_State == EnumWaitJoinControlChannel)
|
|
{
|
|
if(bSuccess)
|
|
{
|
|
TRACESEND(" Control channel joined [%u]\n",wChannelId);
|
|
|
|
ConveneDataChannel();
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
void MBFTPrivateSend::AdmitControlChannel(void)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelAdmitRequest(m_PrivateMBFTControlChannel,
|
|
m_lpUserArray,
|
|
m_iUserCount))
|
|
{
|
|
TRACESEND(" Admit Control Channel Successful [%u]\n",m_PrivateMBFTControlChannel);
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
|
|
if(m_lpParentEngine->MCSChannelAdmitRequest(m_PrivateMBFTDataChannel,
|
|
m_lpUserArray,
|
|
m_iUserCount))
|
|
{
|
|
TRACESEND(" Admit Data Channel Successful [%u]\n",m_PrivateMBFTDataChannel);
|
|
|
|
m_State = EnumWaitChannelResponsePDU;
|
|
|
|
m_TimeOutValue = GetTickCount() + g_nChannelResponseDelay;
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnMCSChannelConveneConfirm
|
|
(
|
|
T120ChannelID wChannelId,
|
|
BOOL bSuccess
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumWaitConveneControlChannel)
|
|
{
|
|
if(bSuccess)
|
|
{
|
|
TRACESEND(" Control channel convened [%u]\n",wChannelId);
|
|
m_PrivateMBFTControlChannel = wChannelId;
|
|
JoinControlChannel();
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
|
|
bReturn = TRUE;
|
|
}
|
|
else if(m_State == EnumWaitConveneDataChannel)
|
|
{
|
|
if(bSuccess)
|
|
{
|
|
TRACESEND(" Data channel convened [%u]\n",wChannelId);
|
|
m_PrivateMBFTDataChannel = wChannelId;
|
|
m_State = EnumWaitSendChannelInvitePDU;
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
|
|
bReturn = TRUE;
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::SubmitFileSendRequest
|
|
(
|
|
SubmitFileSendMsg *pMsg
|
|
)
|
|
{
|
|
BOOL bCompressFiles = pMsg->m_bCompressFiles;
|
|
|
|
delete m_pszCurrentFilePath; // clean up any possible left over
|
|
m_pszCurrentFilePath = pMsg->m_pszFilePath;
|
|
m_CurrentFileHandle = pMsg->m_nFileHandle;
|
|
pMsg->m_pszFilePath = NULL; // keep this pointer for furure use
|
|
|
|
MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
|
|
MBFT_ERROR_TYPES iErrorType = MBFT_PERMANENT_ERROR;
|
|
|
|
//NOTE: Merely turning this flag to TRUE will NOT
|
|
//enable compression. I have set it to FALSE here
|
|
//so that certain stubbed routines will not be
|
|
//entered. If you turn this flag to TRUE....
|
|
//then...have your finger ready on the reset button!!
|
|
//If you want to turn compression on, Then you have
|
|
//to include a bunch of v42.bis compression files etc.
|
|
bCompressFiles = FALSE;
|
|
|
|
// get the peer list
|
|
CPeerList *pPeerList = m_lpParentEngine->GetPeerList();
|
|
|
|
ASSERT(! (pMsg->m_nUserID && pMsg->m_nNodeID));
|
|
BOOL fBroadcast = (0 == pMsg->m_nUserID && 0 == pMsg->m_nNodeID);
|
|
ULONG iNumNodes = 1;
|
|
if (fBroadcast)
|
|
{
|
|
iNumNodes = pPeerList->GetCount();
|
|
ASSERT(iNumNodes);
|
|
}
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpDataBuffer = new char[m_MaxDataLength + MAX_PATH + _iMBFT_FILEDATA_PDU_SUBTRACT]; // enough space for the largest PDU
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpUserArray = new UserID[iNumNodes];
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpAcceptedUsersArray = new UserID[iNumNodes];
|
|
|
|
if (NULL == m_lpDataBuffer || NULL == m_lpUserArray || NULL == m_lpAcceptedUsersArray)
|
|
{
|
|
ERROR_OUT(("MBFTPrivateSend::SubmitFileSendRequest: allocation failure"));
|
|
delete m_lpDataBuffer; m_lpDataBuffer = NULL;
|
|
delete m_lpUserArray; m_lpUserArray = NULL;
|
|
delete m_lpAcceptedUsersArray; m_lpAcceptedUsersArray = NULL;
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
|
|
if(iErrorCode == iMBFT_OK)
|
|
{
|
|
m_iUserCount = 0;
|
|
|
|
ZeroMemory(m_lpUserArray, sizeof(UserID) * iNumNodes);
|
|
ZeroMemory(m_lpAcceptedUsersArray, sizeof(UserID) * iNumNodes);
|
|
|
|
m_bProshareTransfer = TRUE;
|
|
m_bEOFAcknowledge = TRUE;
|
|
if (fBroadcast)
|
|
{
|
|
CPeerData *lpPeer;
|
|
pPeerList->Reset();
|
|
while (NULL != (lpPeer = pPeerList->Iterate()))
|
|
{
|
|
if (lpPeer->GetUserID() != m_lpParentEngine->GetUserID())
|
|
{
|
|
m_lpUserArray[m_iUserCount++] = lpPeer->GetUserID();
|
|
|
|
if(m_bProshareTransfer)
|
|
{
|
|
m_bProshareTransfer = lpPeer->GetIsProshareNode();
|
|
}
|
|
if(m_bEOFAcknowledge)
|
|
{
|
|
m_bEOFAcknowledge = lpPeer->GetEOFAcknowledge();
|
|
}
|
|
}
|
|
} // while
|
|
}
|
|
else
|
|
{
|
|
CPeerData *lpPeer;
|
|
pPeerList->Reset();
|
|
while (NULL != (lpPeer = pPeerList->Iterate()))
|
|
{
|
|
if ((pMsg->m_nUserID && pMsg->m_nUserID == lpPeer->GetUserID())
|
|
||
|
|
(pMsg->m_nNodeID && pMsg->m_nNodeID == lpPeer->GetNodeID()))
|
|
{
|
|
m_lpUserArray[m_iUserCount++] = lpPeer->GetUserID();
|
|
|
|
if(m_bProshareTransfer)
|
|
{
|
|
m_bProshareTransfer = lpPeer->GetIsProshareNode();
|
|
}
|
|
if(m_bEOFAcknowledge)
|
|
{
|
|
m_bEOFAcknowledge = lpPeer->GetEOFAcknowledge();
|
|
}
|
|
break;
|
|
}
|
|
} // while
|
|
if (NULL == lpPeer)
|
|
{
|
|
iErrorCode = iMBFT_RECIPIENT_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
if(m_bCompressFiles)
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
else
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpFile = new CMBFTFile;
|
|
}
|
|
|
|
if(!m_lpFile)
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
|
|
if(iErrorCode == iMBFT_OK)
|
|
{
|
|
m_State = EnumFileSendPending;
|
|
}
|
|
}
|
|
|
|
if(iErrorCode != iMBFT_OK)
|
|
{
|
|
// LOGERROR(iErrorCode,0,0);
|
|
|
|
ReportError(iErrorType,iErrorCode,TRUE);
|
|
TerminateSendSession();
|
|
}
|
|
|
|
return(iErrorCode == iMBFT_OK);
|
|
}
|
|
|
|
void MBFTPrivateSend::ReportSenderError
|
|
(
|
|
int iErrorType,
|
|
int iErrorCode,
|
|
MBFTFILEHANDLE hFile
|
|
)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
FileErrorPDU * lpNewPDU = new FileErrorPDU((hFile) ?
|
|
LOWORD(hFile) :
|
|
LOWORD(m_CurrentFileHandle),
|
|
iErrorType,iErrorCode);
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
for (ULONG Index = 0; Index < m_iUserCount; Index++)
|
|
{
|
|
m_lpParentEngine->SendDataRequest(m_lpUserArray[Index],
|
|
APPLET_HIGH_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength());
|
|
}
|
|
}
|
|
|
|
delete lpNewPDU;
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::ReportError
|
|
(
|
|
int iErrorType,
|
|
int iErrorCode,
|
|
BOOL bIsLocalError,
|
|
T120UserID SenderID,
|
|
MBFTFILEHANDLE FileHandle)
|
|
{
|
|
T120UserID id = SenderID ? SenderID : m_MBFTChannelID;
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpParentEngine->SafePostNotifyMessage(
|
|
new FileErrorMsg(
|
|
m_EventHandle,
|
|
FileHandle ? FileHandle : m_CurrentFileHandle,
|
|
iErrorType,
|
|
iErrorCode,
|
|
bIsLocalError,
|
|
id));
|
|
}
|
|
|
|
void MBFTPrivateSend::TerminateSendSession(void)
|
|
{
|
|
UnInitialize();
|
|
}
|
|
|
|
|
|
void MBFTPrivateSend::UnInitialize
|
|
(
|
|
BOOL bShutDown
|
|
)
|
|
{
|
|
BOOL bDataChannelDisbanded = FALSE;
|
|
BOOL bControlChannelDisbanded = FALSE;
|
|
|
|
if(m_State != EnumWaitForTermination)
|
|
{
|
|
m_State = EnumWaitForTermination;
|
|
|
|
TRACESEND(" Uninit begin\n");
|
|
|
|
if (m_bEOFAcknowledge)
|
|
{
|
|
m_TimeOutValue = 0;
|
|
}
|
|
else
|
|
{
|
|
m_TimeOutValue = GetTickCount() + g_nSendDisbandDelay;
|
|
}
|
|
TRACESEND(" Using TimeOutValue of %d\n", m_TimeOutValue);
|
|
}
|
|
|
|
m_bUnInitializing = TRUE;
|
|
|
|
if(GetTickCount() >= m_TimeOutValue)
|
|
{
|
|
if(m_PrivateMBFTDataChannel)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelDisbandRequest(m_PrivateMBFTDataChannel))
|
|
{
|
|
TRACESEND(" Uninit: Data Channel disbanded [%u]\n",m_PrivateMBFTDataChannel);
|
|
bDataChannelDisbanded = TRUE;
|
|
m_PrivateMBFTDataChannel = 0;
|
|
}
|
|
else if(m_lpParentEngine->GetLastSendDataError() == MCS_TRANSMIT_BUFFER_FULL)
|
|
{
|
|
TRACESEND("Transmit buffer for [%u] full, data channel disband failed\n",m_PrivateMBFTDataChannel);
|
|
}
|
|
else
|
|
{
|
|
TRACESEND("Unexpected error [%u] while disbanding data channel [%u]\n",
|
|
m_lpParentEngine->GetLastSendDataError(),m_PrivateMBFTDataChannel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDataChannelDisbanded = TRUE;
|
|
}
|
|
|
|
if(bDataChannelDisbanded)
|
|
{
|
|
if(m_PrivateMBFTControlChannel)
|
|
{
|
|
if(m_lpParentEngine->MCSChannelDisbandRequest(m_PrivateMBFTControlChannel))
|
|
{
|
|
TRACESEND(" Uninit: Control Channel disbanded [%u]\n",m_PrivateMBFTControlChannel);
|
|
bControlChannelDisbanded = TRUE;
|
|
m_PrivateMBFTControlChannel = 0;
|
|
}
|
|
else if(m_lpParentEngine->GetLastSendDataError() == MCS_TRANSMIT_BUFFER_FULL)
|
|
{
|
|
TRACESEND("Transmit buffer for [%u] full, control channel disband failed\n",m_PrivateMBFTDataChannel);
|
|
}
|
|
else
|
|
{
|
|
TRACESEND("Unexpected error [%u] while disbanding control channel [%u]\n",
|
|
m_lpParentEngine->GetLastSendDataError(),m_PrivateMBFTDataChannel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bControlChannelDisbanded = TRUE;
|
|
}
|
|
}
|
|
|
|
if(!bShutDown)
|
|
{
|
|
if(bDataChannelDisbanded && bControlChannelDisbanded)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpParentEngine->SafePostMessage(new DeleteSessionMsg(this));
|
|
|
|
if(!m_bEventEndPosted)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
|
|
m_bEventEndPosted = TRUE;
|
|
}
|
|
TRACESEND(" Uninit complete\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACESEND(" Uninit complete\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::SendChannelInvitePDU(void)
|
|
{
|
|
MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
|
|
MBFT_ERROR_TYPES iErrorType = MBFT_PERMANENT_ERROR;
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
LPPRIVATECHANNELINVITEPDU lpNewPDU = new PrivateChannelInvitePDU(m_PrivateMBFTControlChannel,
|
|
m_PrivateMBFTDataChannel,
|
|
FALSE);
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
for (ULONG Index = m_LastUserCount;Index < m_iUserCount;Index++)
|
|
{
|
|
if(m_lpParentEngine->SendDataRequest(m_lpUserArray[Index],
|
|
APPLET_HIGH_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength()))
|
|
{
|
|
TRACESEND(" Sent Channel invite PDU, Control Channel [%u], Data Channel [%u] to [%u]\n",m_PrivateMBFTControlChannel,m_PrivateMBFTDataChannel,m_lpUserArray[Index]);
|
|
|
|
m_LastUserCount++;
|
|
}
|
|
else
|
|
{
|
|
m_State = EnumWaitSendChannelInvitePDU;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(Index >= m_iUserCount)
|
|
{
|
|
AdmitControlChannel();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
|
|
}
|
|
|
|
delete lpNewPDU;
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
|
|
if(iErrorCode != iMBFT_OK)
|
|
{
|
|
ReportError(iErrorType,iErrorCode,TRUE);
|
|
UnInitialize();
|
|
}
|
|
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedFileAbortPDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPFILEABORTPDU lpFileAbortPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
MBFTFILEHANDLE hFile = lpFileAbortPDU->GetFileHandle();
|
|
|
|
if (hFile && hFile == m_CurrentFileHandle)
|
|
{
|
|
if (m_bUnInitializing)
|
|
{
|
|
OnControlNotification(hFile,
|
|
FileTransferControlMsg::EnumConductorAbortFile,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
return TRUE; // handled
|
|
}
|
|
|
|
return FALSE; // not handled
|
|
}
|
|
|
|
|
|
void MBFTPrivateSend::DoStateMachine(void)
|
|
{
|
|
if(m_State == EnumFileSendPending)
|
|
{
|
|
ConveneControlChannel();
|
|
}
|
|
else if(m_State == EnumWaitRequestControlConvene)
|
|
{
|
|
ConveneControlChannel();
|
|
}
|
|
else if(m_State == EnumWaitRequestJoinControl)
|
|
{
|
|
JoinControlChannel();
|
|
}
|
|
else if(m_State == EnumWaitRequestDataConvene)
|
|
{
|
|
ConveneDataChannel();
|
|
}
|
|
else if(m_State == EnumWaitSendChannelInvitePDU)
|
|
{
|
|
SendChannelInvitePDU();
|
|
}
|
|
else if(m_State == EnumSendNonStandardPDU)
|
|
{
|
|
TRACESEND(" Not Sending a NonStandardPDU");
|
|
m_State = EnumSendFileOfferPDU;
|
|
SendFileOfferPDU();
|
|
}
|
|
else if(m_State == EnumSendFileOfferPDU)
|
|
{
|
|
SendFileOfferPDU();
|
|
}
|
|
else if(m_State == EnumSendFileStartPDU)
|
|
{
|
|
SendFileStartPDU();
|
|
}
|
|
else if(m_State == EnumSendFileDataPDU)
|
|
{
|
|
SendFileDataPDU();
|
|
}
|
|
else if(m_State == EnumTerminateCurrentSend)
|
|
{
|
|
TerminateCurrentSend();
|
|
}
|
|
else if(m_State == EnumWaitForTermination)
|
|
{
|
|
UnInitialize();
|
|
}
|
|
else if(m_State == EnumWaitChannelResponsePDU)
|
|
{
|
|
if(GetTickCount() >= m_TimeOutValue)
|
|
{
|
|
// LOGERROR(iMBFT_TIMEOUT_ERROR,0,0);
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_TIMEOUT_ERROR,TRUE);
|
|
UnInitialize();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
BOOL MBFTPrivateSend::OnReceivedPrivateChannelResponsePDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPPRIVATECHANNELRESPONSEPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumWaitChannelResponsePDU)
|
|
{
|
|
if(wChannelId == m_MBFTChannelID &&
|
|
lpNewPDU->GetControlChannel() == m_PrivateMBFTControlChannel)
|
|
{
|
|
bReturn = TRUE;
|
|
|
|
TRACESEND(" Received Channel response PDU from [%u]\n",SenderID);
|
|
|
|
for (ULONG Index = 0; Index < m_iUserCount; Index++)
|
|
{
|
|
if(m_lpUserArray[Index] == SenderID)
|
|
{
|
|
m_ResponseCount++;
|
|
}
|
|
}
|
|
|
|
if(!lpNewPDU->GetWasChannelJoined())
|
|
{
|
|
ReportError(MBFT_INFORMATIVE_ERROR,
|
|
iMBFT_RECEIVER_ABORTED,
|
|
FALSE,
|
|
SenderID,
|
|
_iMBFT_PROSHARE_ALL_FILES);
|
|
|
|
RemoveUserFromList(SenderID);
|
|
}
|
|
|
|
if(m_iUserCount)
|
|
{
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
m_State = (! m_bProshareTransfer) ? EnumSendFileOfferPDU :
|
|
EnumSendNonStandardPDU;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
void MBFTPrivateSend::SendFileOfferPDU(void)
|
|
{
|
|
MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
|
|
MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
|
|
|
|
m_AcceptCount = 0;
|
|
m_RejectCount = 0;
|
|
m_ResponseCount = 0;
|
|
m_AcknowledgeCount = 0;
|
|
m_lTotalBytesRead = 0;
|
|
m_SentFileStartPDU = FALSE;
|
|
m_AbortedCount = 0;
|
|
m_bSentFileOfferPDU = FALSE;
|
|
m_AcceptedIndex = 0;
|
|
|
|
::ZeroMemory(m_lpAcceptedUsersArray, sizeof(UserID) * m_iUserCount);
|
|
|
|
if (m_lpFile->Open(m_pszCurrentFilePath, CMBFTFile::OpenReadOnly | CMBFTFile::OpenBinary))
|
|
{
|
|
m_CurrentFileSize = m_lpFile->GetFileSize();
|
|
m_CurrentDateTime = m_lpFile->GetFileDateTime();
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
LPFILEOFFERPDU lpNewPDU = new FileOfferPDU(GetFileNameFromPath(m_pszCurrentFilePath),
|
|
LOWORD(m_CurrentFileHandle),
|
|
m_CurrentFileSize,
|
|
m_CurrentDateTime,
|
|
m_PrivateMBFTDataChannel,TRUE,
|
|
m_lpParentEngine->GetRosterInstance(),
|
|
0, NULL, 0, 0);
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
|
|
APPLET_HIGH_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength()))
|
|
{
|
|
TRACESEND(" Transmitted File Offer PDU for [%u] on [%u]\n",LOWORD(m_CurrentFileHandle),m_PrivateMBFTControlChannel);
|
|
|
|
//Now that we have sent a FileOfferPDU, we can't disband the channel
|
|
//without notice....
|
|
|
|
m_bOKToDisbandChannel = FALSE;
|
|
|
|
m_bSentFileOfferPDU = TRUE;
|
|
m_State = EnumWaitFileAcceptPDU;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
|
|
}
|
|
|
|
delete lpNewPDU;
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
|
|
|
|
//iMBFT_FILE_IO_ERROR;
|
|
}
|
|
|
|
if(iErrorCode != iMBFT_OK)
|
|
{
|
|
ReportError(iErrorType,iErrorCode,TRUE);
|
|
|
|
if(m_bSentFileOfferPDU)
|
|
{
|
|
//If a FileOffer has been sent out, we need to send a FileStartPDU with
|
|
//EOF = TRUE...
|
|
|
|
TerminateCurrentSend();
|
|
}
|
|
else
|
|
{
|
|
ReportError(MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,TRUE,
|
|
m_MBFTChannelID,m_CurrentFileHandle);
|
|
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedFileAcceptPDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPFILEACCEPTPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumWaitFileAcceptPDU)
|
|
{
|
|
if(wChannelId == m_MBFTChannelID)
|
|
{
|
|
if(lpNewPDU->GetFileHandle() == m_CurrentFileHandle)
|
|
{
|
|
TRACESEND(" Received file accept PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
|
|
|
|
bReturn = TRUE;
|
|
|
|
for (ULONG Index = 0; Index < m_iUserCount; Index++)
|
|
{
|
|
if(m_lpUserArray[Index] == SenderID)
|
|
{
|
|
if(m_AcceptedIndex < m_iUserCount)
|
|
{
|
|
m_lpAcceptedUsersArray[m_AcceptedIndex++] = SenderID;
|
|
}
|
|
|
|
m_AcceptCount++;
|
|
m_ResponseCount++;
|
|
}
|
|
}
|
|
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
m_State = EnumSendFileStartPDU;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedFileRejectPDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPFILEREJECTPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumWaitFileAcceptPDU)
|
|
{
|
|
if(wChannelId == m_MBFTChannelID)
|
|
{
|
|
MBFTFILEHANDLE iFileHandle = lpNewPDU->GetFileHandle();
|
|
|
|
if((iFileHandle == m_CurrentFileHandle) ||
|
|
((iFileHandle == LOWORD(_iMBFT_PROSHARE_ALL_FILES)) && m_bProshareTransfer))
|
|
{
|
|
TRACESEND(" Received file reject PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
|
|
|
|
for(ULONG Index = 0;Index < m_iUserCount;Index++)
|
|
{
|
|
if(m_lpUserArray[Index] == SenderID)
|
|
{
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
|
|
if(bReturn)
|
|
{
|
|
if(iFileHandle == m_CurrentFileHandle)
|
|
{
|
|
m_RejectCount++;
|
|
m_ResponseCount++;
|
|
|
|
}
|
|
else if((iFileHandle == LOWORD(_iMBFT_PROSHARE_ALL_FILES)) && m_bProshareTransfer)
|
|
{
|
|
|
|
RemoveUserFromList(SenderID);
|
|
}
|
|
|
|
if(m_iUserCount)
|
|
{
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
if(m_ResponseCount != m_RejectCount)
|
|
{
|
|
m_State = EnumSendFileStartPDU;
|
|
}
|
|
else
|
|
{
|
|
m_lpFile->Close();
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
} //if bReturn
|
|
}
|
|
} //wChannelId == m_MBFTChannelID
|
|
} //m_State == EnumWaitFileAcceptPDU
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedFileErrorPDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPFILEERRORPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
MBFTFILEHANDLE FileHandle = lpNewPDU->GetFileHandle();
|
|
|
|
if ((m_CurrentFileHandle == FileHandle) ||
|
|
(m_bProshareTransfer && (LOWORD(FileHandle) == LOWORD(_iMBFT_PROSHARE_ALL_FILES))))
|
|
{
|
|
TRACERECEIVE(" FileErrorPDU from [%u] for [%u], ErrorCode: [%u]\n",SenderID,lpNewPDU->GetFileHandle(),lpNewPDU->GetErrorCode());
|
|
|
|
if(m_bProshareTransfer)
|
|
{
|
|
if(m_State != EnumWaitForTermination)
|
|
{
|
|
if(lpNewPDU->GetErrorCode() == iMBFT_RECEIVER_ABORTED &&
|
|
lpNewPDU->GetFileHandle() == LOWORD(_iMBFT_PROSHARE_ALL_FILES))
|
|
{
|
|
m_AbortedCount++;
|
|
|
|
RemoveUserFromList(SenderID);
|
|
|
|
//If the state is EnumWaitFileAcceptPDU, we don't
|
|
//have an exact count of the number of recipients who accepted
|
|
//the file. Therefore, we cannot make a decision on whether or not
|
|
//to abort the file based on AcceptCount and AbortedCount....
|
|
|
|
if(m_State != EnumWaitFileAcceptPDU)
|
|
{
|
|
if(m_iUserCount)
|
|
{
|
|
if(m_AbortedCount >= m_AcceptCount)
|
|
{
|
|
m_lpFile->Close();
|
|
SendNextFile();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_lpFile->Close();
|
|
}
|
|
}
|
|
else if(m_iUserCount)
|
|
{
|
|
//In this case, the FileErrorPDU acts as a FileRejectPDU...
|
|
|
|
TRACERECEIVE(" Treating FileErrorPDU for [%u] as FileRejectPDU\n",lpNewPDU->GetFileHandle());
|
|
|
|
//m_RejectCount++;
|
|
//m_ResponseCount++;
|
|
|
|
//In this case, response count has to be greater
|
|
//because a user was just deleted!!!
|
|
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
if(m_ResponseCount != m_RejectCount)
|
|
{
|
|
m_State = EnumSendFileStartPDU;
|
|
}
|
|
else
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (FileHandle == m_CurrentFileHandle)
|
|
{
|
|
m_AbortedCount++;
|
|
|
|
//If the state is EnumWaitFileAcceptPDU, we don't
|
|
//have an exact count of the number of recipients who accepted
|
|
//the file. Therefore, we cannot make a decision on whether or not
|
|
//to abort the file based on AcceptCount and AbortedCount....
|
|
|
|
if(m_State != EnumWaitFileAcceptPDU)
|
|
{
|
|
if(m_AbortedCount >= m_AcceptCount)
|
|
{
|
|
m_lpFile->Close();
|
|
SendNextFile();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//In this case, the FileErrorPDU acts as a FileRejectPDU...
|
|
TRACERECEIVE(" Treating FileErrorPDU for [%u] as FileRejectPDU\n",lpNewPDU->GetFileHandle());
|
|
|
|
m_RejectCount++;
|
|
m_ResponseCount++;
|
|
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
if(m_ResponseCount != m_RejectCount)
|
|
{
|
|
m_State = EnumSendFileStartPDU;
|
|
}
|
|
else
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} //EnumWaitForTermination
|
|
} //IsProshare
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedNonStandardPDU
|
|
(
|
|
T120ChannelID wChannelID,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPNONSTANDARDPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State != EnumWaitForTermination)
|
|
{
|
|
if(wChannelID == m_PrivateMBFTControlChannel)
|
|
{
|
|
if (! ::lstrcmpA(lpNewPDU->GetKey(), PROSHARE_FILE_END_STRING))
|
|
{
|
|
TRACESEND(" Received Non Standard PDU (File End Acknowledge) from [%u]\n",SenderID);
|
|
FileEndAcknowledgeStruct * lpStruct = (FileEndAcknowledgeStruct *)lpNewPDU->GetDataBuffer();
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
LPFILEENDACKNOWLEDGEPDU lpEndAckNewPDU = new FileEndAcknowledgePDU(lpStruct->m_FileHandle);
|
|
if (NULL != lpEndAckNewPDU)
|
|
{
|
|
bReturn = OnReceivedFileEndAcknowledgePDU(wChannelID,
|
|
iPriority,
|
|
SenderID,
|
|
lpEndAckNewPDU,
|
|
IsUniformSendData);
|
|
delete lpEndAckNewPDU;
|
|
}
|
|
}
|
|
else if (! ::lstrcmpA(lpNewPDU->GetKey(), PROSHARE_CHANNEL_LEAVE_STRING))
|
|
{
|
|
TRACESEND(" Received Non Standard PDU (Channel Leave) from [%u]\n",SenderID);
|
|
|
|
ChannelLeaveStruct * lpStruct = (ChannelLeaveStruct *)lpNewPDU->GetDataBuffer();
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
LPCHANNELLEAVEPDU lpLeaveNewPDU = new ChannelLeavePDU(lpStruct->m_ChannelID,lpStruct->m_ErrorCode);
|
|
if (NULL != lpLeaveNewPDU)
|
|
{
|
|
bReturn = OnReceivedChannelLeavePDU(wChannelID,
|
|
iPriority,
|
|
SenderID,
|
|
lpLeaveNewPDU,
|
|
IsUniformSendData);
|
|
delete lpLeaveNewPDU;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE("*** Unknown Non Standard PDU received on [%u] *** \n",wChannelID);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedFileEndAcknowledgePDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPFILEENDACKNOWLEDGEPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumWaitFileEndAcknowledgePDU)
|
|
{
|
|
if(wChannelId == m_PrivateMBFTControlChannel)
|
|
{
|
|
if(lpNewPDU->GetFileHandle() == m_CurrentFileHandle)
|
|
{
|
|
TRACESEND(" Received file end acknowledge PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
|
|
|
|
bReturn = TRUE;
|
|
|
|
for (ULONG Index = 0; Index < m_AcceptedIndex; Index++)
|
|
{
|
|
if(m_lpAcceptedUsersArray[Index] == SenderID)
|
|
{
|
|
m_AcknowledgeCount++;
|
|
}
|
|
}
|
|
|
|
if(m_AcknowledgeCount >= m_AcceptCount)
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::OnReceivedChannelLeavePDU
|
|
(
|
|
T120ChannelID wChannelId,
|
|
T120Priority iPriority,
|
|
T120UserID SenderID,
|
|
LPCHANNELLEAVEPDU lpNewPDU,
|
|
BOOL IsUniformSendData
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
if(m_State == EnumSendFileStartPDU || m_State == EnumSendFileDataPDU ||
|
|
m_State == EnumWaitFileEndAcknowledgePDU)
|
|
{
|
|
if(lpNewPDU->GetChannelID() == m_PrivateMBFTDataChannel)
|
|
{
|
|
bReturn = TRUE;
|
|
|
|
TRACESEND(" Received Channel Leave PDU from [%u] for [%u], CurrentFile [%u]\n",
|
|
SenderID,lpNewPDU->GetChannelID(),m_CurrentFileHandle);
|
|
|
|
for (ULONG Index = 0; Index < m_AcceptedIndex; Index++)
|
|
{
|
|
if(m_lpAcceptedUsersArray[Index] == SenderID)
|
|
{
|
|
m_AcknowledgeCount++;
|
|
}
|
|
}
|
|
|
|
if(m_State == EnumWaitFileEndAcknowledgePDU)
|
|
{
|
|
if(m_AcknowledgeCount >= m_AcceptCount)
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bReturn);
|
|
}
|
|
|
|
void MBFTPrivateSend::SendFileStartPDU(void)
|
|
{
|
|
if(!m_bAbortAllFiles)
|
|
{
|
|
MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
|
|
MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
|
|
|
|
LONG lCurrentPosition = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
|
|
FILE_HEADER_INFO fileHeaderInfo;
|
|
fileHeaderInfo.fileName = (LPSTR)GetFileNameFromPath(m_pszCurrentFilePath);
|
|
fileHeaderInfo.fileSize = m_CurrentFileSize;
|
|
fileHeaderInfo.pduType = T127_FILE_START;
|
|
GetFileHeaderSize(&fileHeaderInfo);
|
|
|
|
int iSizeofFileHeader = fileHeaderInfo.pduSize + sizeof(T127_FILE_START_DATA_BLOCK_HEADER);
|
|
int iBytesRead = m_lpFile->Read(m_lpDataBuffer + iSizeofFileHeader ,m_MaxDataLength);
|
|
m_bSendingFile = TRUE;
|
|
|
|
if(iBytesRead != -1)
|
|
{
|
|
BOOL bIsEOF = (m_lTotalBytesRead + iBytesRead) >= m_CurrentFileSize;
|
|
LPFILESTARTPDU lpNewPDU = NULL;
|
|
|
|
if(!iBytesRead)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
lpNewPDU = new FileStartPDU(m_lpDataBuffer,
|
|
fileHeaderInfo.fileName, // GetFileNameFromPath(m_pszCurrentFilePath),
|
|
LOWORD(m_CurrentFileHandle),
|
|
m_CurrentFileSize,
|
|
m_CurrentDateTime,
|
|
m_lpDataBuffer,
|
|
0,
|
|
bIsEOF);
|
|
}
|
|
else
|
|
{
|
|
if(!m_bCompressFiles)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
lpNewPDU = new FileStartPDU(m_lpDataBuffer,
|
|
fileHeaderInfo.fileName, // GetFileNameFromPath(m_pszCurrentFilePath),
|
|
LOWORD(m_CurrentFileHandle),
|
|
m_CurrentFileSize,
|
|
m_CurrentDateTime,
|
|
m_lpDataBuffer,
|
|
iBytesRead,
|
|
bIsEOF);
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
}
|
|
|
|
if(iErrorCode == iMBFT_OK)
|
|
{
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
|
|
APPLET_LOW_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength()))
|
|
{
|
|
TRACESEND(" Sent file start PDU for [%ld] on [%u], EOF = [%d]\n",
|
|
m_CurrentFileHandle, m_PrivateMBFTDataChannel, bIsEOF);
|
|
|
|
m_lTotalBytesRead += iBytesRead;
|
|
m_SentFileStartPDU = TRUE;
|
|
|
|
SendNotificationMessage(iMBFT_FILE_SEND_BEGIN);
|
|
|
|
if(bIsEOF)
|
|
{
|
|
m_lpFile->Close();
|
|
if(!m_bEOFAcknowledge)
|
|
{
|
|
SendNextFile();
|
|
}
|
|
else
|
|
{
|
|
TRACESEND(" Waiting for End of File ack PDU\n");
|
|
m_State = EnumWaitFileEndAcknowledgePDU;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_State = EnumSendFileDataPDU;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_lpFile->Seek(lCurrentPosition,CMBFTFile::SeekMode::SeekFromBegin);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
|
|
}
|
|
} //if(lpNewPDU)
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
} //if iErrorCode == iMBFT_OK
|
|
|
|
if(lpNewPDU)
|
|
{
|
|
lpNewPDU->NULLDataBuffer();
|
|
delete lpNewPDU;
|
|
}
|
|
} //If bytes read...
|
|
else
|
|
{
|
|
iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
|
|
|
|
//iMBFT_FILE_IO_ERROR;
|
|
}
|
|
|
|
if(iErrorCode != iMBFT_OK)
|
|
{
|
|
ReportError(iErrorType,iErrorCode,TRUE);
|
|
ReportSenderError(iErrorType,iErrorCode);
|
|
TerminateCurrentSend();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TerminateCurrentSend();
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::SendNotificationMessage
|
|
(
|
|
int iProgress,
|
|
T120UserID iUserID,
|
|
MBFTFILEHANDLE hFileHandle
|
|
)
|
|
{
|
|
T120UserID id = iUserID ? iUserID : m_MBFTChannelID;
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
m_lpParentEngine->SafePostNotifyMessage(
|
|
new FileTransmitMsg(m_EventHandle,
|
|
hFileHandle ? hFileHandle : m_CurrentFileHandle,
|
|
m_CurrentFileSize,
|
|
m_lTotalBytesRead,
|
|
iProgress,
|
|
id));
|
|
}
|
|
|
|
void MBFTPrivateSend::TerminateCurrentSend(void)
|
|
{
|
|
m_State = EnumTerminateCurrentSend;
|
|
|
|
ReportError(MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,TRUE,
|
|
m_MBFTChannelID,m_CurrentFileHandle);
|
|
|
|
//We don't care about compression in this case because the buffer is NULL....
|
|
DBG_SAVE_FILE_LINE
|
|
LPFILEDATAPDU lpNewPDU = new FileDataPDU(m_lpDataBuffer,LOWORD(m_CurrentFileHandle),m_lpDataBuffer,0, FALSE, TRUE);
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
|
|
APPLET_LOW_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength()))
|
|
{
|
|
m_lpFile->Close();
|
|
SendNextFile();
|
|
}
|
|
}
|
|
lpNewPDU->NULLDataBuffer();
|
|
delete lpNewPDU;
|
|
}
|
|
}
|
|
|
|
|
|
void MBFTPrivateSend::SendFileDataPDU(void)
|
|
{
|
|
LONG lCurrentPosition = -1;
|
|
LPFILEDATAPDU lpNewPDU = NULL;
|
|
int iBytesRead,Index;
|
|
BOOL bIsEOF = FALSE,bTerminate = FALSE;
|
|
MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
|
|
MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
|
|
|
|
if(!m_bAbortFileSend)
|
|
{
|
|
for(Index = 0;(Index < _MAX_SEND_PACKETS) && !bTerminate;Index++)
|
|
{
|
|
lCurrentPosition = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
|
|
iBytesRead = m_lpFile->Read(m_lpDataBuffer + sizeof(T127_FILE_DATA_HEADER),m_MaxDataLength);
|
|
if(iBytesRead != -1)
|
|
{
|
|
BOOL bDataSent = FALSE;
|
|
bIsEOF = m_lpFile->GetIsEOF();
|
|
|
|
if(!m_bCompressFiles)
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
lpNewPDU = new FileDataPDU(m_lpDataBuffer,
|
|
LOWORD(m_CurrentFileHandle),
|
|
m_lpDataBuffer,iBytesRead,bIsEOF,
|
|
FALSE);
|
|
}
|
|
else
|
|
{
|
|
// MSFT error - no compression
|
|
}
|
|
|
|
if(lpNewPDU)
|
|
{
|
|
if(lpNewPDU->Encode())
|
|
{
|
|
if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
|
|
APPLET_LOW_PRIORITY,
|
|
(LPBYTE)lpNewPDU->GetBuffer(),
|
|
lpNewPDU->GetBufferLength()))
|
|
{
|
|
TRACESEND(" Sent file data PDU on [%u], EOF = [%d], BufferSize = [%d]\n",m_PrivateMBFTDataChannel,bIsEOF,lpNewPDU->GetBufferLength());
|
|
|
|
//m_lTotalBytesRead += iBytesRead;
|
|
|
|
m_lTotalBytesRead = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
|
|
|
|
bDataSent = TRUE;
|
|
|
|
SendNotificationMessage(iMBFT_FILE_SEND_PROGRESS);
|
|
|
|
if(bIsEOF)
|
|
{
|
|
m_lpFile->Close();
|
|
|
|
if(!m_bEOFAcknowledge)
|
|
{
|
|
SendNextFile();
|
|
}
|
|
else
|
|
{
|
|
TRACESEND(" Waiting for End of File ack PDU\n");
|
|
m_State = EnumWaitFileEndAcknowledgePDU;
|
|
}
|
|
|
|
bTerminate = TRUE;
|
|
}
|
|
}
|
|
|
|
if(!bDataSent)
|
|
{
|
|
m_lpFile->Seek(lCurrentPosition,CMBFTFile::SeekMode::SeekFromBegin);
|
|
bTerminate = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
|
|
break;
|
|
}
|
|
lpNewPDU->NULLDataBuffer();
|
|
delete lpNewPDU;
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
|
|
|
|
//iMBFT_FILE_IO_ERROR;
|
|
|
|
break;
|
|
}
|
|
} //for loop
|
|
}
|
|
else
|
|
{
|
|
TerminateCurrentSend();
|
|
}
|
|
|
|
if(iErrorCode != iMBFT_OK)
|
|
{
|
|
ReportError(iErrorType,iErrorCode,TRUE);
|
|
ReportSenderError(iErrorType,iErrorCode);
|
|
TerminateCurrentSend();
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::RemoveFileFromList
|
|
(
|
|
MBFTFILEHANDLE hFile
|
|
)
|
|
{
|
|
if (hFile == m_CurrentFileHandle)
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_NO_MORE_FILES,TRUE);
|
|
TerminateSendSession();
|
|
}
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::RemoveUserFromAcceptedList
|
|
(
|
|
T120UserID iUserID
|
|
)
|
|
{
|
|
BOOL bUserRemoved = FALSE;
|
|
|
|
for (ULONG Index = 1; Index <= m_AcceptedIndex; Index++)
|
|
{
|
|
if(m_lpAcceptedUsersArray[Index - 1] == iUserID)
|
|
{
|
|
bUserRemoved = TRUE;
|
|
|
|
if(Index != m_AcceptedIndex)
|
|
{
|
|
CopyMemory(&m_lpAcceptedUsersArray[Index - 1],&m_lpAcceptedUsersArray[Index],
|
|
(m_AcceptedIndex - Index) * sizeof(UserID));
|
|
}
|
|
|
|
m_AcceptedIndex--;
|
|
}
|
|
}
|
|
|
|
return(bUserRemoved);
|
|
}
|
|
|
|
BOOL MBFTPrivateSend::RemoveUserFromList
|
|
(
|
|
T120UserID iUserID
|
|
)
|
|
{
|
|
BOOL bUserRemoved = FALSE;
|
|
|
|
for (ULONG Index = 1; Index <= m_iUserCount; Index++)
|
|
{
|
|
if(m_lpUserArray[Index - 1] == iUserID)
|
|
{
|
|
bUserRemoved = TRUE;
|
|
|
|
if(Index != m_iUserCount)
|
|
{
|
|
CopyMemory(&m_lpUserArray[Index - 1],&m_lpUserArray[Index],
|
|
(m_iUserCount - Index) * sizeof(UserID));
|
|
}
|
|
|
|
m_iUserCount--;
|
|
}
|
|
}
|
|
|
|
if(bUserRemoved)
|
|
{
|
|
if(!m_iUserCount)
|
|
{
|
|
ReportError(MBFT_PERMANENT_ERROR,iMBFT_NO_MORE_RECIPIENTS,TRUE);
|
|
|
|
if(m_State == EnumSendFileDataPDU || m_State == EnumSendFileOfferPDU ||
|
|
m_State == EnumWaitFileAcceptPDU)
|
|
{
|
|
if(m_lpFile)
|
|
{
|
|
m_lpFile->Close();
|
|
}
|
|
|
|
if(m_State == EnumSendFileDataPDU)
|
|
{
|
|
SendNotificationMessage(iMBFT_FILE_SEND_END);
|
|
}
|
|
}
|
|
|
|
TerminateSendSession();
|
|
}
|
|
}
|
|
|
|
return(bUserRemoved);
|
|
}
|
|
|
|
void MBFTPrivateSend::OnControlNotification
|
|
(
|
|
MBFTFILEHANDLE hFile,
|
|
FileTransferControlMsg::FileTransferControl iControlCommand,
|
|
LPCSTR lpszDirectory,
|
|
LPCSTR lpszFileName
|
|
)
|
|
{
|
|
if(iControlCommand == FileTransferControlMsg::EnumAbortFile ||
|
|
iControlCommand == FileTransferControlMsg::EnumConductorAbortFile)
|
|
{
|
|
if(m_bOKToDisbandChannel)
|
|
{
|
|
if(hFile == _iMBFT_PROSHARE_ALL_FILES /*&& m_bProshareTransfer*/)
|
|
{
|
|
//Fix to ensure a iMBFT_SENDER_ABORTED notification if sender aborts way too early...
|
|
ReportError(MBFT_INFORMATIVE_ERROR,
|
|
(iControlCommand == FileTransferControlMsg::EnumAbortFile) ?
|
|
iMBFT_SENDER_ABORTED :
|
|
iMBFT_CONDUCTOR_ABORTED,
|
|
TRUE,
|
|
m_MBFTChannelID,
|
|
_iMBFT_PROSHARE_ALL_FILES);
|
|
|
|
UnInitialize();
|
|
}
|
|
else
|
|
{
|
|
RemoveFileFromList(hFile);
|
|
}
|
|
}
|
|
else if(!m_bUnInitializing)
|
|
{
|
|
if(hFile == _iMBFT_PROSHARE_ALL_FILES)
|
|
{
|
|
AbortAllFiles();
|
|
}
|
|
else if(hFile == m_CurrentFileHandle)
|
|
{
|
|
AbortCurrentFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::AbortAllFiles(void)
|
|
{
|
|
AbortCurrentFile();
|
|
|
|
m_bAbortAllFiles = TRUE;
|
|
}
|
|
|
|
void MBFTPrivateSend::AbortCurrentFile(void)
|
|
{
|
|
if(m_bSendingFile)
|
|
{
|
|
m_bAbortFileSend = TRUE;
|
|
}
|
|
}
|
|
|
|
void MBFTPrivateSend::SendNextFile(void)
|
|
{
|
|
// Notify the ui if some receivers didn't accept the previous file
|
|
if(m_AbortedCount)
|
|
{
|
|
// All the receivers aborted the FT, this is the same as the sender canceling FT
|
|
ReportError(MBFT_PERMANENT_ERROR,
|
|
m_AbortedCount >= m_AcceptCount ? iMBFT_SENDER_ABORTED : iMBFT_MULT_RECEIVER_ABORTED,
|
|
TRUE);
|
|
}
|
|
if(m_RejectCount)
|
|
{
|
|
// If we just had one FT an it rejected we say that there was a problem sending the file
|
|
// If we had more receivers we will use the receiver aborted message
|
|
ReportError(MBFT_PERMANENT_ERROR,
|
|
m_AcceptCount == 0 ? iMBFT_RECEIVER_REJECTED : iMBFT_MULT_RECEIVER_ABORTED,
|
|
TRUE);
|
|
}
|
|
|
|
// We are sending or the receiver Rejected before we start sending
|
|
if(m_bSendingFile || m_RejectCount)
|
|
{
|
|
SendNotificationMessage(iMBFT_FILE_SEND_END);
|
|
}
|
|
|
|
m_bSendingFile = FALSE;
|
|
m_bAbortFileSend = FALSE;
|
|
|
|
TerminateSendSession();
|
|
}
|
|
|
|
void MBFTPrivateSend::OnPeerDeletedNotification
|
|
(
|
|
CPeerData *lpPeerData
|
|
)
|
|
{
|
|
if(m_State != EnumWaitForTermination)
|
|
{
|
|
if(RemoveUserFromList(lpPeerData->GetUserID()))
|
|
{
|
|
if(m_iUserCount)
|
|
{
|
|
if(m_State == EnumWaitFileAcceptPDU ||
|
|
m_State == EnumWaitChannelResponsePDU)
|
|
{
|
|
//m_RejectCount++;
|
|
//m_ResponseCount++;
|
|
|
|
if(m_ResponseCount >= m_iUserCount)
|
|
{
|
|
if(m_State == EnumWaitFileAcceptPDU)
|
|
{
|
|
if(m_ResponseCount != m_RejectCount)
|
|
{
|
|
m_State = EnumSendFileStartPDU;
|
|
}
|
|
else
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
else if(m_State == EnumWaitChannelResponsePDU)
|
|
{
|
|
if(!m_bProshareTransfer)
|
|
{
|
|
m_State = EnumSendFileOfferPDU;
|
|
}
|
|
else
|
|
{
|
|
m_State = EnumSendNonStandardPDU;
|
|
}
|
|
}
|
|
} //m_ResponseCount >= m_iUserCount
|
|
}
|
|
else if ((m_State == EnumWaitFileEndAcknowledgePDU) || (m_State == EnumSendFileDataPDU))
|
|
{
|
|
if(RemoveUserFromAcceptedList(lpPeerData->GetUserID()))
|
|
{
|
|
m_AcknowledgeCount++;
|
|
}
|
|
|
|
if(m_AcknowledgeCount >= m_AcceptCount)
|
|
{
|
|
SendNextFile();
|
|
}
|
|
}
|
|
} //UserCount
|
|
} //RemoveUserFromList
|
|
} //EnumWaitForTermination
|
|
}
|
|
|
|
|