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.
625 lines
16 KiB
625 lines
16 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: Caps.cpp
|
|
* Content: Dplay8 caps routines
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 03/17/00 rmt Created
|
|
* 03/23/00 rmt Removed unused local variables
|
|
* 03/25/00 rmt Updated to make calls into SP's function
|
|
* rmt Updated SP calls to Initialize SP (and create if required)
|
|
* 03/31/00 rmt Hooked up the GetCaps/SetCaps calls to call the protocol
|
|
* 04/17/00 rmt Strong param validation
|
|
* 04/19/00 mjn Removed AddRef() for NameTableEntry in DN_GetConnectionInfoHelper()
|
|
* 05/03/00 mjn Use GetHostPlayerRef() rather than GetHostPlayer()
|
|
* 06/05/00 mjn Fixed DN_GetConnectionInfoHelper() to use GetConnectionRef
|
|
* 06/09/00 rmt Updates to split CLSID and allow whistler compat
|
|
* 07/06/00 mjn Use GetInterfaceRef for SP interface
|
|
* mjn Fixed up DN_SetActualSPCaps() and DN_GetActualSPCaps()
|
|
* 07/29/00 mjn Fixed SetSPCaps() recursion problem
|
|
* 07/31/00 mjn Renamed dwDefaultEnumRetryCount to dwDefaultEnumCount in DPN_SP_CAPS
|
|
* 08/03/2000 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/05/00 mjn Added dwFlags to DN_GetConnectionInfoHelper()
|
|
* 08/20/00 mjn DNSetActualSPCaps() uses CServiceProvider object instead of GUID
|
|
* 01/22/01 mjn Fixed debug text in DN_GetConnectionInfoHelper()
|
|
* 02/12/01 mjn Fixed CConnection::GetEndPt() to track calling thread
|
|
* 03/30/01 mjn Changes to prevent multiple loading/unloading of SP's
|
|
* mjn Removed cached caps functionallity
|
|
* 07/24/01 mjn Added DPNBUILD_NOPARAMVAL compile flag
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dncorei.h"
|
|
|
|
|
|
// DN_SetCaps
|
|
//
|
|
// Set caps
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_SetCaps"
|
|
|
|
STDMETHODIMP DN_SetCaps(PVOID pv,
|
|
const DPN_CAPS *const pdnCaps,
|
|
const DWORD dwFlags)
|
|
{
|
|
DIRECTNETOBJECT *pdnObject;
|
|
HRESULT hResultCode;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pdnCaps [0x%p] dwFlags [0x%lx]", pdnCaps, dwFlags );
|
|
|
|
pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
|
|
DNASSERT(pdnObject != NULL);
|
|
|
|
#ifndef DPNBUILD_NOPARAMVAL
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
|
|
{
|
|
if( FAILED( hResultCode = DN_ValidateSetCaps( pv, pdnCaps, dwFlags ) ) )
|
|
{
|
|
DPFERR( "Error validating SetCaps params" );
|
|
DPF_RETURN( hResultCode );
|
|
}
|
|
}
|
|
#endif // !DPNBUILD_NOPARAMVAL
|
|
|
|
// Check to ensure message handler registered
|
|
if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
|
|
{
|
|
DPFERR( "Object is not initialized" );
|
|
DPF_RETURN(DPNERR_UNINITIALIZED);
|
|
}
|
|
|
|
hResultCode = DNPSetProtocolCaps( pdnObject->pdnProtocolData, (DPN_CAPS*)pdnCaps );
|
|
|
|
DPF_RETURN(hResultCode);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_GetCaps"
|
|
|
|
STDMETHODIMP DN_GetCaps(PVOID pv,
|
|
DPN_CAPS *const pdnCaps,
|
|
const DWORD dwFlags)
|
|
{
|
|
DPFX(DPFPREP, 2,"Parameters: pdnCaps [0x%p], dwFlags [0x%lx]", pdnCaps,dwFlags);
|
|
|
|
DIRECTNETOBJECT *pdnObject;
|
|
HRESULT hResultCode;
|
|
|
|
pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
|
|
DNASSERT(pdnObject != NULL);
|
|
|
|
#ifndef DPNBUILD_NOPARAMVAL
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
|
|
{
|
|
if( FAILED( hResultCode = DN_ValidateGetCaps( pv, pdnCaps, dwFlags ) ) )
|
|
{
|
|
DPFERR( "Error validating GetCaps params" );
|
|
DPF_RETURN( hResultCode );
|
|
}
|
|
}
|
|
#endif // DPNBUILD_NOPARAMVAL
|
|
|
|
// Check to ensure message handler registered
|
|
if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
|
|
{
|
|
DPFERR( "Object is not initialized" );
|
|
DPF_RETURN(DPNERR_UNINITIALIZED);
|
|
}
|
|
|
|
hResultCode = DNPGetProtocolCaps( pdnObject->pdnProtocolData, pdnCaps );
|
|
|
|
DPF_RETURN(hResultCode);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_GetSPCaps"
|
|
|
|
STDMETHODIMP DN_GetSPCaps(PVOID pv,
|
|
const GUID * const pguidSP,
|
|
DPN_SP_CAPS *const pdnSPCaps,
|
|
const DWORD dwFlags)
|
|
{
|
|
DIRECTNETOBJECT *pdnObject;
|
|
HRESULT hResultCode;
|
|
CServiceProvider *pSP;
|
|
|
|
DPFX(DPFPREP, 2,"Parameters: pdnSPCaps [0x%p], dwFlags [0x%lx]", pdnSPCaps, dwFlags );
|
|
|
|
pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
|
|
DNASSERT(pdnObject != NULL);
|
|
|
|
#ifndef DPNBUILD_NOPARAMVAL
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
|
|
{
|
|
if( FAILED( hResultCode = DN_ValidateGetSPCaps( pv, pguidSP, pdnSPCaps, dwFlags ) ) )
|
|
{
|
|
DPFERR( "Error validating GetSPCaps params" );
|
|
DPF_RETURN( hResultCode );
|
|
}
|
|
}
|
|
#endif // !DPNBUILD_NOPARAMVAL
|
|
|
|
// Check to ensure message handler registered
|
|
if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
|
|
{
|
|
DPFERR( "Object is not initialized" );
|
|
DPF_RETURN(DPNERR_UNINITIALIZED);
|
|
}
|
|
|
|
pSP = NULL;
|
|
|
|
#if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
|
|
DNASSERT(pdnObject->pOnlySP != NULL);
|
|
pdnObject->pOnlySP->AddRef();
|
|
pSP = pdnObject->pOnlySP;
|
|
#else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
//
|
|
// Ensure SP is loaded
|
|
//
|
|
hResultCode = DN_SPEnsureLoaded(pdnObject,
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
pguidSP,
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
#ifndef DPNBUILD_LIBINTERFACE
|
|
NULL,
|
|
#endif // ! DPNBUILD_LIBINTERFACE
|
|
&pSP);
|
|
if (hResultCode != DPN_OK)
|
|
{
|
|
DPFERR("Could not find or load SP");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
DNASSERT( pSP != NULL );
|
|
#endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
|
|
//
|
|
// Get actual SP caps
|
|
//
|
|
hResultCode = DNGetActualSPCaps(pSP,pdnSPCaps);
|
|
|
|
pSP->Release();
|
|
pSP = NULL;
|
|
|
|
#if ((! defined(DPNBUILD_ONLYONESP)) || (! defined(DPNBUILD_LIBINTERFACE)))
|
|
Exit:
|
|
#endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
DNASSERT( pSP == NULL );
|
|
|
|
DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
|
|
return(hResultCode);
|
|
|
|
#if ((! defined(DPNBUILD_ONLYONESP)) || (! defined(DPNBUILD_LIBINTERFACE)))
|
|
Failure:
|
|
if (pSP)
|
|
{
|
|
pSP->Release();
|
|
pSP = NULL;
|
|
}
|
|
goto Exit;
|
|
#endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_SetSPCaps"
|
|
|
|
STDMETHODIMP DN_SetSPCaps(PVOID pv,
|
|
const GUID * const pguidSP,
|
|
const DPN_SP_CAPS *const pdnSPCaps,
|
|
const DWORD dwFlags)
|
|
{
|
|
DPFX(DPFPREP, 2,"Parameters: pdnSPCaps [0x%p]", pdnSPCaps );
|
|
|
|
DIRECTNETOBJECT *pdnObject;
|
|
CServiceProvider *pSP;
|
|
HRESULT hResultCode;
|
|
SPSETCAPSDATA spSetCapsData;
|
|
IDP8ServiceProvider *pIDP8SP;
|
|
|
|
pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
|
|
DNASSERT(pdnObject != NULL);
|
|
|
|
#ifndef DPNBUILD_NOPARAMVAL
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
|
|
{
|
|
if( FAILED( hResultCode = DN_ValidateSetSPCaps( pv, pguidSP, pdnSPCaps, dwFlags ) ) )
|
|
{
|
|
DPFERR( "Error validating SetSPCaps params" );
|
|
DPF_RETURN( hResultCode );
|
|
}
|
|
}
|
|
#endif // !DPNBUILD_NOPARAMVAL
|
|
|
|
// Check to ensure message handler registered
|
|
if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
|
|
{
|
|
DPFERR( "Object is not initialized" );
|
|
DPF_RETURN(DPNERR_UNINITIALIZED);
|
|
}
|
|
|
|
pSP = NULL;
|
|
pIDP8SP = NULL;
|
|
|
|
#if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
|
|
DNASSERT(pdnObject->pOnlySP != NULL);
|
|
pdnObject->pOnlySP->AddRef();
|
|
pSP = pdnObject->pOnlySP;
|
|
#else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
//
|
|
// Ensure the SP is loaded. If it's not currently loaded, we will load it now.
|
|
//
|
|
hResultCode = DN_SPEnsureLoaded(pdnObject,
|
|
#ifndef DPNBUILD_ONLYONESP
|
|
pguidSP,
|
|
#endif // ! DPNBUILD_ONLYONESP
|
|
#ifndef DPNBUILD_LIBINTERFACE
|
|
NULL,
|
|
#endif // ! DPNBUILD_LIBINTERFACE
|
|
&pSP);
|
|
if (hResultCode != DPN_OK)
|
|
{
|
|
DPFERR("Could not find or load SP");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
DNASSERT(pSP != NULL);
|
|
#endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
|
|
|
|
//
|
|
// Get the SP interface
|
|
//
|
|
if ((hResultCode = pSP->GetInterfaceRef( &pIDP8SP )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not get SP interface reference");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Set the SP caps
|
|
//
|
|
memset( &spSetCapsData, 0x00, sizeof( SPSETCAPSDATA ) );
|
|
spSetCapsData.dwSize = sizeof( SPSETCAPSDATA );
|
|
spSetCapsData.dwIOThreadCount = pdnSPCaps->dwNumThreads;
|
|
spSetCapsData.dwBuffersPerThread = pdnSPCaps->dwBuffersPerThread;
|
|
spSetCapsData.dwSystemBufferSize = pdnSPCaps->dwSystemBufferSize;
|
|
|
|
if ((hResultCode = IDP8ServiceProvider_SetCaps( pIDP8SP, &spSetCapsData )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not set SP caps");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
IDP8ServiceProvider_Release( pIDP8SP );
|
|
pIDP8SP = NULL;
|
|
|
|
pSP->Release();
|
|
pSP = NULL;
|
|
|
|
hResultCode = DPN_OK;
|
|
|
|
Exit:
|
|
DNASSERT( pIDP8SP == NULL);
|
|
DNASSERT( pSP == NULL);
|
|
|
|
DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
|
|
return(hResultCode);
|
|
|
|
Failure:
|
|
if (pIDP8SP)
|
|
{
|
|
IDP8ServiceProvider_Release( pIDP8SP );
|
|
pIDP8SP = NULL;
|
|
}
|
|
if (pSP)
|
|
{
|
|
pSP->Release();
|
|
pSP = NULL;
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_GetConnectionInfoHelper"
|
|
|
|
STDMETHODIMP DN_GetConnectionInfoHelper(PVOID pv,
|
|
const DPNID dpnid,
|
|
DPN_CONNECTION_INFO *const pdpConnectionInfo,
|
|
BOOL fServerPlayer,
|
|
const DWORD dwFlags)
|
|
{
|
|
DIRECTNETOBJECT *pdnObject;
|
|
HRESULT hResultCode;
|
|
CNameTableEntry *pPlayerEntry;
|
|
CConnection *pConnection;
|
|
HANDLE hEndPoint;
|
|
CCallbackThread CallbackThread;
|
|
|
|
pPlayerEntry = NULL;
|
|
pConnection = NULL;
|
|
CallbackThread.Initialize();
|
|
|
|
pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
|
|
DNASSERT(pdnObject != NULL);
|
|
|
|
#ifndef DPNBUILD_NOPARAMVAL
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
|
|
{
|
|
if( FAILED( hResultCode = DN_ValidateGetConnectionInfoHelper( pv, dpnid, pdpConnectionInfo, fServerPlayer,dwFlags ) ) )
|
|
{
|
|
DPFERR( "Error validating GetConnectionInfoHelper params" );
|
|
DPF_RETURN( hResultCode );
|
|
}
|
|
}
|
|
#endif // !DPNBUILD_NOPARAMVAL
|
|
|
|
// Check to ensure message handler registered
|
|
if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
|
|
{
|
|
DPFERR( "Object is not initialized" );
|
|
DPF_RETURN(DPNERR_UNINITIALIZED);
|
|
}
|
|
|
|
if( pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING )
|
|
{
|
|
DPFERR("Object is connecting / starting to host" );
|
|
DPF_RETURN(DPNERR_CONNECTING);
|
|
}
|
|
|
|
if( !(pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTED) )
|
|
{
|
|
DPFERR("You must be connected / hosting to get connection info" );
|
|
DPF_RETURN(DPNERR_NOCONNECTION);
|
|
}
|
|
|
|
if( fServerPlayer )
|
|
{
|
|
hResultCode = pdnObject->NameTable.GetHostPlayerRef( &pPlayerEntry );
|
|
if ( FAILED( hResultCode ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "No host player present" );
|
|
DPF_RETURN(DPNERR_INVALIDPLAYER);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hResultCode = pdnObject->NameTable.FindEntry( dpnid, &pPlayerEntry );
|
|
|
|
if( FAILED( hResultCode ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not find specified player" );
|
|
DPF_RETURN(DPNERR_INVALIDPLAYER);
|
|
}
|
|
}
|
|
|
|
if( pPlayerEntry == NULL )
|
|
{
|
|
DNASSERT(FALSE);
|
|
DPFX(DPFPREP, 0, "Internal error" );
|
|
DPF_RETURN(DPNERR_GENERIC);
|
|
}
|
|
|
|
if( pPlayerEntry->IsGroup() )
|
|
{
|
|
DPFX(DPFPREP, 0, "Cannot retrieve connection info on groups" );
|
|
hResultCode = DPNERR_INVALIDPLAYER;
|
|
goto Failure;
|
|
}
|
|
|
|
if ((hResultCode = pPlayerEntry->GetConnectionRef( &pConnection )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not get connection reference");
|
|
hResultCode = DPNERR_CONNECTIONLOST;
|
|
goto Failure;
|
|
}
|
|
|
|
hResultCode = pConnection->GetEndPt(&hEndPoint,&CallbackThread);
|
|
if( FAILED( hResultCode ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Unable to get endpoint hr=[0x%08x]", hResultCode );
|
|
hResultCode = DPNERR_CONNECTIONLOST;
|
|
goto Failure;
|
|
}
|
|
|
|
if (hEndPoint != NULL)
|
|
{
|
|
hResultCode = DNPGetEPCaps( pdnObject->pdnProtocolData, hEndPoint, pdpConnectionInfo );
|
|
}
|
|
else
|
|
{
|
|
hResultCode = DPNERR_INVALIDENDPOINT;
|
|
}
|
|
|
|
pConnection->ReleaseEndPt(&CallbackThread);
|
|
|
|
if( FAILED( hResultCode ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error getting connection info hr=[0x%08x]", hResultCode );
|
|
hResultCode = DPNERR_INVALIDPLAYER;
|
|
goto Failure;
|
|
}
|
|
|
|
pConnection->Release();
|
|
pPlayerEntry->Release();
|
|
|
|
hResultCode = DPN_OK;
|
|
|
|
Exit:
|
|
CallbackThread.Deinitialize();
|
|
DPF_RETURN(hResultCode);
|
|
|
|
Failure:
|
|
if (pPlayerEntry)
|
|
{
|
|
pPlayerEntry->Release();
|
|
pPlayerEntry = NULL;
|
|
}
|
|
if (pConnection)
|
|
{
|
|
pConnection->Release();
|
|
pConnection = NULL;
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_GetConnectionInfo"
|
|
|
|
STDMETHODIMP DN_GetConnectionInfo(PVOID pv,
|
|
const DPNID dpnid,
|
|
DPN_CONNECTION_INFO *const pdpConnectionInfo,
|
|
const DWORD dwFlags)
|
|
{
|
|
DPFX(DPFPREP, 3,"Parameters: dpnid [0x%lx] pdpConnectionInfo [0x%p], dwFlags [0x%lx]", dpnid, pdpConnectionInfo,dwFlags );
|
|
|
|
return DN_GetConnectionInfoHelper( pv, dpnid, pdpConnectionInfo, FALSE, dwFlags );
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DN_GetConnectionInfo"
|
|
|
|
STDMETHODIMP DN_GetServerConnectionInfo(PVOID pv,
|
|
DPN_CONNECTION_INFO *const pdpConnectionInfo,
|
|
const DWORD dwFlags)
|
|
{
|
|
DPFX(DPFPREP, 2,"Parameters: pdpConnectionInfo [0x%p], dwFlags [0x%lx]", pdpConnectionInfo, dwFlags);
|
|
|
|
return DN_GetConnectionInfoHelper( pv, 0, pdpConnectionInfo, TRUE, dwFlags );
|
|
}
|
|
|
|
|
|
HRESULT DNCAPS_QueryInterface( IDP8SPCallback *pSP, REFIID riid, LPVOID * ppvObj )
|
|
{
|
|
*ppvObj = pSP;
|
|
return DPN_OK;
|
|
}
|
|
|
|
|
|
ULONG DNCAPS_AddRef( IDP8SPCallback *pSP )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
ULONG DNCAPS_Release( IDP8SPCallback *pSP )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
HRESULT DNCAPS_IndicateEvent( IDP8SPCallback *pSP, SP_EVENT_TYPE spetEvent,LPVOID pvData )
|
|
{
|
|
return DPN_OK;
|
|
}
|
|
|
|
|
|
HRESULT DNCAPS_CommandComplete( IDP8SPCallback *pSP,HANDLE hCommand,HRESULT hrResult,LPVOID pvData )
|
|
{
|
|
return DPN_OK;
|
|
}
|
|
|
|
|
|
LPVOID dncapsspInterface[] =
|
|
{
|
|
(LPVOID)DNCAPS_QueryInterface,
|
|
(LPVOID)DNCAPS_AddRef,
|
|
(LPVOID)DNCAPS_Release,
|
|
(LPVOID)DNCAPS_IndicateEvent,
|
|
(LPVOID)DNCAPS_CommandComplete
|
|
};
|
|
|
|
|
|
// SP should be loaded
|
|
//
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DNGetActualSPCaps"
|
|
|
|
HRESULT DNGetActualSPCaps(CServiceProvider *const pSP,
|
|
DPN_SP_CAPS *const pCaps)
|
|
{
|
|
HRESULT hResultCode;
|
|
SPGETCAPSDATA spGetCapsData;
|
|
IDP8ServiceProvider *pIDP8SP;
|
|
|
|
DPFX(DPFPREP, 4,"Parameters: pSP [0x%p], pCaps [0x%p]",pSP,pCaps);
|
|
|
|
DNASSERT(pSP != NULL);
|
|
|
|
pIDP8SP = NULL;
|
|
|
|
//
|
|
// Get the SP interface
|
|
//
|
|
if ((hResultCode = pSP->GetInterfaceRef( &pIDP8SP )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not get SP interface reference");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Get the SP caps
|
|
//
|
|
memset( &spGetCapsData, 0x00, sizeof( SPGETCAPSDATA ) );
|
|
spGetCapsData.dwSize = sizeof( SPGETCAPSDATA );
|
|
spGetCapsData.hEndpoint = INVALID_HANDLE_VALUE;
|
|
if ((hResultCode = IDP8ServiceProvider_GetCaps( pIDP8SP, &spGetCapsData )) != DPN_OK)
|
|
{
|
|
DPFERR("Could not get SP caps");
|
|
DisplayDNError(0,hResultCode);
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Clean up
|
|
//
|
|
IDP8ServiceProvider_Release( pIDP8SP );
|
|
pIDP8SP = NULL;
|
|
|
|
//
|
|
// Map from SP structure to our own
|
|
//
|
|
pCaps->dwFlags = spGetCapsData.dwFlags;
|
|
pCaps->dwNumThreads = spGetCapsData.dwIOThreadCount;
|
|
pCaps->dwDefaultEnumCount = spGetCapsData.dwDefaultEnumRetryCount;
|
|
pCaps->dwDefaultEnumRetryInterval = spGetCapsData.dwDefaultEnumRetryInterval;
|
|
pCaps->dwDefaultEnumTimeout = spGetCapsData.dwDefaultEnumTimeout;
|
|
pCaps->dwMaxEnumPayloadSize = spGetCapsData.dwEnumFrameSize - sizeof( DN_ENUM_QUERY_PAYLOAD );
|
|
pCaps->dwBuffersPerThread = spGetCapsData.dwBuffersPerThread;
|
|
pCaps->dwSystemBufferSize = spGetCapsData.dwSystemBufferSize;
|
|
|
|
hResultCode = DPN_OK;
|
|
|
|
Exit:
|
|
DNASSERT( pIDP8SP == NULL );
|
|
|
|
DPFX(DPFPREP, 4,"Returning: [0x%lx]",hResultCode);
|
|
return(hResultCode);
|
|
|
|
Failure:
|
|
if (pIDP8SP)
|
|
{
|
|
IDP8ServiceProvider_Release(pIDP8SP);
|
|
pIDP8SP = NULL;
|
|
}
|
|
goto Exit;
|
|
}
|