249 lines
6.3 KiB
C++
249 lines
6.3 KiB
C++
/*++
|
|
|
|
Copyright (C) 1996-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
TRANSTRM.CPP
|
|
|
|
Abstract:
|
|
|
|
CTransportStream implementation.
|
|
|
|
This is a generic data stream for object/interface marshaling.
|
|
|
|
History:
|
|
|
|
a-raymcc 10-Apr-96 Created.
|
|
a-raymcc 06-Jun-96 CArena support.
|
|
a-raymcc 11-Sep-96 Support NULL pointers
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include "wmishared.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#ifdef TCPIP_MARSHALER
|
|
#include <winsock.h>
|
|
#endif
|
|
#include <strm.h>
|
|
#include <transtrm.h>
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::CTransportStream
|
|
//
|
|
// Standard constructor.
|
|
//
|
|
// PARAMETERS:
|
|
// nFlags
|
|
// auto_delete or no_delete. If auto_delete, the internal buffer
|
|
// is automatically deallocated at destruct-time. If no_delete,
|
|
// it is assumed that another object has acquired the m_pBuffer
|
|
// pointer and will deallocate it with m_pArena->Free().
|
|
// pArena
|
|
// The arena to use for allocation/deallocation. If NULL, the
|
|
// CWin32DefaultArena is used.
|
|
// nInitialSize
|
|
// The initial size of the stream in bytes.
|
|
// nGrowBy
|
|
// How much to grow the internal buffer by when the caller has written
|
|
// past the end-of-stream.
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
CTransportStream::CTransportStream(
|
|
int nFlags,
|
|
CArena *pArena,
|
|
int nInitialSize,
|
|
int nGrowBy
|
|
|
|
) : CMemStream ( nFlags,pArena,nInitialSize,nGrowBy)
|
|
{
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::CTransportStream
|
|
//
|
|
// Binding constructor.
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
CTransportStream::CTransportStream(
|
|
LPVOID pBindingAddress,
|
|
CArena *pArena,
|
|
int nFlags,
|
|
int nGrowBy
|
|
|
|
) : CMemStream (pBindingAddress,pArena,nFlags,nGrowBy)
|
|
{
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::CTransportStream
|
|
//
|
|
// Copy constructor.
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
CTransportStream::CTransportStream(CTransportStream &Src) : CMemStream ( Src )
|
|
{
|
|
}
|
|
|
|
CTransportStream::~CTransportStream()
|
|
{
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::operator =
|
|
//
|
|
// Note that the arena is not copied as part of the assignment. This
|
|
// is to allow transfer of objects between arenas.
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
CTransportStream& CTransportStream::operator =(CTransportStream &Src)
|
|
{
|
|
CMemStream :: operator= ( Src ) ;
|
|
return *this;
|
|
}
|
|
|
|
#ifdef TCPIP_MARSHALER
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::Deserialize
|
|
//
|
|
// This function deserializes a stream from a Win32 file handle.
|
|
// This function only works for files (including memory mapped files, etc.)
|
|
/// and pipes. It will not work for mailslots since they must be read
|
|
// in one operation.
|
|
//
|
|
// PARAMETERS:
|
|
// hFile
|
|
// The Win32 file handle.
|
|
//
|
|
// RETURN VALUES:
|
|
// failed, out_of_memory, no_error
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
int CTransportStream::Deserialize(SOCKET a_Socket,DWORD a_Timeout)
|
|
{
|
|
Reset();
|
|
|
|
// Read the header. Note that we read this separately
|
|
// first before the stream proper. This is because we
|
|
// don't know how much memory to allocate until we have
|
|
// read the header.
|
|
// ====================================================
|
|
|
|
STREAM_HEADER &hdr = *(STREAM_HEADER *) m_pBuffer;
|
|
BOOL bRes;
|
|
DWORD dwRead;
|
|
|
|
fd_set t_fdset ;
|
|
FD_ZERO ( & t_fdset ) ;
|
|
FD_SET ( a_Socket , & t_fdset ) ;
|
|
|
|
timeval t_Timeval ;
|
|
ULONG t_Seconds = a_Timeout / 1000 ;
|
|
ULONG t_Microseconds = ( a_Timeout - ( t_Seconds * 1000 ) ) * 1000 ;
|
|
t_Timeval.tv_sec = t_Seconds ;
|
|
t_Timeval.tv_usec = t_Microseconds ;
|
|
|
|
int t_Number = select ( 1 , & t_fdset , NULL , NULL , & t_Timeval ) ;
|
|
if ( t_Number == 0 )
|
|
{
|
|
return timeout ;
|
|
}
|
|
|
|
dwRead = recv(a_Socket, (char*) &hdr, sizeof(hdr), 0);
|
|
if (dwRead == SOCKET_ERROR)
|
|
{
|
|
DWORD t_LastError = GetLastError () ;
|
|
return failed;
|
|
}
|
|
|
|
if(dwRead == 0)
|
|
{
|
|
return end_of_stream ;
|
|
}
|
|
|
|
if (!hdr.Verify())
|
|
return failed;
|
|
|
|
DWORD t_ReadLength = hdr.dwLength;
|
|
|
|
// Read the rest.
|
|
// ===============
|
|
if (Resize(hdr.dwLength))
|
|
return out_of_memory;
|
|
|
|
BYTE *t_ReadPosition = m_pBuffer + sizeof ( hdr ) ;
|
|
DWORD t_Remainder = m_dwSize - dwRead ;
|
|
|
|
while ( t_Remainder )
|
|
{
|
|
int t_Number = select ( 1 , & t_fdset , NULL , NULL , & t_Timeval ) ;
|
|
if ( t_Number == 0 )
|
|
{
|
|
return timeout ;
|
|
}
|
|
|
|
dwRead = recv(a_Socket, (char*) t_ReadPosition , t_Remainder, 0);
|
|
if (dwRead == SOCKET_ERROR)
|
|
{
|
|
DWORD t_LastError = GetLastError () ;
|
|
return failed;
|
|
}
|
|
|
|
if(dwRead == 0)
|
|
{
|
|
return end_of_stream ;
|
|
}
|
|
|
|
t_Remainder = t_Remainder - dwRead ;
|
|
t_ReadPosition = t_ReadPosition + dwRead ;
|
|
}
|
|
|
|
m_dwEndOfStream = t_ReadLength;
|
|
|
|
return no_error;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CTransportStream::Serialize
|
|
//
|
|
// Writes the object to a Win32 file.
|
|
//
|
|
// PARAMETERS:
|
|
// hFile
|
|
// The Win32 file handle to which to write the object.
|
|
//
|
|
// RETURN VALUES:
|
|
// failed, no_error
|
|
//
|
|
//***************************************************************************
|
|
// ok
|
|
int CTransportStream::Serialize(SOCKET a_Socket)
|
|
{
|
|
UpdateHdr();
|
|
|
|
// Write body of stream. This includes the header.
|
|
// ================================================
|
|
|
|
DWORD dwWritten = 0;
|
|
dwWritten = send(a_Socket, (char*) m_pBuffer, m_dwEndOfStream, 0);
|
|
if (dwWritten== SOCKET_ERROR)
|
|
return failed;
|
|
|
|
return no_error;
|
|
}
|
|
|
|
#endif // TCPIP_MARSHALER
|