Leaked source code of windows server 2003
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

/*==========================================================================
*
* 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 );
}