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.

625 lines
16 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Caps.cpp
  6. * Content: Dplay8 caps routines
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/17/00 rmt Created
  12. * 03/23/00 rmt Removed unused local variables
  13. * 03/25/00 rmt Updated to make calls into SP's function
  14. * rmt Updated SP calls to Initialize SP (and create if required)
  15. * 03/31/00 rmt Hooked up the GetCaps/SetCaps calls to call the protocol
  16. * 04/17/00 rmt Strong param validation
  17. * 04/19/00 mjn Removed AddRef() for NameTableEntry in DN_GetConnectionInfoHelper()
  18. * 05/03/00 mjn Use GetHostPlayerRef() rather than GetHostPlayer()
  19. * 06/05/00 mjn Fixed DN_GetConnectionInfoHelper() to use GetConnectionRef
  20. * 06/09/00 rmt Updates to split CLSID and allow whistler compat
  21. * 07/06/00 mjn Use GetInterfaceRef for SP interface
  22. * mjn Fixed up DN_SetActualSPCaps() and DN_GetActualSPCaps()
  23. * 07/29/00 mjn Fixed SetSPCaps() recursion problem
  24. * 07/31/00 mjn Renamed dwDefaultEnumRetryCount to dwDefaultEnumCount in DPN_SP_CAPS
  25. * 08/03/2000 rmt Bug #41244 - Wrong return codes -- part 2
  26. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  27. * 08/05/00 mjn Added dwFlags to DN_GetConnectionInfoHelper()
  28. * 08/20/00 mjn DNSetActualSPCaps() uses CServiceProvider object instead of GUID
  29. * 01/22/01 mjn Fixed debug text in DN_GetConnectionInfoHelper()
  30. * 02/12/01 mjn Fixed CConnection::GetEndPt() to track calling thread
  31. * 03/30/01 mjn Changes to prevent multiple loading/unloading of SP's
  32. * mjn Removed cached caps functionallity
  33. * 07/24/01 mjn Added DPNBUILD_NOPARAMVAL compile flag
  34. *@@END_MSINTERNAL
  35. *
  36. ***************************************************************************/
  37. #include "dncorei.h"
  38. // DN_SetCaps
  39. //
  40. // Set caps
  41. #undef DPF_MODNAME
  42. #define DPF_MODNAME "DN_SetCaps"
  43. STDMETHODIMP DN_SetCaps(PVOID pv,
  44. const DPN_CAPS *const pdnCaps,
  45. const DWORD dwFlags)
  46. {
  47. DIRECTNETOBJECT *pdnObject;
  48. HRESULT hResultCode;
  49. DPFX(DPFPREP, 3,"Parameters: pdnCaps [0x%p] dwFlags [0x%lx]", pdnCaps, dwFlags );
  50. pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
  51. DNASSERT(pdnObject != NULL);
  52. #ifndef DPNBUILD_NOPARAMVAL
  53. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  54. {
  55. if( FAILED( hResultCode = DN_ValidateSetCaps( pv, pdnCaps, dwFlags ) ) )
  56. {
  57. DPFERR( "Error validating SetCaps params" );
  58. DPF_RETURN( hResultCode );
  59. }
  60. }
  61. #endif // !DPNBUILD_NOPARAMVAL
  62. // Check to ensure message handler registered
  63. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  64. {
  65. DPFERR( "Object is not initialized" );
  66. DPF_RETURN(DPNERR_UNINITIALIZED);
  67. }
  68. hResultCode = DNPSetProtocolCaps( pdnObject->pdnProtocolData, (DPN_CAPS*)pdnCaps );
  69. DPF_RETURN(hResultCode);
  70. }
  71. #undef DPF_MODNAME
  72. #define DPF_MODNAME "DN_GetCaps"
  73. STDMETHODIMP DN_GetCaps(PVOID pv,
  74. DPN_CAPS *const pdnCaps,
  75. const DWORD dwFlags)
  76. {
  77. DPFX(DPFPREP, 2,"Parameters: pdnCaps [0x%p], dwFlags [0x%lx]", pdnCaps,dwFlags);
  78. DIRECTNETOBJECT *pdnObject;
  79. HRESULT hResultCode;
  80. pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
  81. DNASSERT(pdnObject != NULL);
  82. #ifndef DPNBUILD_NOPARAMVAL
  83. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  84. {
  85. if( FAILED( hResultCode = DN_ValidateGetCaps( pv, pdnCaps, dwFlags ) ) )
  86. {
  87. DPFERR( "Error validating GetCaps params" );
  88. DPF_RETURN( hResultCode );
  89. }
  90. }
  91. #endif // DPNBUILD_NOPARAMVAL
  92. // Check to ensure message handler registered
  93. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  94. {
  95. DPFERR( "Object is not initialized" );
  96. DPF_RETURN(DPNERR_UNINITIALIZED);
  97. }
  98. hResultCode = DNPGetProtocolCaps( pdnObject->pdnProtocolData, pdnCaps );
  99. DPF_RETURN(hResultCode);
  100. }
  101. #undef DPF_MODNAME
  102. #define DPF_MODNAME "DN_GetSPCaps"
  103. STDMETHODIMP DN_GetSPCaps(PVOID pv,
  104. const GUID * const pguidSP,
  105. DPN_SP_CAPS *const pdnSPCaps,
  106. const DWORD dwFlags)
  107. {
  108. DIRECTNETOBJECT *pdnObject;
  109. HRESULT hResultCode;
  110. CServiceProvider *pSP;
  111. DPFX(DPFPREP, 2,"Parameters: pdnSPCaps [0x%p], dwFlags [0x%lx]", pdnSPCaps, dwFlags );
  112. pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
  113. DNASSERT(pdnObject != NULL);
  114. #ifndef DPNBUILD_NOPARAMVAL
  115. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  116. {
  117. if( FAILED( hResultCode = DN_ValidateGetSPCaps( pv, pguidSP, pdnSPCaps, dwFlags ) ) )
  118. {
  119. DPFERR( "Error validating GetSPCaps params" );
  120. DPF_RETURN( hResultCode );
  121. }
  122. }
  123. #endif // !DPNBUILD_NOPARAMVAL
  124. // Check to ensure message handler registered
  125. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  126. {
  127. DPFERR( "Object is not initialized" );
  128. DPF_RETURN(DPNERR_UNINITIALIZED);
  129. }
  130. pSP = NULL;
  131. #if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
  132. DNASSERT(pdnObject->pOnlySP != NULL);
  133. pdnObject->pOnlySP->AddRef();
  134. pSP = pdnObject->pOnlySP;
  135. #else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  136. //
  137. // Ensure SP is loaded
  138. //
  139. hResultCode = DN_SPEnsureLoaded(pdnObject,
  140. #ifndef DPNBUILD_ONLYONESP
  141. pguidSP,
  142. #endif // ! DPNBUILD_ONLYONESP
  143. #ifndef DPNBUILD_LIBINTERFACE
  144. NULL,
  145. #endif // ! DPNBUILD_LIBINTERFACE
  146. &pSP);
  147. if (hResultCode != DPN_OK)
  148. {
  149. DPFERR("Could not find or load SP");
  150. DisplayDNError(0,hResultCode);
  151. goto Failure;
  152. }
  153. DNASSERT( pSP != NULL );
  154. #endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  155. //
  156. // Get actual SP caps
  157. //
  158. hResultCode = DNGetActualSPCaps(pSP,pdnSPCaps);
  159. pSP->Release();
  160. pSP = NULL;
  161. #if ((! defined(DPNBUILD_ONLYONESP)) || (! defined(DPNBUILD_LIBINTERFACE)))
  162. Exit:
  163. #endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  164. DNASSERT( pSP == NULL );
  165. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  166. return(hResultCode);
  167. #if ((! defined(DPNBUILD_ONLYONESP)) || (! defined(DPNBUILD_LIBINTERFACE)))
  168. Failure:
  169. if (pSP)
  170. {
  171. pSP->Release();
  172. pSP = NULL;
  173. }
  174. goto Exit;
  175. #endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  176. }
  177. #undef DPF_MODNAME
  178. #define DPF_MODNAME "DN_SetSPCaps"
  179. STDMETHODIMP DN_SetSPCaps(PVOID pv,
  180. const GUID * const pguidSP,
  181. const DPN_SP_CAPS *const pdnSPCaps,
  182. const DWORD dwFlags)
  183. {
  184. DPFX(DPFPREP, 2,"Parameters: pdnSPCaps [0x%p]", pdnSPCaps );
  185. DIRECTNETOBJECT *pdnObject;
  186. CServiceProvider *pSP;
  187. HRESULT hResultCode;
  188. SPSETCAPSDATA spSetCapsData;
  189. IDP8ServiceProvider *pIDP8SP;
  190. pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
  191. DNASSERT(pdnObject != NULL);
  192. #ifndef DPNBUILD_NOPARAMVAL
  193. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  194. {
  195. if( FAILED( hResultCode = DN_ValidateSetSPCaps( pv, pguidSP, pdnSPCaps, dwFlags ) ) )
  196. {
  197. DPFERR( "Error validating SetSPCaps params" );
  198. DPF_RETURN( hResultCode );
  199. }
  200. }
  201. #endif // !DPNBUILD_NOPARAMVAL
  202. // Check to ensure message handler registered
  203. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  204. {
  205. DPFERR( "Object is not initialized" );
  206. DPF_RETURN(DPNERR_UNINITIALIZED);
  207. }
  208. pSP = NULL;
  209. pIDP8SP = NULL;
  210. #if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
  211. DNASSERT(pdnObject->pOnlySP != NULL);
  212. pdnObject->pOnlySP->AddRef();
  213. pSP = pdnObject->pOnlySP;
  214. #else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  215. //
  216. // Ensure the SP is loaded. If it's not currently loaded, we will load it now.
  217. //
  218. hResultCode = DN_SPEnsureLoaded(pdnObject,
  219. #ifndef DPNBUILD_ONLYONESP
  220. pguidSP,
  221. #endif // ! DPNBUILD_ONLYONESP
  222. #ifndef DPNBUILD_LIBINTERFACE
  223. NULL,
  224. #endif // ! DPNBUILD_LIBINTERFACE
  225. &pSP);
  226. if (hResultCode != DPN_OK)
  227. {
  228. DPFERR("Could not find or load SP");
  229. DisplayDNError(0,hResultCode);
  230. goto Failure;
  231. }
  232. DNASSERT(pSP != NULL);
  233. #endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  234. //
  235. // Get the SP interface
  236. //
  237. if ((hResultCode = pSP->GetInterfaceRef( &pIDP8SP )) != DPN_OK)
  238. {
  239. DPFERR("Could not get SP interface reference");
  240. DisplayDNError(0,hResultCode);
  241. goto Failure;
  242. }
  243. //
  244. // Set the SP caps
  245. //
  246. memset( &spSetCapsData, 0x00, sizeof( SPSETCAPSDATA ) );
  247. spSetCapsData.dwSize = sizeof( SPSETCAPSDATA );
  248. spSetCapsData.dwIOThreadCount = pdnSPCaps->dwNumThreads;
  249. spSetCapsData.dwBuffersPerThread = pdnSPCaps->dwBuffersPerThread;
  250. spSetCapsData.dwSystemBufferSize = pdnSPCaps->dwSystemBufferSize;
  251. if ((hResultCode = IDP8ServiceProvider_SetCaps( pIDP8SP, &spSetCapsData )) != DPN_OK)
  252. {
  253. DPFERR("Could not set SP caps");
  254. DisplayDNError(0,hResultCode);
  255. goto Failure;
  256. }
  257. //
  258. // Clean up
  259. //
  260. IDP8ServiceProvider_Release( pIDP8SP );
  261. pIDP8SP = NULL;
  262. pSP->Release();
  263. pSP = NULL;
  264. hResultCode = DPN_OK;
  265. Exit:
  266. DNASSERT( pIDP8SP == NULL);
  267. DNASSERT( pSP == NULL);
  268. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  269. return(hResultCode);
  270. Failure:
  271. if (pIDP8SP)
  272. {
  273. IDP8ServiceProvider_Release( pIDP8SP );
  274. pIDP8SP = NULL;
  275. }
  276. if (pSP)
  277. {
  278. pSP->Release();
  279. pSP = NULL;
  280. }
  281. goto Exit;
  282. }
  283. #undef DPF_MODNAME
  284. #define DPF_MODNAME "DN_GetConnectionInfoHelper"
  285. STDMETHODIMP DN_GetConnectionInfoHelper(PVOID pv,
  286. const DPNID dpnid,
  287. DPN_CONNECTION_INFO *const pdpConnectionInfo,
  288. BOOL fServerPlayer,
  289. const DWORD dwFlags)
  290. {
  291. DIRECTNETOBJECT *pdnObject;
  292. HRESULT hResultCode;
  293. CNameTableEntry *pPlayerEntry;
  294. CConnection *pConnection;
  295. HANDLE hEndPoint;
  296. CCallbackThread CallbackThread;
  297. pPlayerEntry = NULL;
  298. pConnection = NULL;
  299. CallbackThread.Initialize();
  300. pdnObject = static_cast<DIRECTNETOBJECT*>(GET_OBJECT_FROM_INTERFACE(pv));
  301. DNASSERT(pdnObject != NULL);
  302. #ifndef DPNBUILD_NOPARAMVAL
  303. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  304. {
  305. if( FAILED( hResultCode = DN_ValidateGetConnectionInfoHelper( pv, dpnid, pdpConnectionInfo, fServerPlayer,dwFlags ) ) )
  306. {
  307. DPFERR( "Error validating GetConnectionInfoHelper params" );
  308. DPF_RETURN( hResultCode );
  309. }
  310. }
  311. #endif // !DPNBUILD_NOPARAMVAL
  312. // Check to ensure message handler registered
  313. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  314. {
  315. DPFERR( "Object is not initialized" );
  316. DPF_RETURN(DPNERR_UNINITIALIZED);
  317. }
  318. if( pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING )
  319. {
  320. DPFERR("Object is connecting / starting to host" );
  321. DPF_RETURN(DPNERR_CONNECTING);
  322. }
  323. if( !(pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTED) )
  324. {
  325. DPFERR("You must be connected / hosting to get connection info" );
  326. DPF_RETURN(DPNERR_NOCONNECTION);
  327. }
  328. if( fServerPlayer )
  329. {
  330. hResultCode = pdnObject->NameTable.GetHostPlayerRef( &pPlayerEntry );
  331. if ( FAILED( hResultCode ) )
  332. {
  333. DPFX(DPFPREP, 0, "No host player present" );
  334. DPF_RETURN(DPNERR_INVALIDPLAYER);
  335. }
  336. }
  337. else
  338. {
  339. hResultCode = pdnObject->NameTable.FindEntry( dpnid, &pPlayerEntry );
  340. if( FAILED( hResultCode ) )
  341. {
  342. DPFX(DPFPREP, 0, "Could not find specified player" );
  343. DPF_RETURN(DPNERR_INVALIDPLAYER);
  344. }
  345. }
  346. if( pPlayerEntry == NULL )
  347. {
  348. DNASSERT(FALSE);
  349. DPFX(DPFPREP, 0, "Internal error" );
  350. DPF_RETURN(DPNERR_GENERIC);
  351. }
  352. if( pPlayerEntry->IsGroup() )
  353. {
  354. DPFX(DPFPREP, 0, "Cannot retrieve connection info on groups" );
  355. hResultCode = DPNERR_INVALIDPLAYER;
  356. goto Failure;
  357. }
  358. if ((hResultCode = pPlayerEntry->GetConnectionRef( &pConnection )) != DPN_OK)
  359. {
  360. DPFERR("Could not get connection reference");
  361. hResultCode = DPNERR_CONNECTIONLOST;
  362. goto Failure;
  363. }
  364. hResultCode = pConnection->GetEndPt(&hEndPoint,&CallbackThread);
  365. if( FAILED( hResultCode ) )
  366. {
  367. DPFX(DPFPREP, 0, "Unable to get endpoint hr=[0x%08x]", hResultCode );
  368. hResultCode = DPNERR_CONNECTIONLOST;
  369. goto Failure;
  370. }
  371. if (hEndPoint != NULL)
  372. {
  373. hResultCode = DNPGetEPCaps( pdnObject->pdnProtocolData, hEndPoint, pdpConnectionInfo );
  374. }
  375. else
  376. {
  377. hResultCode = DPNERR_INVALIDENDPOINT;
  378. }
  379. pConnection->ReleaseEndPt(&CallbackThread);
  380. if( FAILED( hResultCode ) )
  381. {
  382. DPFX(DPFPREP, 0, "Error getting connection info hr=[0x%08x]", hResultCode );
  383. hResultCode = DPNERR_INVALIDPLAYER;
  384. goto Failure;
  385. }
  386. pConnection->Release();
  387. pPlayerEntry->Release();
  388. hResultCode = DPN_OK;
  389. Exit:
  390. CallbackThread.Deinitialize();
  391. DPF_RETURN(hResultCode);
  392. Failure:
  393. if (pPlayerEntry)
  394. {
  395. pPlayerEntry->Release();
  396. pPlayerEntry = NULL;
  397. }
  398. if (pConnection)
  399. {
  400. pConnection->Release();
  401. pConnection = NULL;
  402. }
  403. goto Exit;
  404. }
  405. #undef DPF_MODNAME
  406. #define DPF_MODNAME "DN_GetConnectionInfo"
  407. STDMETHODIMP DN_GetConnectionInfo(PVOID pv,
  408. const DPNID dpnid,
  409. DPN_CONNECTION_INFO *const pdpConnectionInfo,
  410. const DWORD dwFlags)
  411. {
  412. DPFX(DPFPREP, 3,"Parameters: dpnid [0x%lx] pdpConnectionInfo [0x%p], dwFlags [0x%lx]", dpnid, pdpConnectionInfo,dwFlags );
  413. return DN_GetConnectionInfoHelper( pv, dpnid, pdpConnectionInfo, FALSE, dwFlags );
  414. }
  415. #undef DPF_MODNAME
  416. #define DPF_MODNAME "DN_GetConnectionInfo"
  417. STDMETHODIMP DN_GetServerConnectionInfo(PVOID pv,
  418. DPN_CONNECTION_INFO *const pdpConnectionInfo,
  419. const DWORD dwFlags)
  420. {
  421. DPFX(DPFPREP, 2,"Parameters: pdpConnectionInfo [0x%p], dwFlags [0x%lx]", pdpConnectionInfo, dwFlags);
  422. return DN_GetConnectionInfoHelper( pv, 0, pdpConnectionInfo, TRUE, dwFlags );
  423. }
  424. HRESULT DNCAPS_QueryInterface( IDP8SPCallback *pSP, REFIID riid, LPVOID * ppvObj )
  425. {
  426. *ppvObj = pSP;
  427. return DPN_OK;
  428. }
  429. ULONG DNCAPS_AddRef( IDP8SPCallback *pSP )
  430. {
  431. return 1;
  432. }
  433. ULONG DNCAPS_Release( IDP8SPCallback *pSP )
  434. {
  435. return 1;
  436. }
  437. HRESULT DNCAPS_IndicateEvent( IDP8SPCallback *pSP, SP_EVENT_TYPE spetEvent,LPVOID pvData )
  438. {
  439. return DPN_OK;
  440. }
  441. HRESULT DNCAPS_CommandComplete( IDP8SPCallback *pSP,HANDLE hCommand,HRESULT hrResult,LPVOID pvData )
  442. {
  443. return DPN_OK;
  444. }
  445. LPVOID dncapsspInterface[] =
  446. {
  447. (LPVOID)DNCAPS_QueryInterface,
  448. (LPVOID)DNCAPS_AddRef,
  449. (LPVOID)DNCAPS_Release,
  450. (LPVOID)DNCAPS_IndicateEvent,
  451. (LPVOID)DNCAPS_CommandComplete
  452. };
  453. // SP should be loaded
  454. //
  455. #undef DPF_MODNAME
  456. #define DPF_MODNAME "DNGetActualSPCaps"
  457. HRESULT DNGetActualSPCaps(CServiceProvider *const pSP,
  458. DPN_SP_CAPS *const pCaps)
  459. {
  460. HRESULT hResultCode;
  461. SPGETCAPSDATA spGetCapsData;
  462. IDP8ServiceProvider *pIDP8SP;
  463. DPFX(DPFPREP, 4,"Parameters: pSP [0x%p], pCaps [0x%p]",pSP,pCaps);
  464. DNASSERT(pSP != NULL);
  465. pIDP8SP = NULL;
  466. //
  467. // Get the SP interface
  468. //
  469. if ((hResultCode = pSP->GetInterfaceRef( &pIDP8SP )) != DPN_OK)
  470. {
  471. DPFERR("Could not get SP interface reference");
  472. DisplayDNError(0,hResultCode);
  473. goto Failure;
  474. }
  475. //
  476. // Get the SP caps
  477. //
  478. memset( &spGetCapsData, 0x00, sizeof( SPGETCAPSDATA ) );
  479. spGetCapsData.dwSize = sizeof( SPGETCAPSDATA );
  480. spGetCapsData.hEndpoint = INVALID_HANDLE_VALUE;
  481. if ((hResultCode = IDP8ServiceProvider_GetCaps( pIDP8SP, &spGetCapsData )) != DPN_OK)
  482. {
  483. DPFERR("Could not get SP caps");
  484. DisplayDNError(0,hResultCode);
  485. goto Failure;
  486. }
  487. //
  488. // Clean up
  489. //
  490. IDP8ServiceProvider_Release( pIDP8SP );
  491. pIDP8SP = NULL;
  492. //
  493. // Map from SP structure to our own
  494. //
  495. pCaps->dwFlags = spGetCapsData.dwFlags;
  496. pCaps->dwNumThreads = spGetCapsData.dwIOThreadCount;
  497. pCaps->dwDefaultEnumCount = spGetCapsData.dwDefaultEnumRetryCount;
  498. pCaps->dwDefaultEnumRetryInterval = spGetCapsData.dwDefaultEnumRetryInterval;
  499. pCaps->dwDefaultEnumTimeout = spGetCapsData.dwDefaultEnumTimeout;
  500. pCaps->dwMaxEnumPayloadSize = spGetCapsData.dwEnumFrameSize - sizeof( DN_ENUM_QUERY_PAYLOAD );
  501. pCaps->dwBuffersPerThread = spGetCapsData.dwBuffersPerThread;
  502. pCaps->dwSystemBufferSize = spGetCapsData.dwSystemBufferSize;
  503. hResultCode = DPN_OK;
  504. Exit:
  505. DNASSERT( pIDP8SP == NULL );
  506. DPFX(DPFPREP, 4,"Returning: [0x%lx]",hResultCode);
  507. return(hResultCode);
  508. Failure:
  509. if (pIDP8SP)
  510. {
  511. IDP8ServiceProvider_Release(pIDP8SP);
  512. pIDP8SP = NULL;
  513. }
  514. goto Exit;
  515. }