779 lines
21 KiB
C++
779 lines
21 KiB
C++
/*++
|
|
|
|
Copyright (C) 1997-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
TCPIP.CPP
|
|
|
|
Abstract:
|
|
|
|
Defines the functions used for tcpip transport.
|
|
|
|
History:
|
|
|
|
a-davj 16-june-97 Created.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include "wmishared.h"
|
|
#include "tcpip.h"
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD LaunchReadTcpipThread
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Starting point for anon pipe read thread.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pParam pointer to comlink object
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// 0
|
|
//***************************************************************************
|
|
|
|
DWORD LaunchReadTcpipThread ( LPDWORD pParam )
|
|
{
|
|
InitializeCom () ;
|
|
CComLink_Tcpip *t_Com = ( CComLink_Tcpip *) pParam ;
|
|
|
|
return t_Com->DoReading () ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CComLink_Tcpip::CComLink_Tcpip
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Constructor.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// hRead write handle
|
|
// hWrite read handle
|
|
// Type comlink type
|
|
// hTerm event which can be set to invoke destruction
|
|
//
|
|
//***************************************************************************
|
|
|
|
CComLink_Tcpip::CComLink_Tcpip (
|
|
|
|
IN LinkType a_Type,
|
|
IN SOCKET a_Socket
|
|
|
|
) : CComLink ( a_Type ) ,
|
|
m_Socket ( a_Socket )
|
|
{
|
|
DWORD t_ThreadId ;
|
|
|
|
AddRef2 ( NULL , NONE , DONOTHING ) ;
|
|
|
|
m_ReadThread = CreateThread (
|
|
|
|
NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) LaunchReadTcpipThread,
|
|
(LPVOID)this,
|
|
0,
|
|
&t_ThreadId
|
|
) ;
|
|
|
|
m_ReadThreadDoneEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
|
|
gMaintObj.AddComLink ( this ) ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CComLink_Tcpip::~CComLink_Tcpip
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Destructor.
|
|
//
|
|
//***************************************************************************
|
|
|
|
CComLink_Tcpip :: ~CComLink_Tcpip ()
|
|
{
|
|
DEBUGTRACE((LOG,"\nLocal Tcpip comlink [0x%x] is terminating", this));
|
|
|
|
// Stop the read thread
|
|
|
|
if(m_ReadThread)
|
|
{
|
|
DWORD dwRet = WbemWaitForSingleObject ( m_ReadThreadDoneEvent , 2000 ) ;
|
|
if ( dwRet != WAIT_OBJECT_0 )
|
|
{
|
|
}
|
|
|
|
if ( m_Socket )
|
|
closesocket ( m_Socket) ;
|
|
|
|
if ( m_ReadThread )
|
|
CloseHandle ( m_ReadThread ) ;
|
|
|
|
if ( m_ReadThreadDoneEvent )
|
|
CloseHandle ( m_ReadThreadDoneEvent ) ;
|
|
|
|
TerminateThread ( m_ReadThread , 1 ) ;
|
|
|
|
return ;
|
|
}
|
|
|
|
if ( m_Socket )
|
|
closesocket ( m_Socket ) ;
|
|
|
|
if ( m_ReadThread )
|
|
CloseHandle ( m_ReadThread ) ;
|
|
|
|
if ( m_ReadThreadDoneEvent )
|
|
CloseHandle ( m_ReadThreadDoneEvent ) ;
|
|
|
|
}
|
|
|
|
DWORD CComLink_Tcpip :: Call ( IN IOperation &a_Operation )
|
|
{
|
|
HRESULT t_Result = WBEM_E_TRANSPORT_FAILURE;
|
|
|
|
// Verify that the streams are OK and get a slot in the write queue
|
|
|
|
if ( ! SUCCEEDED ( a_Operation.GetStatus () ) )
|
|
{
|
|
t_Result = WBEM_E_INVALID_STREAM;
|
|
}
|
|
else
|
|
{
|
|
BOOL t_ReceivedResponse = FALSE ;
|
|
|
|
HANDLE t_EventContainer [ 2 ] ;
|
|
|
|
t_EventContainer [ 0 ] = m_WriteQueue.AllocateRequest ( a_Operation ) ;
|
|
if ( ! t_EventContainer [ 0 ] )
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
else
|
|
{
|
|
t_EventContainer [ 1 ] = m_TerminationEvent ;
|
|
|
|
ResetEvent ( t_EventContainer [ 0 ] ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
CTransportStream t_WriteStream ;
|
|
|
|
bool t_Status = a_Operation.EncodeRequest ( t_WriteStream , t_Helper ) ;
|
|
if ( t_Status )
|
|
{
|
|
Transmit ( t_WriteStream ) ;
|
|
|
|
DWORD t_Status = WbemWaitForMultipleObjects ( 2 , t_EventContainer , INFINITE ) ;
|
|
|
|
// Check for forced termiation
|
|
// ===========================
|
|
|
|
switch ( t_Status )
|
|
{
|
|
case WAIT_OBJECT_0+1:
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE; // Termination event
|
|
}
|
|
break ;
|
|
|
|
case WAIT_OBJECT_0:
|
|
{
|
|
if ( m_WriteQueue.GetRequestStatus ( t_EventContainer [0] ) == COMLINK_MSG_RETURN )
|
|
{
|
|
CTransportStream &t_ReadStream = a_Operation.GetDecodeStream ();
|
|
t_ReadStream.Reset () ;
|
|
DWORD t_Position = t_ReadStream.GetCurrentPos () + sizeof ( PACKET_HEADER ) ;
|
|
t_ReadStream.SetCurrentPos ( t_Position ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
if ( a_Operation.DecodeResponse ( t_ReadStream , t_Helper ) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
// looks good so far. Get the return code
|
|
|
|
t_Result = a_Operation.GetStatus () ;
|
|
|
|
}
|
|
else if ( m_WriteQueue.GetRequestStatus ( t_EventContainer [0] ) == COMLINK_MSG_RETURN_FATAL_ERROR )
|
|
{
|
|
// this occures only if the server is out of resources, in that
|
|
// case we dont want to send additional request.
|
|
// ============================================================
|
|
|
|
t_Result = WBEM_E_PROVIDER_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// All done, give up the slot and return.
|
|
|
|
m_WriteQueue.DeallocateRequest ( t_EventContainer [ 0 ] ) ;
|
|
|
|
a_Operation.SetErrorInfoOnThread () ;
|
|
}
|
|
|
|
a_Operation.SetStatus ( t_Result ) ;
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// int CComLink_Tcpip::Transmit
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Transmitts a packet via the anon pipe
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// dwSend type of package
|
|
// *pSendStream stream containing data to write
|
|
// guidPacketID GUILD to identify packet
|
|
// hWrite write header
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// S_OK all is well
|
|
// WBEM_E_TRANSPORT_FAILURE if write fails
|
|
// otherwise error set by Serialize
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD CComLink_Tcpip::Transmit ( CTransportStream &a_WriteStream )
|
|
{
|
|
BOOL t_Status = TRUE ;
|
|
|
|
#if 0
|
|
DWORD t_Result = WbemWaitForSingleObject ( m_WriteMutex , MAX_WAIT_FOR_WRITE ) ;
|
|
#else
|
|
DWORD t_Result = WAIT_OBJECT_0 ;
|
|
EnterCriticalSection(&m_cs);
|
|
#endif
|
|
|
|
if ( t_Result == WAIT_OBJECT_0 )
|
|
{
|
|
t_Result = a_WriteStream.Serialize ( (HANDLE)m_Socket ) ; // Serialise the stream to the pipe
|
|
t_Status = SUCCEEDED ( t_Result ) ;
|
|
if ( ! t_Status )
|
|
{
|
|
// Set Some internal error
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = FALSE ;
|
|
}
|
|
|
|
#if 0
|
|
ReleaseMutex ( m_WriteMutex ) ;
|
|
#else
|
|
LeaveCriticalSection(&m_cs);
|
|
#endif
|
|
|
|
return t_Status ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CComLink_Tcpip::DoReading
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Where the anon pipe read thread lives.
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD CComLink_Tcpip :: DoReading ()
|
|
{
|
|
while ( 1 )
|
|
{
|
|
DWORD t_Result = WbemWaitForSingleObject ( m_TerminationEvent , 0 ) ;
|
|
if ( t_Result != WAIT_OBJECT_0 )
|
|
{
|
|
CTransportStream t_ReadStream ;
|
|
switch ( t_ReadStream.Deserialize ( (HANDLE)m_Socket ) )
|
|
{
|
|
case CTransportStream :: failed:
|
|
case CTransportStream :: out_of_memory:
|
|
{
|
|
DWORD t_ErrorResult = GetLastError () ;
|
|
SetEvent ( m_TerminationEvent ) ;
|
|
SetEvent ( m_ReadThreadDoneEvent ) ;
|
|
|
|
Release2 ( NULL , NONE ) ;
|
|
|
|
CoUninitialize () ;
|
|
ExitThread ( 0 ) ; // terminate the thread
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_ReadStream.Reset () ;
|
|
PACKET_HEADER *t_PacketHeader = (PACKET_HEADER *)
|
|
((BYTE *)t_ReadStream.GetPtr() + t_ReadStream.GetCurrentPos());
|
|
|
|
ProcessRead (
|
|
|
|
t_PacketHeader ,
|
|
( unsigned char * ) t_ReadStream.GetPtr () ,
|
|
t_ReadStream.Size ()
|
|
) ;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetEvent ( m_ReadThreadDoneEvent ) ;
|
|
Release2 ( NULL , NONE ) ;
|
|
CoUninitialize () ;
|
|
ExitThread ( 0 ) ; // terminate the thread
|
|
}
|
|
}
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// void CComLink::ProcessRead
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Got a package from our partner. It could be a response to something
|
|
// we sent, or it could be something initiated in our partner.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pPacketHeader pointer to header object
|
|
// pData data to be sent
|
|
// dwDataSize size of data
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
void CComLink_Tcpip :: ProcessRead (
|
|
|
|
IN PACKET_HEADER *a_PacketHeader ,
|
|
IN BYTE *a_PayLoadData ,
|
|
IN DWORD a_PayLoadSize
|
|
)
|
|
{
|
|
m_LastReadTime = GetCurrentTime ();
|
|
|
|
// bump up the count at the start and restore at the end of this
|
|
// routine. This is done so that object wount disappear in the
|
|
// middle of handling a read.
|
|
//==============================================================
|
|
|
|
AddRef2(NULL, NONE, DONOTHING);
|
|
|
|
DWORD t_Type = a_PacketHeader->GetType();
|
|
RequestId t_RequestId = a_PacketHeader->GetRequestId ();
|
|
|
|
DEBUGTRACE((LOG,"\nProcessing Read on comlink [0x%x], type is %d RequestId=%d",
|
|
this, t_Type,t_RequestId));
|
|
|
|
|
|
if ( t_Type == COMLINK_MSG_RETURN || t_Type == COMLINK_MSG_RETURN_FATAL_ERROR )
|
|
{
|
|
IOperation *t_Operation = m_WriteQueue.GetOperation ( t_RequestId );
|
|
if ( ! t_Operation )
|
|
{
|
|
Release2 ( NULL , NONE ) ;
|
|
|
|
return; //todo, else, should bitch
|
|
}
|
|
|
|
if ( t_Type == COMLINK_MSG_RETURN )
|
|
{
|
|
CTransportStream &t_ReadStream = t_Operation->GetDecodeStream ();
|
|
t_ReadStream.CMemStream :: Deserialize ( a_PayLoadData , a_PayLoadSize ) ;
|
|
}
|
|
else
|
|
{
|
|
t_Operation->SetStatus ( WBEM_E_PROVIDER_FAILURE ) ;
|
|
}
|
|
|
|
m_WriteQueue.SetEventAndStatus ( t_RequestId , t_Type ) ;
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_CALL )
|
|
{
|
|
// This is a new call. This might be lengthy
|
|
// and so a thread is created to call the stub. If the thread is
|
|
// created, it is responsible for freeing up the allocations and
|
|
// doing an extra Release on the comlink
|
|
// =================================================================
|
|
|
|
// ISecurityHelper t_Helper ;
|
|
CTransportStream t_ReadStream ;
|
|
t_ReadStream.CMemStream :: Deserialize ( a_PayLoadData , a_PayLoadSize ) ;
|
|
|
|
t_ReadStream.Reset () ;
|
|
DWORD t_Position = t_ReadStream.GetCurrentPos () + sizeof ( PACKET_HEADER ) ;
|
|
t_ReadStream.SetCurrentPos ( t_Position ) ;
|
|
|
|
IOperation *t_Operation = NULL ;
|
|
if ( IOperation_LPipe :: Decode ( *a_PacketHeader , t_ReadStream , &t_Operation ) )
|
|
{
|
|
ISecurityHelper t_Helper ;
|
|
if ( t_Operation->DecodeRequest ( t_ReadStream , t_Helper ) )
|
|
{
|
|
HANDLE t_ReadEvent = m_ReadQueue.AllocateRequest ( *t_Operation );
|
|
if ( t_ReadEvent )
|
|
{
|
|
BOOL t_Status = gThrdPool.Execute (
|
|
|
|
*this ,
|
|
*t_Operation
|
|
) ;
|
|
|
|
if ( t_Status )
|
|
{
|
|
return ;
|
|
}
|
|
|
|
// should only be here if some failure, clean up any allocations
|
|
|
|
if ( t_ReadEvent )
|
|
{
|
|
m_ReadQueue.DeallocateRequest ( t_ReadEvent ) ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_PING )
|
|
{
|
|
// Reply to strobe
|
|
|
|
ISecurityHelper t_Helper ;
|
|
COperation_LPipe_Ping t_pingOp (*a_PacketHeader);
|
|
CTransportStream t_WriteStream ;
|
|
|
|
if (t_pingOp.EncodeResponse ( t_WriteStream, t_Helper ))
|
|
{
|
|
if ( Transmit ( t_WriteStream ) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_PING_ACK )
|
|
{
|
|
// simple ack type
|
|
m_WriteQueue.SetEventAndStatus ( t_RequestId ,t_Type ) ;
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_CALL_NACK )
|
|
{
|
|
// simple ack type
|
|
m_WriteQueue.SetEventAndStatus ( t_RequestId ,t_Type ) ;
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_HEART_BEAT )
|
|
{
|
|
ISecurityHelper t_Helper ;
|
|
COperation_LPipe_Strobe t_StrobeOp (*a_PacketHeader);
|
|
CTransportStream t_WriteStream ;
|
|
|
|
if (t_StrobeOp.EncodeResponse ( t_WriteStream, t_Helper ))
|
|
{
|
|
if ( Transmit ( t_WriteStream ) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_HEART_BEAT_ACK )
|
|
{
|
|
}
|
|
else if ( t_Type == COMLINK_MSG_NOTIFY_DESTRUCT )
|
|
{
|
|
SetEvent ( m_TerminationEvent ) ;
|
|
gMaintObj.ShutDownComlink ( this ) ;
|
|
}
|
|
else
|
|
{
|
|
// ???
|
|
}
|
|
|
|
Release2 ( NULL , NONE ) ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD CComLink::Ping
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Sends a simple message and waits for a simple ack. This is used as a
|
|
// "heart beat" test.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// hTerm1 First event handle that can be used to stop this call
|
|
// hTerm2 second event handle that can be used to stop this call
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// S_OK no error,
|
|
// else set by SendAndWaitSimple
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD CComLink_Tcpip :: ProbeConnection ()
|
|
{
|
|
HRESULT t_Result ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
|
|
COperation_LPipe_Ping t_Operation ;
|
|
|
|
HANDLE t_EventContainer [ 2 ] ;
|
|
|
|
t_EventContainer [ 0 ] = m_WriteQueue.AllocateRequest ( t_Operation ) ;
|
|
if ( ! t_EventContainer [ 0 ] )
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
else
|
|
{
|
|
t_EventContainer [ 1 ] = m_TerminationEvent ;
|
|
|
|
ResetEvent ( t_EventContainer [ 0 ] ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
CTransportStream t_WriteStream ;
|
|
|
|
bool t_Status = t_Operation.EncodeRequest ( t_WriteStream , t_Helper ) ;
|
|
if ( t_Status )
|
|
{
|
|
Transmit ( t_WriteStream ) ;
|
|
|
|
DWORD t_Status = WbemWaitForMultipleObjects ( 2 , t_EventContainer , INFINITE ) ;
|
|
|
|
// Check for forced termiation
|
|
// ===========================
|
|
|
|
switch ( t_Status )
|
|
{
|
|
case WAIT_OBJECT_0+1:
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE; // Termination event
|
|
}
|
|
break ;
|
|
|
|
case WAIT_OBJECT_0:
|
|
{
|
|
if ( m_WriteQueue.GetRequestStatus ( t_EventContainer [0] ) == COMLINK_MSG_PING_ACK && SUCCEEDED ( t_Operation.GetStatus () ) )
|
|
{
|
|
// looks good so far. Get the return code
|
|
|
|
}
|
|
else if ( m_WriteQueue.GetRequestStatus ( t_EventContainer [0] ) == COMLINK_MSG_RETURN_FATAL_ERROR )
|
|
{
|
|
// this occures only if the server is out of resources, in that
|
|
// case we dont want to send additional request.
|
|
// ============================================================
|
|
|
|
t_Result = WBEM_E_PROVIDER_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE;
|
|
}
|
|
}
|
|
break ;
|
|
|
|
default:
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Result = WBEM_E_TRANSPORT_FAILURE ;
|
|
}
|
|
|
|
// All done, give up the slot and return.
|
|
|
|
m_WriteQueue.DeallocateRequest ( t_EventContainer [ 0 ] ) ;
|
|
|
|
}
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD CComLink::Ping
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Sends a simple message and waits for a simple ack. This is used as a
|
|
// "heart beat" test.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// hTerm1 First event handle that can be used to stop this call
|
|
// hTerm2 second event handle that can be used to stop this call
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// S_OK no error,
|
|
// else set by SendAndWaitSimple
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD CComLink_Tcpip :: StrobeConnection ()
|
|
{
|
|
HRESULT t_Result ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
|
|
COperation_LPipe_Strobe t_Operation ;
|
|
|
|
HANDLE t_EventContainer [ 1 ] ;
|
|
|
|
t_EventContainer [ 0 ] = m_WriteQueue.AllocateRequest ( t_Operation ) ;
|
|
if ( ! t_EventContainer [ 0 ] )
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
else
|
|
{
|
|
ResetEvent ( t_EventContainer [ 0 ] ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
CTransportStream t_WriteStream ;
|
|
|
|
bool t_Status = t_Operation.EncodeRequest ( t_WriteStream , t_Helper ) ;
|
|
if ( t_Status )
|
|
{
|
|
Transmit ( t_WriteStream ) ;
|
|
}
|
|
|
|
// All done, give up the slot and return.
|
|
|
|
m_WriteQueue.DeallocateRequest ( t_EventContainer [ 0 ] ) ;
|
|
}
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
DWORD CComLink_Tcpip :: Shutdown ()
|
|
{
|
|
HRESULT t_Result ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
|
|
COperation_LPipe_Shutdown t_Operation ;
|
|
|
|
HANDLE t_EventContainer [ 1 ] ;
|
|
|
|
t_EventContainer [ 0 ] = m_WriteQueue.AllocateRequest ( t_Operation ) ;
|
|
if ( ! t_EventContainer [ 0 ] )
|
|
{
|
|
t_Result = WBEM_E_OUT_OF_MEMORY ;
|
|
}
|
|
else
|
|
{
|
|
ResetEvent ( t_EventContainer [ 0 ] ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
CTransportStream t_WriteStream ;
|
|
|
|
bool t_Status = t_Operation.EncodeRequest ( t_WriteStream , t_Helper ) ;
|
|
if ( t_Status )
|
|
{
|
|
Transmit ( t_WriteStream ) ;
|
|
}
|
|
|
|
m_WriteQueue.DeallocateRequest ( t_EventContainer [ 0 ] ) ;
|
|
}
|
|
|
|
DropLink () ;
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
DWORD CComLink_Tcpip :: HandleCall ( IN IOperation &a_Operation )
|
|
{
|
|
a_Operation.HandleCall ( *this ) ;
|
|
|
|
ISecurityHelper t_Helper ;
|
|
CTransportStream t_WriteStream ;
|
|
|
|
bool t_Status = a_Operation.EncodeResponse ( t_WriteStream , t_Helper ) ;
|
|
if ( t_Status )
|
|
{
|
|
Transmit ( t_WriteStream ) ;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
m_ReadQueue.DeallocateRequest ( m_ReadQueue.GetHandle ( a_Operation.GetRequestId () ) ) ;
|
|
|
|
HRESULT t_Result = a_Operation.GetStatus () ;
|
|
|
|
IOperation *t_Operation = & a_Operation ;
|
|
|
|
delete t_Operation ;
|
|
|
|
return t_Result ;
|
|
}
|
|
|
|
CObjectSinkProxy* CComLink_Tcpip::CreateObjectSinkProxy (IN IStubAddress& stubAddr,
|
|
IN IWbemServices* pServices)
|
|
{
|
|
return new CObjectSinkProxy_LPipe (this, stubAddr, pServices);
|
|
}
|
|
|
|
void CComLink_Tcpip :: DropLink ()
|
|
{
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
ReleaseStubs () ;
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
}
|