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

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ServProv.cpp
  6. * Content: Service Provider Objects
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/17/00 mjn Created
  12. * 04/04/00 rmt Added set of SP caps from cache (if cache exists).
  13. * 04/10/00 mjn Farm out RemoveSP to worker thread
  14. * 05/02/00 mjn Fixed RefCount issue
  15. * 06/09/00 rmt Updates to split CLSID and allow whistler compat
  16. * 07/06/00 mjn Fixes to support SP handle to Protocol
  17. * 08/03/00 rmt Bug #41244 - Wrong return codes -- part 2
  18. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  19. * 08/06/00 mjn Added CWorkerJob
  20. * 08/20/00 mjn Changed Initialize() to not add SP to DirectNet object bilink
  21. * 10/08/01 vanceo Add multicast filter
  22. *@@END_MSINTERNAL
  23. *
  24. ***************************************************************************/
  25. #include "dncorei.h"
  26. //**********************************************************************
  27. // Constant definitions
  28. //**********************************************************************
  29. //**********************************************************************
  30. // Macro definitions
  31. //**********************************************************************
  32. //**********************************************************************
  33. // Structure definitions
  34. //**********************************************************************
  35. //**********************************************************************
  36. // Variable definitions
  37. //**********************************************************************
  38. //**********************************************************************
  39. // Function prototypes
  40. //**********************************************************************
  41. //**********************************************************************
  42. // Function definitions
  43. //**********************************************************************
  44. #undef DPF_MODNAME
  45. #define DPF_MODNAME "CServiceProvider::Initialize"
  46. HRESULT CServiceProvider::Initialize(DIRECTNETOBJECT *const pdnObject
  47. #if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_PREALLOCATEDMEMORYMODEL)))
  48. ,const XDP8CREATE_PARAMS * const pDP8CreateParams
  49. #else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  50. #ifndef DPNBUILD_ONLYONESP
  51. ,const GUID *const pguid
  52. #endif // ! DPNBUILD_ONLYONESP
  53. #ifndef DPNBUILD_LIBINTERFACE
  54. ,const GUID *const pguidApplication
  55. #endif // ! DPNBUILD_LIBINTERFACE
  56. #endif // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  57. )
  58. {
  59. HRESULT hResultCode;
  60. IDP8ServiceProvider *pISP;
  61. BOOL fAddedToProtocol;
  62. #ifndef DPNBUILD_LIBINTERFACE
  63. SPISAPPLICATIONSUPPORTEDDATA spAppSupData;
  64. #endif // ! DPNBUILD_LIBINTERFACE
  65. DNASSERT(pdnObject != NULL);
  66. #ifndef DPNBUILD_ONLYONESP
  67. DNASSERT(pguid != NULL);
  68. #endif // ! DPNBUILD_ONLYONESP
  69. m_pdnObject = NULL;
  70. #if ((defined(DPNBUILD_ONLYONESP)) && (defined(DPNBUILD_LIBINTERFACE)))
  71. m_lRefCount = 0;
  72. #else // ! DPNBUILD_ONLYONESP or ! DPNBUILD_LIBINTERFACE
  73. m_lRefCount = 1;
  74. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  75. m_pISP = NULL;
  76. m_hProtocolSPHandle = NULL;
  77. #ifndef DPNBUILD_ONLYONESP
  78. m_bilinkServiceProviders.Initialize();
  79. #endif // ! DPNBUILD_ONLYONESP
  80. pISP = NULL;
  81. fAddedToProtocol = FALSE;
  82. m_pdnObject = pdnObject;
  83. //
  84. // Instantiate SP
  85. //
  86. #ifndef DPNBUILD_ONLYONESP
  87. if (IsEqualCLSID(*pguid, CLSID_DP8SP_TCPIP))
  88. #endif // ! DPNBUILD_ONLYONESP
  89. {
  90. hResultCode = CreateIPInterface(
  91. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  92. pDP8CreateParams,
  93. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  94. &pISP
  95. );
  96. }
  97. #ifndef DPNBUILD_ONLYONESP
  98. #ifndef DPNBUILD_NOIPX
  99. else if (IsEqualCLSID(*pguid, CLSID_DP8SP_IPX))
  100. {
  101. hResultCode = CreateIPXInterface(
  102. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  103. pDP8CreateParams,
  104. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  105. &pISP
  106. );
  107. }
  108. #endif // ! DPNBUILD_NOIPX
  109. #ifndef DPNBUILD_NOSERIALSP
  110. else if (IsEqualCLSID(*pguid, CLSID_DP8SP_MODEM))
  111. {
  112. hResultCode = CreateModemInterface(
  113. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  114. pDP8CreateParams,
  115. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  116. &pISP
  117. );
  118. }
  119. else if (IsEqualCLSID(*pguid, CLSID_DP8SP_SERIAL))
  120. {
  121. hResultCode = CreateSerialInterface(
  122. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  123. pDP8CreateParams,
  124. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  125. &pISP
  126. );
  127. }
  128. #endif // ! DPNBUILD_NOSERIALSP
  129. else
  130. {
  131. hResultCode = COM_CoCreateInstance(*pguid,
  132. NULL,
  133. CLSCTX_INPROC_SERVER,
  134. IID_IDP8ServiceProvider,
  135. reinterpret_cast<void**>(&pISP),
  136. FALSE);
  137. }
  138. #endif // ! DPNBUILD_ONLYONESP
  139. if (hResultCode != S_OK)
  140. {
  141. DPFX(DPFPREP,0,"Could not instantiate SP (err = 0x%lx)!",hResultCode);
  142. hResultCode = DPNERR_DOESNOTEXIST;
  143. DisplayDNError(0,hResultCode);
  144. goto Exit;
  145. }
  146. //
  147. // Add SP to Protocol Layer
  148. //
  149. #if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
  150. DNProtocolAddRef(pdnObject);
  151. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  152. //Flags parameter for DNPAddServiceProvider is passed through as the
  153. //flags parameter in the SPINITIALIZEDATA structure to the SP
  154. //We pass the session type via it
  155. DWORD dwFlags;
  156. if (pdnObject->dwFlags & DN_OBJECT_FLAG_PEER)
  157. dwFlags=SP_SESSION_TYPE_PEER;
  158. else if (pdnObject->dwFlags & DN_OBJECT_FLAG_CLIENT)
  159. dwFlags=SP_SESSION_TYPE_CLIENT;
  160. else
  161. {
  162. DNASSERT(pdnObject->dwFlags & DN_OBJECT_FLAG_SERVER);
  163. dwFlags=SP_SESSION_TYPE_SERVER;
  164. }
  165. hResultCode = DNPAddServiceProvider(m_pdnObject->pdnProtocolData, pISP,
  166. &m_hProtocolSPHandle, dwFlags);
  167. if (hResultCode!= DPN_OK)
  168. {
  169. DPFX(DPFPREP,1,"Could not add service provider to protocol");
  170. DisplayDNError(1,hResultCode);
  171. #if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
  172. DNProtocolRelease(pdnObject);
  173. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  174. goto Failure;
  175. }
  176. fAddedToProtocol = TRUE;
  177. #ifndef DPNBUILD_NOMULTICAST
  178. //
  179. // If this is a multicast object, make sure the SP in question supports multicasting.
  180. //
  181. if (pdnObject->dwFlags & DN_OBJECT_FLAG_MULTICAST)
  182. {
  183. SPGETCAPSDATA spGetCapsData;
  184. //
  185. // Get the SP caps
  186. //
  187. memset( &spGetCapsData, 0x00, sizeof( SPGETCAPSDATA ) );
  188. spGetCapsData.dwSize = sizeof( SPGETCAPSDATA );
  189. spGetCapsData.hEndpoint = INVALID_HANDLE_VALUE;
  190. if ((hResultCode = IDP8ServiceProvider_GetCaps( pISP, &spGetCapsData )) != DPN_OK)
  191. {
  192. DPFERR("Could not get SP caps");
  193. DisplayDNError(0,hResultCode);
  194. goto Failure;
  195. }
  196. //
  197. // Check for the multicast support flag.
  198. //
  199. if (! (spGetCapsData.dwFlags & DPNSPCAPS_SUPPORTSMULTICAST))
  200. {
  201. DPFX(DPFPREP,1,"Service provider does not support multicasting.");
  202. hResultCode = DPNERR_UNSUPPORTED;
  203. goto Failure;
  204. }
  205. }
  206. #endif // ! DPNBUILD_NOMULTICAST
  207. #ifndef DPNBUILD_LIBINTERFACE
  208. //
  209. // If an application GUID was given, make sure the SP can be used by that app.
  210. //
  211. if (pguidApplication != NULL) // app GUID given
  212. {
  213. spAppSupData.pApplicationGuid = pguidApplication;
  214. spAppSupData.dwFlags = 0;
  215. if ((hResultCode = IDP8ServiceProvider_IsApplicationSupported(pISP,&spAppSupData)) != DPN_OK) // SP doesn't support app
  216. {
  217. DPFX(DPFPREP,1,"Service provider does not support app (err = 0x%lx).", hResultCode);
  218. hResultCode = DPNERR_UNSUPPORTED;
  219. goto Failure;
  220. }
  221. }
  222. #endif // ! DPNBUILD_LIBINTERFACE
  223. IDP8ServiceProvider_AddRef(pISP);
  224. m_pISP = pISP;
  225. IDP8ServiceProvider_Release(pISP);
  226. pISP = NULL;
  227. #ifndef DPNBUILD_ONLYONESP
  228. m_guid = *pguid;
  229. /* REMOVE
  230. // Add to bilink
  231. AddRef();
  232. m_bilink.InsertBefore(&m_pdnObject->m_bilinkServiceProviders);
  233. */
  234. #endif // ! DPNBUILD_ONLYONESP
  235. hResultCode = DPN_OK;
  236. Exit:
  237. return(hResultCode);
  238. Failure:
  239. if (fAddedToProtocol)
  240. {
  241. //
  242. // Ignore failure.
  243. //
  244. DNPRemoveServiceProvider(pdnObject->pdnProtocolData,m_hProtocolSPHandle);
  245. #if ((! defined(DPNBUILD_LIBINTERFACE)) || (! defined(DPNBUILD_ONLYONESP)))
  246. DNProtocolRelease(pdnObject);
  247. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  248. }
  249. if (pISP)
  250. {
  251. IDP8ServiceProvider_Release(pISP);
  252. pISP = NULL;
  253. }
  254. goto Exit;
  255. };
  256. #if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
  257. #undef DPF_MODNAME
  258. #define DPF_MODNAME "CServiceProvider::Deinitialize"
  259. void CServiceProvider::Deinitialize( void )
  260. #else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  261. #undef DPF_MODNAME
  262. #define DPF_MODNAME "CServiceProvider::Release"
  263. void CServiceProvider::Release( void )
  264. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  265. {
  266. HRESULT hResultCode;
  267. #if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
  268. DNASSERT(m_lRefCount == 0);
  269. #else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  270. LONG lRefCount;
  271. lRefCount = DNInterlockedDecrement(&m_lRefCount);
  272. DPFX(DPFPREP, 9,"[0x%p] new RefCount [%ld]",this,lRefCount);
  273. DNASSERT(lRefCount >= 0);
  274. if (lRefCount == 0)
  275. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  276. {
  277. #if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
  278. hResultCode = DNPRemoveServiceProvider(m_pdnObject->pdnProtocolData,m_hProtocolSPHandle);
  279. if (hResultCode != DPN_OK)
  280. #else // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  281. CWorkerJob *pWorkerJob;
  282. pWorkerJob = NULL;
  283. if ((hResultCode = WorkerJobNew(m_pdnObject,&pWorkerJob)) == DPN_OK)
  284. {
  285. pWorkerJob->SetJobType( WORKER_JOB_REMOVE_SERVICE_PROVIDER );
  286. DNASSERT( m_hProtocolSPHandle != NULL );
  287. pWorkerJob->SetRemoveServiceProviderHandle( m_hProtocolSPHandle );
  288. DNQueueWorkerJob(m_pdnObject,pWorkerJob);
  289. pWorkerJob = NULL;
  290. }
  291. else
  292. #endif // ! DPNBUILD_LIBINTERFACE or ! DPNBUILD_ONLYONESP
  293. {
  294. DPFERR("Could not remove SP");
  295. DisplayDNError(0,hResultCode);
  296. DNASSERT(FALSE);
  297. }
  298. if (m_pISP)
  299. {
  300. IDP8ServiceProvider_Release(m_pISP);
  301. m_pISP = NULL;
  302. }
  303. m_pdnObject = NULL;
  304. DNFree(this);
  305. }
  306. }
  307. #undef DPF_MODNAME
  308. #define DPF_MODNAME "CServiceProvider::GetInterfaceRef"
  309. HRESULT CServiceProvider::GetInterfaceRef( IDP8ServiceProvider **ppIDP8SP )
  310. {
  311. DNASSERT( ppIDP8SP != NULL );
  312. if (m_pISP == NULL)
  313. {
  314. return( DPNERR_GENERIC );
  315. }
  316. IDP8ServiceProvider_AddRef( m_pISP );
  317. *ppIDP8SP = m_pISP;
  318. return( DPN_OK );
  319. }