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.
368 lines
11 KiB
368 lines
11 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: ServProv.cpp
|
|
* Content: Service Provider Objects
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 03/17/00 mjn Created
|
|
* 04/04/00 rmt Added set of SP caps from cache (if cache exists).
|
|
* 04/10/00 mjn Farm out RemoveSP to worker thread
|
|
* 05/02/00 mjn Fixed RefCount issue
|
|
* 06/09/00 rmt Updates to split CLSID and allow whistler compat
|
|
* 07/06/00 mjn Fixes to support SP handle to Protocol
|
|
* 08/03/00 rmt Bug #41244 - Wrong return codes -- part 2
|
|
* 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
|
|
* 08/06/00 mjn Added CWorkerJob
|
|
* 08/20/00 mjn Changed Initialize() to not add SP to DirectNet object bilink
|
|
* 10/08/01 vanceo Add multicast filter
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dncorei.h"
|
|
|
|
|
|
//**********************************************************************
|
|
// Constant definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Macro definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Structure definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Variable definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function prototypes
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function definitions
|
|
//**********************************************************************
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CServiceProvider::Initialize"
|
|
|
|
HRESULT CServiceProvider::Initialize(DIRECTNETOBJECT *const pdnObject
|
|
#if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_PREALLOCATEDMEMORYMODEL)))
|
|
,const XDP8CREATE_PARAMS * const pDP8CreateParams
|
|
#else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
,const GUID *const pguid
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
#ifndef DPNBUILD_LIBINTERFACE
|
|
,const GUID *const pguidApplication
|
|
#endif // ! DPNBUILD_LIBINTERFACE
|
|
#endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
)
|
|
{
|
|
HRESULT hResultCode;
|
|
IDP8ServiceProvider *pISP;
|
|
BOOL fAddedToProtocol;
|
|
#ifndef DPNBUILD_LIBINTERFACE
|
|
SPISAPPLICATIONSUPPORTEDDATA spAppSupData;
|
|
#endif // ! DPNBUILD_LIBINTERFACE
|
|
|
|
|
|
DNASSERT(pdnObject != NULL);
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
DNASSERT(pguid != NULL);
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
|
|
m_pdnObject = NULL;
|
|
#if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
|
|
m_lRefCount = 0;
|
|
#else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
m_lRefCount = 1;
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
m_pISP = NULL;
|
|
m_hProtocolSPHandle = NULL;
|
|
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
m_bilinkServiceProviders.Initialize();
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
|
|
pISP = NULL;
|
|
fAddedToProtocol = FALSE;
|
|
|
|
m_pdnObject = pdnObject;
|
|
|
|
//
|
|
// Instantiate SP
|
|
//
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
if (IsEqualCLSID(*pguid, CLSID_DP8SP_TCPIP))
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
{
|
|
hResultCode = CreateIPInterface(
|
|
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
pDP8CreateParams,
|
|
#endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
&pISP
|
|
);
|
|
}
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
#ifndef DPNBUILD_NOIPX
|
|
else if (IsEqualCLSID(*pguid, CLSID_DP8SP_IPX))
|
|
{
|
|
hResultCode = CreateIPXInterface(
|
|
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
pDP8CreateParams,
|
|
#endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
&pISP
|
|
);
|
|
}
|
|
#endif // ! DPNBUILD_NOIPX
|
|
#ifndef DPNBUILD_NOSERIALSP
|
|
else if (IsEqualCLSID(*pguid, CLSID_DP8SP_MODEM))
|
|
{
|
|
hResultCode = CreateModemInterface(
|
|
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
pDP8CreateParams,
|
|
#endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
&pISP
|
|
);
|
|
}
|
|
else if (IsEqualCLSID(*pguid, CLSID_DP8SP_SERIAL))
|
|
{
|
|
hResultCode = CreateSerialInterface(
|
|
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
pDP8CreateParams,
|
|
#endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
|
|
&pISP
|
|
);
|
|
}
|
|
#endif // ! DPNBUILD_NOSERIALSP
|
|
else
|
|
{
|
|
hResultCode = COM_CoCreateInstance(*pguid,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDP8ServiceProvider,
|
|
reinterpret_cast<void**>(&pISP),
|
|
FALSE);
|
|
}
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
if (hResultCode != S_OK)
|
|
{
|
|
DPFX(DPFPREP,0,"Could not instantiate SP (err = 0x%lx)!",hResultCode);
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
DisplayDNError(0,hResultCode);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Add SP to Protocol Layer
|
|
//
|
|
#if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
|
|
DNProtocolAddRef(pdnObject);
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
|
|
//Flags parameter for DNPAddServiceProvider is passed through as the
|
|
//flags parameter in the SPINITIALIZEDATA structure to the SP
|
|
//We pass the session type via it
|
|
DWORD dwFlags;
|
|
if (pdnObject->dwFlags & DN_OBJECT_FLAG_PEER)
|
|
dwFlags=SP_SESSION_TYPE_PEER;
|
|
else if (pdnObject->dwFlags & DN_OBJECT_FLAG_CLIENT)
|
|
dwFlags=SP_SESSION_TYPE_CLIENT;
|
|
else
|
|
{
|
|
DNASSERT(pdnObject->dwFlags & DN_OBJECT_FLAG_SERVER);
|
|
dwFlags=SP_SESSION_TYPE_SERVER;
|
|
}
|
|
hResultCode = DNPAddServiceProvider(m_pdnObject->pdnProtocolData, pISP,
|
|
&m_hProtocolSPHandle, dwFlags);
|
|
if (hResultCode!= DPN_OK)
|
|
{
|
|
DPFX(DPFPREP,1,"Could not add service provider to protocol");
|
|
DisplayDNError(1,hResultCode);
|
|
#if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
|
|
DNProtocolRelease(pdnObject);
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
goto Failure;
|
|
}
|
|
|
|
fAddedToProtocol = TRUE;
|
|
|
|
#ifndef DPNBUILD_NOMULTICAST
|
|
//
|
|
// If this is a multicast object, make sure the SP in question supports multicasting.
|
|
//
|
|
if (pdnObject->dwFlags & DN_OBJECT_FLAG_MULTICAST)
|
|
{
|
|
SPGETCAPSDATA spGetCapsData;
|
|
|
|
//
|
|
// Get the SP caps
|
|
//
|
|
memset( &spGetCapsData, 0x00, sizeof( SPGETCAPSDATA ) );
|
|
spGetCapsData.dwSize = sizeof( SPGETCAPSDATA );
|
|
spGetCapsData.hEndpoint = INVALID_HANDLE_VALUE;
|
|
if ((hResultCode = IDP8ServiceProvider_GetCaps( pISP, &spGetCapsData )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not get SP caps");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Check for the multicast support flag.
|
|
//
|
|
if (! (spGetCapsData.dwFlags & DPNSPCAPS_SUPPORTSMULTICAST))
|
|
{
|
|
DPFX(DPFPREP,1,"Service provider does not support multicasting.");
|
|
hResultCode = DPNERR_UNSUPPORTED;
|
|
goto Failure;
|
|
}
|
|
}
|
|
#endif // ! DPNBUILD_NOMULTICAST
|
|
|
|
#ifndef DPNBUILD_LIBINTERFACE
|
|
//
|
|
// If an application GUID was given, make sure the SP can be used by that app.
|
|
//
|
|
if (pguidApplication != NULL) // app GUID given
|
|
{
|
|
spAppSupData.pApplicationGuid = pguidApplication;
|
|
spAppSupData.dwFlags = 0;
|
|
if ((hResultCode = IDP8ServiceProvider_IsApplicationSupported(pISP,&spAppSupData)) != DPN_OK) // SP doesn't support app
|
|
{
|
|
DPFX(DPFPREP,1,"Service provider does not support app (err = 0x%lx).", hResultCode);
|
|
hResultCode = DPNERR_UNSUPPORTED;
|
|
goto Failure;
|
|
}
|
|
}
|
|
#endif // ! DPNBUILD_LIBINTERFACE
|
|
|
|
IDP8ServiceProvider_AddRef(pISP);
|
|
m_pISP = pISP;
|
|
IDP8ServiceProvider_Release(pISP);
|
|
pISP = NULL;
|
|
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
m_guid = *pguid;
|
|
/* REMOVE
|
|
// Add to bilink
|
|
AddRef();
|
|
m_bilink.InsertBefore(&m_pdnObject->m_bilinkServiceProviders);
|
|
*/
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
|
|
hResultCode = DPN_OK;
|
|
|
|
Exit:
|
|
return(hResultCode);
|
|
|
|
Failure:
|
|
|
|
if (fAddedToProtocol)
|
|
{
|
|
//
|
|
// Ignore failure.
|
|
//
|
|
DNPRemoveServiceProvider(pdnObject->pdnProtocolData,m_hProtocolSPHandle);
|
|
#if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
|
|
DNProtocolRelease(pdnObject);
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
}
|
|
|
|
if (pISP)
|
|
{
|
|
IDP8ServiceProvider_Release(pISP);
|
|
pISP = NULL;
|
|
}
|
|
goto Exit;
|
|
};
|
|
|
|
|
|
#if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CServiceProvider::Deinitialize"
|
|
|
|
void CServiceProvider::Deinitialize( void )
|
|
#else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CServiceProvider::Release"
|
|
|
|
void CServiceProvider::Release( void )
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
{
|
|
HRESULT hResultCode;
|
|
|
|
#if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
|
|
DNASSERT(m_lRefCount == 0);
|
|
#else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
LONG lRefCount;
|
|
|
|
lRefCount = DNInterlockedDecrement(&m_lRefCount);
|
|
DPFX(DPFPREP, 9,"[0x%p] new RefCount [%ld]",this,lRefCount);
|
|
DNASSERT(lRefCount >= 0);
|
|
if (lRefCount == 0)
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
{
|
|
#if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
|
|
hResultCode = DNPRemoveServiceProvider(m_pdnObject->pdnProtocolData,m_hProtocolSPHandle);
|
|
if (hResultCode != DPN_OK)
|
|
#else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
CWorkerJob *pWorkerJob;
|
|
|
|
pWorkerJob = NULL;
|
|
|
|
if ((hResultCode = WorkerJobNew(m_pdnObject,&pWorkerJob)) == DPN_OK)
|
|
{
|
|
pWorkerJob->SetJobType( WORKER_JOB_REMOVE_SERVICE_PROVIDER );
|
|
DNASSERT( m_hProtocolSPHandle != NULL );
|
|
pWorkerJob->SetRemoveServiceProviderHandle( m_hProtocolSPHandle );
|
|
|
|
DNQueueWorkerJob(m_pdnObject,pWorkerJob);
|
|
pWorkerJob = NULL;
|
|
}
|
|
else
|
|
#endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
|
|
{
|
|
DPFERR("Could not remove SP");
|
|
DisplayDNError(0,hResultCode);
|
|
DNASSERT(FALSE);
|
|
}
|
|
if (m_pISP)
|
|
{
|
|
IDP8ServiceProvider_Release(m_pISP);
|
|
m_pISP = NULL;
|
|
}
|
|
|
|
m_pdnObject = NULL;
|
|
|
|
DNFree(this);
|
|
}
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CServiceProvider::GetInterfaceRef"
|
|
|
|
HRESULT CServiceProvider::GetInterfaceRef( IDP8ServiceProvider **ppIDP8SP )
|
|
{
|
|
DNASSERT( ppIDP8SP != NULL );
|
|
|
|
if (m_pISP == NULL)
|
|
{
|
|
return( DPNERR_GENERIC );
|
|
}
|
|
|
|
IDP8ServiceProvider_AddRef( m_pISP );
|
|
*ppIDP8SP = m_pISP;
|
|
|
|
return( DPN_OK );
|
|
}
|
|
|