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.
775 lines
26 KiB
775 lines
26 KiB
//---------------------------------------------------------------------
|
|
// Copyright (c)1998 Microsoft Corporation, All Rights Reserved.
|
|
//
|
|
// complete.cpp
|
|
//
|
|
// This is the main for the IrTran-P service.
|
|
//---------------------------------------------------------------------
|
|
|
|
#include "precomp.h"
|
|
|
|
extern HINSTANCE g_hInst; // Instance of ircamera.dll
|
|
extern void *g_pvIrUsdDevice; // Devined: irtranp.cpp
|
|
|
|
extern CCONNECTION_MAP *g_pConnectionMap; // Defined: irtranp.cpp
|
|
extern BOOL ReceivesAllowed(); // Defined: irtranp.cpp
|
|
extern BOOL CheckSaveAsUPF(); // Defined: irtranp.cpp
|
|
|
|
extern DWORD SignalWIA( IN char *pszFileName,
|
|
IN void *pvIrUsdDevice ); // see ../device.cpp
|
|
|
|
//---------------------------------------------------------------------
|
|
// Constants:
|
|
//---------------------------------------------------------------------
|
|
|
|
#define DEFAULT_TIMEOUT 10000
|
|
|
|
//---------------------------------------------------------------------
|
|
// ReceiveComplete()
|
|
//
|
|
//---------------------------------------------------------------------
|
|
void ReceiveComplete( IN CCONNECTION *pConnection,
|
|
IN DWORD dwStatusCode )
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
if ( (dwStatusCode == NO_ERROR)
|
|
|| (dwStatusCode == ERROR_SCEP_UNSPECIFIED_DISCONNECT)
|
|
|| (dwStatusCode == ERROR_SCEP_USER_DISCONNECT)
|
|
|| (dwStatusCode == ERROR_SCEP_PROVIDER_DISCONNECT) )
|
|
{
|
|
//
|
|
// A new picture has just been received, so we need to signal
|
|
// WIA...
|
|
//
|
|
SignalWIA( pConnection->GetPathPlusFileName(), g_pvIrUsdDevice );
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessConnectRequest()
|
|
//
|
|
// Called by ProcessClient() when the input PDU message type is
|
|
// MSG_TYPE_CONNECT_REQ.
|
|
//
|
|
// pConnection - The newly established Winsock connection with the
|
|
// camera.
|
|
//
|
|
// pPdu - The SCEP PDU holding the connect request. It was
|
|
// allocated in ProcessClient() by AssemblePdu() and
|
|
// will always be free'd when ProcessConnectRequest()
|
|
// finishes.
|
|
//
|
|
// dwPduSize - The size of the input PDU in bytes.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessConnectRequest( IN CCONNECTION *pConnection,
|
|
IN SCEP_HEADER *pPdu,
|
|
IN DWORD dwPduSize )
|
|
{
|
|
DWORD dwStatus;
|
|
DWORD dwRespPduSize;
|
|
BOOL fReceivesAllowed = ::ReceivesAllowed();
|
|
SCEP_HEADER *pRespPdu;
|
|
CIOPACKET *pNewIoPacket; // Posted IO packet (by SendPdu()).
|
|
|
|
CSCEP_CONNECTION *pScepConnection
|
|
= (CSCEP_CONNECTION*)pConnection->GetScepConnection();
|
|
|
|
if (fReceivesAllowed)
|
|
{
|
|
// Build an connection accept acknowledgement:
|
|
dwStatus = pScepConnection->BuildConnectRespPdu(&pRespPdu,
|
|
&dwRespPduSize);
|
|
}
|
|
else
|
|
{
|
|
// Build a connect NACK:
|
|
dwStatus = pScepConnection->BuildConnectNackPdu(&pRespPdu,
|
|
&dwRespPduSize);
|
|
}
|
|
|
|
if (dwStatus == NO_ERROR)
|
|
{
|
|
pConnection->SendPdu(pRespPdu,dwRespPduSize,&pNewIoPacket);
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pRespPdu);
|
|
}
|
|
else
|
|
{
|
|
DeletePdu(pRespPdu);
|
|
}
|
|
|
|
if (!fReceivesAllowed)
|
|
{
|
|
// Note: After sending a NACK, the camera should close
|
|
// the connection, but at lease some don't, so I'm
|
|
// forced to slam the connection...
|
|
pConnection->CloseSocket(); // Was: ShutdownSocket().
|
|
}
|
|
}
|
|
|
|
DeletePdu(pPdu);
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessConnectResponse()
|
|
//
|
|
// Called by ProcessClient() when the input PDU message type is
|
|
// MSG_TYPE_CONNECT_RESP.
|
|
//
|
|
// NOTE: Note implemented in the IrTran-P server, because the server
|
|
// is not currently setup to connect to a camera to download
|
|
// pictures back to the camera... We should never get this PDU
|
|
// during normal operation.
|
|
//
|
|
// pConnection - The newly established Winsock connection with the
|
|
// camera.
|
|
//
|
|
// pPdu - The SCEP PDU holding the connect request. It was
|
|
// allocated in ProcessClient() by AssemblePdu() and
|
|
// will always be free'd when ProcessConnectResponse()
|
|
// finishes.
|
|
//
|
|
// dwPduSize - The size of the input PDU in bytes.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessConnectResponse( CCONNECTION *pConnection,
|
|
SCEP_HEADER *pPdu,
|
|
DWORD dwPduSize )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
|
|
WIAS_TRACE((g_hInst,"ProcessClient(): Unimplemented MSG_TYPE_CONNECT_RESP"));
|
|
|
|
DeletePdu(pPdu);
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessData()
|
|
//
|
|
// Called by ProcessClient() when the input PDU message type is
|
|
// MSG_TYPE_DATA.
|
|
//
|
|
// pConnection - The newly established Winsock connection with the
|
|
// camera.
|
|
//
|
|
// pPdu - The SCEP PDU holding the connect request. It was
|
|
// allocated in ProcessClient() by AssemblePdu() and
|
|
// will always be free'd when ProcessConnectResponse()
|
|
// finishes.
|
|
//
|
|
// dwPduSize - The size of the input PDU in bytes.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessData( CCONNECTION *pConnection,
|
|
SCEP_HEADER *pPdu,
|
|
DWORD dwPduSize,
|
|
COMMAND_HEADER *pCommandHeader,
|
|
UCHAR *pUserData,
|
|
DWORD dwUserDataSize )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
DWORD dwRespPduSize;
|
|
DWORD dwBftpOp;
|
|
UCHAR *pPutData;
|
|
DWORD dwPutDataSize;
|
|
DWORD dwJpegOffset;
|
|
DWORD dwJpegSize;
|
|
SCEP_HEADER *pRespPdu;
|
|
CIOPACKET *pNewIoPacket; // Posted IO packet (by SendPdu()).
|
|
|
|
|
|
CSCEP_CONNECTION *pScepConnection
|
|
= (CSCEP_CONNECTION*)pConnection->GetScepConnection();
|
|
|
|
// First, check to see if this is an abort PDU, send by the camera:
|
|
if ( (pCommandHeader) && (pCommandHeader->PduType == PDU_TYPE_ABORT) )
|
|
{
|
|
DeletePdu(pPdu);
|
|
return ERROR_SCEP_ABORT;
|
|
}
|
|
|
|
// Is one of the 2nd through Nth fragments of a fragmented PDU?
|
|
if ( (pScepConnection->IsFragmented())
|
|
&& (pScepConnection->GetSequenceNo() > 0))
|
|
{
|
|
#ifdef DBG_IO
|
|
WIAS_TRACE((g_hInst,"ProcessClient(): Put Fragment: SequenceNo: %d RestNo: %d", pScepConnection->GetSequenceNo(), pScepConnection->GetRestNo() ));
|
|
#endif
|
|
|
|
pConnection->WritePictureFile( pUserData,
|
|
dwUserDataSize,
|
|
&pNewIoPacket );
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pPdu);
|
|
}
|
|
else
|
|
{
|
|
DeletePdu(pPdu);
|
|
}
|
|
|
|
if (pScepConnection->GetDFlag() == DFLAG_LAST_FRAGMENT)
|
|
{
|
|
pScepConnection->BuildPutRespPdu( PDU_TYPE_REPLY_ACK,
|
|
ERROR_PUT_NO_ERROR,
|
|
&pRespPdu,
|
|
&dwRespPduSize);
|
|
pConnection->SendPdu( pRespPdu,
|
|
dwRespPduSize,
|
|
&pNewIoPacket);
|
|
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pRespPdu);
|
|
}
|
|
else
|
|
{
|
|
DeletePdu(pRespPdu);
|
|
}
|
|
}
|
|
}
|
|
else if (pCommandHeader)
|
|
{
|
|
// Length4 in the COMMAN_HEADER is the user data size
|
|
// plus the bytes for machine ids (16), the DestPid (2),
|
|
// SrcPid (2) and CommandId (2) so offset by 22.
|
|
|
|
dwStatus = pScepConnection->ParseBftp( pUserData,
|
|
dwUserDataSize,
|
|
pConnection->CheckSaveAsUPF(),
|
|
&dwBftpOp,
|
|
&pPutData,
|
|
&dwPutDataSize );
|
|
if ((dwStatus == NO_ERROR) && (IsBftpQuery(dwBftpOp)))
|
|
{
|
|
pScepConnection->BuildWht0RespPdu(dwBftpOp,
|
|
&pRespPdu,
|
|
&dwRespPduSize);
|
|
|
|
pConnection->SendPdu( pRespPdu,
|
|
dwRespPduSize,
|
|
&pNewIoPacket );
|
|
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pRespPdu);
|
|
}
|
|
else
|
|
{
|
|
DeletePdu(pRespPdu);
|
|
}
|
|
|
|
DeletePdu(pPdu);
|
|
}
|
|
else if ((dwStatus == NO_ERROR) && (IsBftpPut(dwBftpOp)))
|
|
{
|
|
//
|
|
// Ok, we have a bFTP PUT command, so open a file
|
|
// and get ready to start collecting image data.
|
|
//
|
|
dwStatus = pScepConnection->ParseUpfHeaders( pPutData,
|
|
dwPutDataSize,
|
|
&dwJpegOffset,
|
|
&dwJpegSize );
|
|
|
|
pConnection->SetJpegOffsetAndSize(dwJpegOffset,dwJpegSize);
|
|
|
|
dwStatus = pConnection->Impersonate();
|
|
|
|
dwStatus = pConnection->CreatePictureFile();
|
|
|
|
dwStatus = pConnection->SetPictureFileTime( pScepConnection->GetCreateTime() );
|
|
|
|
dwStatus = pConnection->RevertToSelf();
|
|
|
|
dwStatus = pConnection->WritePictureFile( pPutData,
|
|
dwPutDataSize,
|
|
&pNewIoPacket );
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pPdu);
|
|
}
|
|
else
|
|
{
|
|
DeletePdu(pPdu);
|
|
}
|
|
}
|
|
else if (IsBftpError(dwBftpOp))
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessClient(): bFTP Error: %d", dwStatus));
|
|
#endif
|
|
|
|
DeletePdu(pPdu);
|
|
dwStatus = ERROR_BFTP_INVALID_PROTOCOL;
|
|
}
|
|
else
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessClient(): Unknown bFTP Command: %d",dwBftpOp));
|
|
#endif
|
|
|
|
DeletePdu(pPdu);
|
|
dwStatus = ERROR_BFTP_INVALID_PROTOCOL;
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessDisconnect()
|
|
//
|
|
// Called by ProcessClient() when the input PDU message type is
|
|
// MSG_TYPE_DISCONNECT.
|
|
//
|
|
// pConnection - The newly established Winsock connection with the
|
|
// camera.
|
|
//
|
|
// pPdu - The SCEP PDU holding the connect request. It was
|
|
// allocated in ProcessClient() by AssemblePdu() and
|
|
// will always be free'd when ProcessConnectResponse()
|
|
// finishes.
|
|
//
|
|
// dwPduSize - The size of the input PDU in bytes.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessDisconnect( CCONNECTION *pConnection,
|
|
SCEP_HEADER *pPdu,
|
|
DWORD dwPduSize )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
|
|
// Don't need to do anything special here, since
|
|
// ParsePdu() will set dwStatus to one of:
|
|
// ERROR_SCEP_UNSPECIFIED_DISCONNECT (5002)
|
|
// ERROR_SCEP_USER_DISCONNECT (5003)
|
|
// or ERROR_SCEP_PROVIDER_DISCONNECT (5004)
|
|
|
|
pConnection->SetReceiveComplete(TRUE);
|
|
|
|
DeletePdu(pPdu);
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessClient() Synchronous Version
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessClient( CIOSTATUS *pIoStatus,
|
|
CCONNECTION *pConnection,
|
|
char *pBuffer,
|
|
DWORD dwNumBytes )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
CSCEP_CONNECTION *pScepConnection;
|
|
SCEP_HEADER *pPdu;
|
|
DWORD dwPduSize;
|
|
COMMAND_HEADER *pCommandHeader;
|
|
UCHAR *pUserData; // Location of bFTP data.
|
|
DWORD dwUserDataSize;
|
|
DWORD dwError = 0;
|
|
|
|
|
|
pScepConnection = (CSCEP_CONNECTION*)pConnection->GetScepConnection();
|
|
|
|
WIAS_ASSERT(g_hInst,pScepConnection!=NULL);
|
|
|
|
while (dwStatus == NO_ERROR)
|
|
{
|
|
dwStatus = pScepConnection->AssemblePdu( pBuffer,
|
|
dwNumBytes,
|
|
&pPdu,
|
|
&dwPduSize );
|
|
if (dwStatus == NO_ERROR)
|
|
{
|
|
dwStatus = pScepConnection->ParsePdu( pPdu,
|
|
dwPduSize,
|
|
&pCommandHeader,
|
|
&pUserData,
|
|
&dwUserDataSize );
|
|
|
|
switch (pPdu->MsgType)
|
|
{
|
|
case MSG_TYPE_CONNECT_REQ:
|
|
//
|
|
// Message was an SCEP Connection Request:
|
|
//
|
|
dwStatus = ProcessConnectRequest(pConnection,
|
|
pPdu,
|
|
dwPduSize );
|
|
|
|
if ((dwStatus) || (!ReceivesAllowed()))
|
|
{
|
|
pConnection->ClosePictureFile();
|
|
ReceiveComplete(pConnection,dwStatus);
|
|
}
|
|
else
|
|
{
|
|
pConnection->StartProgress();
|
|
}
|
|
break;
|
|
|
|
case MSG_TYPE_CONNECT_RESP:
|
|
// Message was a reply from a connection request:
|
|
dwStatus = ProcessConnectResponse(pConnection,
|
|
pPdu,
|
|
dwPduSize );
|
|
break;
|
|
|
|
case MSG_TYPE_DATA:
|
|
// Message is a SCEP command of some sort:
|
|
dwStatus = ProcessData(pConnection,
|
|
pPdu,
|
|
dwPduSize,
|
|
pCommandHeader,
|
|
pUserData,
|
|
dwUserDataSize );
|
|
pConnection->UpdateProgress();
|
|
break;
|
|
|
|
case MSG_TYPE_DISCONNECT:
|
|
// Message from the camera was a disconnect:
|
|
ProcessDisconnect(pConnection,
|
|
pPdu,
|
|
dwPduSize );
|
|
pConnection->ClosePictureFile();
|
|
ReceiveComplete(pConnection,dwStatus);
|
|
pConnection->EndProgress();
|
|
break;
|
|
|
|
default:
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessClient(): Unknown MSG_TYPE_xxx: %d", pPdu->MsgType));
|
|
#endif
|
|
DeletePdu(pPdu);
|
|
pConnection->EndProgress();
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
|
|
pBuffer = 0;
|
|
dwNumBytes = 0;
|
|
}
|
|
|
|
if (dwStatus == ERROR_CONTINUE)
|
|
{
|
|
dwStatus = NO_ERROR;
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// SendAbortPdu()
|
|
//
|
|
// Stop the camera.
|
|
//
|
|
// I should be able to send a Stop PDU, followed by a Disconnect, or
|
|
// maybe an Abort PDU, but these don't work on all the cameras, so I
|
|
// currently end up just doing a hard close on the connection to the
|
|
// camera.
|
|
//---------------------------------------------------------------------
|
|
DWORD SendAbortPdu( IN CCONNECTION *pConnection )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
|
|
#if TRUE
|
|
pConnection->CloseSocket();
|
|
|
|
#else
|
|
DWORD dwPduSize;
|
|
SCEP_HEADER *pPdu;
|
|
CIOPACKET *pNewIoPacket = 0;
|
|
CSCEP_CONNECTION *pScepConnection
|
|
= (CSCEP_CONNECTION*)pConnection->GetScepConnection();
|
|
|
|
if (pScepConnection)
|
|
{
|
|
dwStatus = pScepConnection->BuildStopPdu(&pPdu,&dwPduSize);
|
|
|
|
if (dwStatus != NO_ERROR)
|
|
{
|
|
pConnection->CloseSocket();
|
|
return dwStatus;
|
|
}
|
|
|
|
dwStatus = pConnection->SendPdu(pPdu,dwPduSize,&pNewIoPacket);
|
|
|
|
if (dwStatus != NO_ERROR)
|
|
{
|
|
DeletePdu(pPdu);
|
|
pConnection->CloseSocket();
|
|
return dwStatus;
|
|
}
|
|
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pPdu);
|
|
}
|
|
|
|
dwStatus = pScepConnection->BuildDisconnectPdu(
|
|
REASON_CODE_PROVIDER_DISCONNECT,
|
|
&pPdu,
|
|
&dwPduSize);
|
|
|
|
if (dwStatus != NO_ERROR)
|
|
{
|
|
pConnection->CloseSocket();
|
|
return dwStatus;
|
|
}
|
|
|
|
dwStatus = pConnection->SendPdu(pPdu,dwPduSize,&pNewIoPacket);
|
|
|
|
if (dwStatus != NO_ERROR)
|
|
{
|
|
DeletePdu(pPdu);
|
|
pConnection->CloseSocket();
|
|
return dwStatus;
|
|
}
|
|
|
|
if (pNewIoPacket)
|
|
{
|
|
pNewIoPacket->SetWritePdu(pPdu);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// MapStatusCode()
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD MapStatusCode( DWORD dwStatus,
|
|
DWORD dwDefaultStatus )
|
|
{
|
|
// The Facility part of an error code are the first 12 bits of the
|
|
// high word (16bits):
|
|
#define FACILITY_MASK 0x0FFF0000
|
|
|
|
// If the error code is already an IrTran-P error code, then don't
|
|
// remap it:
|
|
if ( ((dwStatus&FACILITY_MASK) >> 16) == FACILITY_IRTRANP)
|
|
{
|
|
return dwStatus;
|
|
}
|
|
|
|
// Map other errors:
|
|
if (dwStatus != NO_ERROR)
|
|
{
|
|
if ( (dwStatus == ERROR_DISK_FULL)
|
|
|| (dwStatus == ERROR_WRITE_FAULT)
|
|
|| (dwStatus == ERROR_WRITE_PROTECT)
|
|
|| (dwStatus == ERROR_GEN_FAILURE)
|
|
|| (dwStatus == ERROR_NOT_DOS_DISK) )
|
|
{
|
|
dwStatus = ERROR_IRTRANP_DISK_FULL;
|
|
}
|
|
else
|
|
{
|
|
dwStatus = dwDefaultStatus;
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// ProcessIoPackets() Synchronous Version
|
|
//
|
|
//---------------------------------------------------------------------
|
|
DWORD ProcessIoPackets( CIOSTATUS *pIoStatus )
|
|
{
|
|
DWORD dwStatus = NO_ERROR;
|
|
DWORD dwProcessStatus = NO_ERROR; // Processing IO status.
|
|
DWORD dwNumBytes;
|
|
DWORD dwState;
|
|
SOCKET Socket = INVALID_SOCKET;
|
|
CCONNECTION *pConnection;
|
|
CCONNECTION *pNewConnection;
|
|
CSCEP_CONNECTION *pScepConnection;
|
|
DWORD dwKind = PACKET_KIND_LISTEN;
|
|
int iCount;
|
|
|
|
|
|
while (TRUE)
|
|
{
|
|
if (dwKind == PACKET_KIND_LISTEN)
|
|
{
|
|
dwState = 0;
|
|
|
|
Socket = g_pConnectionMap->ReturnNextSocket(&dwState);
|
|
|
|
pConnection = g_pConnectionMap->Lookup(Socket);
|
|
if (!pConnection)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Lookup(%d) Failed."));
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// New connection:
|
|
//
|
|
SOCKET NewSocket = accept(Socket,NULL,NULL);
|
|
|
|
if (NewSocket == INVALID_SOCKET)
|
|
{
|
|
dwStatus = WSAGetLastError();
|
|
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Accept() failed: %d",dwStatus));
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
WIAS_TRACE((g_hInst,"ProcessIoPackets(): Accept(): Socket: %d",NewSocket));
|
|
|
|
pScepConnection = new CSCEP_CONNECTION;
|
|
if (!pScepConnection)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Out of memeory on allocate of new SCEP connection object."));
|
|
#endif
|
|
|
|
closesocket(NewSocket);
|
|
continue;
|
|
}
|
|
|
|
pNewConnection = new CCONNECTION(
|
|
PACKET_KIND_READ,
|
|
NewSocket,
|
|
NULL, // No IO Completion port...
|
|
pScepConnection,
|
|
::CheckSaveAsUPF() );
|
|
if (!pNewConnection)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Out of memeory on allocate of new connection object."));
|
|
#endif
|
|
|
|
delete pScepConnection;
|
|
closesocket(NewSocket);
|
|
continue;
|
|
}
|
|
|
|
g_pConnectionMap->Add(pNewConnection,
|
|
pNewConnection->GetSocket() );
|
|
|
|
Socket = NewSocket;
|
|
dwKind = PACKET_KIND_READ;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Incomming data from connected client:
|
|
//
|
|
DWORD dwFlags = 0;
|
|
|
|
char ReadBuffer[DEFAULT_READ_BUFFER_SIZE];
|
|
int iReadBufferSize = DEFAULT_READ_BUFFER_SIZE;
|
|
|
|
|
|
pConnection = g_pConnectionMap->Lookup(Socket);
|
|
if (!pConnection)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Lookup(%d) Failed."));
|
|
#endif
|
|
|
|
dwKind = PACKET_KIND_LISTEN;
|
|
continue;
|
|
}
|
|
|
|
iCount = recv(Socket,ReadBuffer,iReadBufferSize,dwFlags);
|
|
|
|
if (iCount == SOCKET_ERROR)
|
|
{
|
|
//
|
|
// Error on Recv().
|
|
//
|
|
dwStatus = WSAGetLastError();
|
|
|
|
#ifdef DBG_ERROR
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): Recv() failed: %d",dwStatus));
|
|
#endif
|
|
|
|
g_pConnectionMap->Remove(Socket);
|
|
|
|
delete pConnection;
|
|
|
|
dwKind = PACKET_KIND_LISTEN;
|
|
continue;
|
|
}
|
|
|
|
if (iCount == 0)
|
|
{
|
|
//
|
|
// Graceful close.
|
|
//
|
|
g_pConnectionMap->Remove(Socket);
|
|
|
|
delete pConnection;
|
|
|
|
dwKind = PACKET_KIND_LISTEN;
|
|
continue;
|
|
}
|
|
|
|
WIAS_ASSERT(g_hInst, iCount>0 );
|
|
|
|
dwNumBytes = iCount;
|
|
|
|
dwProcessStatus
|
|
= ProcessClient(pIoStatus,
|
|
pConnection,
|
|
ReadBuffer,
|
|
dwNumBytes);
|
|
|
|
if (dwProcessStatus != NO_ERROR)
|
|
{
|
|
#ifdef DBG_ERROR
|
|
if ( (dwProcessStatus != ERROR_SCEP_UNSPECIFIED_DISCONNECT)
|
|
&& (dwProcessStatus != ERROR_SCEP_USER_DISCONNECT)
|
|
&& (dwProcessStatus != ERROR_SCEP_PROVIDER_DISCONNECT) )
|
|
{
|
|
WIAS_ERROR((g_hInst,"ProcessIoPackets(): ProcessClient(): Failed: 0x%x",dwProcessStatus));
|
|
}
|
|
#endif
|
|
|
|
SendAbortPdu(pConnection);
|
|
pConnection->ClosePictureFile();
|
|
pConnection->EndProgress();
|
|
pConnection->DeletePictureFile();
|
|
g_pConnectionMap->Remove(Socket);
|
|
delete pConnection;
|
|
|
|
dwProcessStatus = MapStatusCode(
|
|
dwProcessStatus,
|
|
ERROR_SCEP_INVALID_PROTOCOL );
|
|
// pConnection->ClosePictureFile();
|
|
// ReceiveComplete(pConnection,dwProcessStatus);
|
|
|
|
dwKind = PACKET_KIND_LISTEN;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|