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.

1698 lines
46 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ClassFac.cpp
  6. * Content: DNET COM class factory
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/21/99 mjn Created
  12. * 12/23/99 mjn Fixed Host and AllPlayers short-cut pointer use
  13. * 12/28/99 mjn Moved Async Op stuff to Async.h
  14. * 01/06/00 mjn Moved NameTable stuff to NameTable.h
  15. * 01/08/00 mjn Fixed DN_APPLICATION_DESC in DIRECTNETOBJECT
  16. * 01/13/00 mjn Added CFixedPools and CRefCountBuffers
  17. * 01/14/00 mjn Removed pvUserContext from DN_NAMETABLE_ENTRY
  18. * 01/15/00 mjn Replaced DN_COUNT_BUFFER with CRefCountBuffer
  19. * 01/16/00 mjn Removed User message fixed pool
  20. * 01/18/00 mjn Fixed bug in ref count.
  21. * 01/19/00 mjn Replaced DN_SYNC_EVENT with CSyncEvent
  22. * 01/19/00 mjn Initialize structures for NameTable Operation List
  23. * 01/25/00 mjn Added NameTable pending operation list
  24. * 01/31/00 mjn Added Internal FPM's for RefCountBuffers
  25. * 03/17/00 rmt Added calls to init/free SP Caps cache
  26. * 03/23/00 mjn Implemented RegisterLobby()
  27. * 04/04/00 rmt Enabled "Enable Parameter Validation" flag on object by default
  28. * 04/09/00 mjn Added support for CAsyncOp
  29. * 04/11/00 mjn Added DIRECTNETOBJECT bilink for CAsyncOps
  30. * 04/26/00 mjn Removed DN_ASYNC_OP and related functions
  31. * 04/28/00 mjn Code cleanup - removed hsAsyncHandles,blAsyncOperations
  32. * 05/04/00 mjn Cleaned up and made multi-thread safe
  33. * 05/23/00 RichGr IA64: Substituted %p format specifier whereever
  34. * %x was being used to format pointers. %p is 32-bit
  35. * in a 32-bit build, and 64-bit in a 64-bit build.
  36. * 06/09/00 rmt Updates to split CLSID and allow whistler compat
  37. * 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
  38. * 06/20/00 mjn Fixed QueryInterface bug
  39. * 06/27/00 rmt Fixed bug which was causing interfaces to always be created as peer interfaces
  40. * 07/05/00 rmt Bug #38478 - Could QI for peer interfaces from client object
  41. * (All interfaces could be queried from all types of objects).
  42. * mjn Initialize pConnect element of DIRECNETOBJECT to NULL
  43. * 07/07/00 mjn Added pNewHost for DirectNetObject
  44. * 07/08/00 mjn Call DN_Close when object is about to be free'd
  45. * 07/09/00 rmt Added code to free interface set by RegisterLobby (if there is one)
  46. * 07/17/00 mjn Add signature to DirectNetObject
  47. * 07/21/00 RichGr IA64: Use %p format specifier for 32/64-bit pointers.
  48. * 07/26/00 mjn DN_QueryInterface returns E_POINTER if NULL destination pointer specified
  49. * 07/28/00 mjn Added m_bilinkConnections to DirectNetObject
  50. * 07/30/00 mjn Added CPendingDeletion
  51. * 07/31/00 mjn Added CQueuedMsg
  52. * 08/05/00 mjn Added m_bilinkActiveList and csActiveList
  53. * 08/06/00 mjn Added CWorkerJob
  54. * 08/23/00 mjn Added CNameTableOp
  55. * 09/04/00 mjn Added CApplicationDesc
  56. * 01/11/2001 rmt MANBUG #48487 - DPLAY: Crashes if CoCreate() isn't called
  57. * 02/05/01 mjn Removed unused debug members from DIRECTNETOBJECT
  58. * mjn Added CCallbackThread
  59. * 03/14/2001 rmt WINBUG #342420 - Restore COM emulation layer to operation
  60. * 03/30/01 mjn Changes to prevent multiple loading/unloading of SP's
  61. * mjn Added pConnectSP,dwMaxFrameSize
  62. * mjn Removed blSPCapsList
  63. * 04/04/01 mjn Added voice and lobby sigs
  64. * 04/13/01 mjn Added m_bilinkRequestList
  65. * 05/17/01 mjn Added dwRunningOpCount,hRunningOpEvent,dwWaitingThreadID to track threads performing NameTable operations
  66. * 07/24/01 mjn Added DPNBUILD_NOSERVER compile flag
  67. * 10/05/01 vanceo Added multicast object
  68. *@@END_MSINTERNAL
  69. *
  70. ***************************************************************************/
  71. #include "dncorei.h"
  72. //**********************************************************************
  73. // Constant definitions
  74. //**********************************************************************
  75. //**********************************************************************
  76. // Macro definitions
  77. //**********************************************************************
  78. //**********************************************************************
  79. // Structure definitions
  80. //**********************************************************************
  81. #ifndef DPNBUILD_LIBINTERFACE
  82. typedef STDMETHODIMP IUnknownQueryInterface( IUnknown *pInterface, REFIID riid, LPVOID *ppvObj );
  83. typedef STDMETHODIMP_(ULONG) IUnknownAddRef( IUnknown *pInterface );
  84. typedef STDMETHODIMP_(ULONG) IUnknownRelease( IUnknown *pInterface );
  85. //
  86. // VTable for IUnknown interface
  87. //
  88. IUnknownVtbl DN_UnknownVtbl =
  89. {
  90. (IUnknownQueryInterface*) DN_QueryInterface,
  91. (IUnknownAddRef*) DN_AddRef,
  92. (IUnknownRelease*) DN_Release
  93. };
  94. //
  95. // VTable for Class Factory
  96. //
  97. IClassFactoryVtbl DNCF_Vtbl =
  98. {
  99. DPCF_QueryInterface, // dplay8\common\classfactory.cpp will implement these
  100. DPCF_AddRef,
  101. DPCF_Release,
  102. DNCORECF_CreateInstance,
  103. DPCF_LockServer
  104. };
  105. #endif // ! DPNBUILD_LIBINTERFACE
  106. //**********************************************************************
  107. // Variable definitions
  108. //**********************************************************************
  109. #ifndef DPNBUILD_NOVOICE
  110. extern IDirectPlayVoiceTransportVtbl DN_VoiceTbl;
  111. #endif // DPNBUILD_NOVOICE
  112. //**********************************************************************
  113. // Function prototypes
  114. //**********************************************************************
  115. //**********************************************************************
  116. // Function definitions
  117. //**********************************************************************
  118. #undef DPF_MODNAME
  119. #define DPF_MODNAME "DNCF_CreateObject"
  120. HRESULT DNCF_CreateObject(
  121. #ifndef DPNBUILD_LIBINTERFACE
  122. IClassFactory* pInterface,
  123. #endif // ! DPNBUILD_LIBINTERFACE
  124. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  125. XDP8CREATE_PARAMS * pDP8CreateParams,
  126. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  127. DP8REFIID riid,
  128. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  129. LPVOID *lplpv
  130. )
  131. {
  132. HRESULT hResultCode = S_OK;
  133. DIRECTNETOBJECT *pdnObject = NULL;
  134. #ifndef DPNBUILD_LIBINTERFACE
  135. const _IDirectPlayClassFactory* pDPClassFactory = (_IDirectPlayClassFactory*) pInterface;
  136. #endif // ! DPNBUILD_LIBINTERFACE
  137. DPFX(DPFPREP, 4,"Parameters: lplpv [%p]", lplpv);
  138. /*
  139. *
  140. * TIME BOMB
  141. *
  142. */
  143. #if ((! defined(DX_FINAL_RELEASE)) && (! defined(DPNBUILD_LIBINTERFACE)))
  144. {
  145. #pragma message("BETA EXPIRATION TIME BOMB! Remove for final build!")
  146. SYSTEMTIME st;
  147. GetSystemTime(&st);
  148. if ( st.wYear > DX_EXPIRE_YEAR || ((st.wYear == DX_EXPIRE_YEAR) && (MAKELONG(st.wDay, st.wMonth) > MAKELONG(DX_EXPIRE_DAY, DX_EXPIRE_MONTH))) )
  149. {
  150. MessageBox(0, DX_EXPIRE_TEXT,TEXT("Microsoft Direct Play"), MB_OK);
  151. // return E_FAIL;
  152. }
  153. }
  154. #endif // ! DX_FINAL_RELEASE and ! DPNBUILD_LIBINTERFACE
  155. #ifndef DPNBUILD_LIBINTERFACE
  156. if( pDPClassFactory->clsid == CLSID_DirectPlay8Client )
  157. {
  158. if( riid != IID_IDirectPlay8Client &&
  159. riid != IID_IUnknown
  160. #ifndef DPNBUILD_NOVOICE
  161. && riid != IID_IDirectPlayVoiceTransport
  162. #endif // DPNBUILD_NOVOICE
  163. )
  164. {
  165. DPFX(DPFPREP, 0, "Requesting unknown interface from client CLSID" );
  166. return E_NOINTERFACE;
  167. }
  168. }
  169. #ifndef DPNBUILD_NOSERVER
  170. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Server )
  171. {
  172. if( riid != IID_IDirectPlay8Server &&
  173. riid != IID_IUnknown
  174. #ifndef DPNBUILD_NOVOICE
  175. && riid != IID_IDirectPlayVoiceTransport
  176. #endif // ! DPNBUILD_NOVOICE
  177. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  178. && riid != IID_IDirectPlay8Protocol
  179. #endif // ! DPNBUILD_NOPROTOCOLTESTITF
  180. )
  181. {
  182. DPFX(DPFPREP, 0, "Requesting unknown interface from server CLSID" );
  183. return E_NOINTERFACE;
  184. }
  185. }
  186. #endif // ! DPNBUILD_NOSERVER
  187. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Peer )
  188. {
  189. if( riid != IID_IDirectPlay8Peer &&
  190. riid != IID_IUnknown
  191. #ifndef DPNBUILD_NOVOICE
  192. && riid != IID_IDirectPlayVoiceTransport
  193. #endif // ! DPNBUILD_NOVOICE
  194. )
  195. {
  196. DPFX(DPFPREP, 0, "Requesting unknown interface from peer CLSID" );
  197. return E_NOINTERFACE;
  198. }
  199. }
  200. #ifndef DPNBUILD_NOMULTICAST
  201. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Multicast )
  202. {
  203. if( riid != IID_IDirectPlay8Multicast &&
  204. riid != IID_IUnknown
  205. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  206. && riid != IID_IDirectPlay8Protocol
  207. #endif // ! DPNBUILD_NOPROTOCOLTESTITF
  208. )
  209. {
  210. DPFX(DPFPREP, 0, "Requesting unknown interface from server CLSID" );
  211. return E_NOINTERFACE;
  212. }
  213. }
  214. #endif // ! DPNBUILD_NOMULTICAST
  215. else
  216. {
  217. DNASSERT(FALSE);
  218. }
  219. #endif // ! DPNBUILD_LIBINTERFACE
  220. // Allocate object
  221. pdnObject = (DIRECTNETOBJECT*) DNMalloc(sizeof(DIRECTNETOBJECT));
  222. if (pdnObject == NULL)
  223. {
  224. DPFERR("Creating DIRECTNETOBJECT failed!");
  225. return(E_OUTOFMEMORY);
  226. }
  227. DPFX(DPFPREP, 0,"pdnObject [%p]",pdnObject);
  228. // Zero out the new object so we don't have to individually zero many members
  229. memset(pdnObject, 0, sizeof(DIRECTNETOBJECT));
  230. //
  231. // Signatures
  232. //
  233. pdnObject->Sig[0] = 'D';
  234. pdnObject->Sig[1] = 'N';
  235. pdnObject->Sig[2] = 'E';
  236. pdnObject->Sig[3] = 'T';
  237. #ifndef DPNBUILD_NOVOICE
  238. pdnObject->VoiceSig[0] = 'V';
  239. pdnObject->VoiceSig[1] = 'O';
  240. pdnObject->VoiceSig[2] = 'I';
  241. pdnObject->VoiceSig[3] = 'C';
  242. #endif // !DPNBUILD_NOVOICE
  243. #ifndef DPNBUILD_NOLOBBY
  244. pdnObject->LobbySig[0] = 'L';
  245. pdnObject->LobbySig[1] = 'O';
  246. pdnObject->LobbySig[2] = 'B';
  247. pdnObject->LobbySig[3] = 'B';
  248. #endif // ! DPNBUILD_NOLOBBY
  249. // Initialize Critical Section
  250. if (!DNInitializeCriticalSection(&(pdnObject->csDirectNetObject)))
  251. {
  252. DPFERR("DNInitializeCriticalSection() failed");
  253. DNCF_FreeObject(pdnObject);
  254. return(E_OUTOFMEMORY);
  255. }
  256. if (!DNInitializeCriticalSection(&(pdnObject->csServiceProviders)))
  257. {
  258. DPFERR("DNInitializeCriticalSection() failed");
  259. DNCF_FreeObject(pdnObject);
  260. return(E_OUTOFMEMORY);
  261. }
  262. if (!DNInitializeCriticalSection(&(pdnObject->csNameTableOpList)))
  263. {
  264. DPFERR("DNInitializeCriticalSection() failed");
  265. DNCF_FreeObject(pdnObject);
  266. return(E_OUTOFMEMORY);
  267. }
  268. #ifdef DBG
  269. if (!DNInitializeCriticalSection(&(pdnObject->csAsyncOperations)))
  270. {
  271. DPFERR("DNInitializeCriticalSection() failed");
  272. DNCF_FreeObject(pdnObject);
  273. return(E_OUTOFMEMORY);
  274. }
  275. #endif // DBG
  276. #ifndef DPNBUILD_NOVOICE
  277. if (!DNInitializeCriticalSection(&(pdnObject->csVoice)))
  278. {
  279. DPFERR("DNInitializeCriticalSection() failed");
  280. DNCF_FreeObject(pdnObject);
  281. return(E_OUTOFMEMORY);
  282. }
  283. #endif // !DPNBUILD_NOVOICE
  284. #ifndef DPNBUILD_NONSEQUENTIALWORKERQUEUE
  285. if (!DNInitializeCriticalSection(&(pdnObject->csWorkerQueue)))
  286. {
  287. DPFERR("DNInitializeCriticalSection(worker queue) failed");
  288. DNCF_FreeObject(pdnObject);
  289. return(E_OUTOFMEMORY);
  290. }
  291. #endif // ! DPNBUILD_NONSEQUENTIALWORKERQUEUE
  292. if (!DNInitializeCriticalSection(&(pdnObject->csActiveList)))
  293. {
  294. DPFERR("DNInitializeCriticalSection(csActiveList) failed");
  295. DNCF_FreeObject(pdnObject);
  296. return(E_OUTOFMEMORY);
  297. }
  298. if (!DNInitializeCriticalSection(&(pdnObject->csConnectionList)))
  299. {
  300. DPFERR("DNInitializeCriticalSection(csConnectionList) failed");
  301. DNCF_FreeObject(pdnObject);
  302. return(E_OUTOFMEMORY);
  303. }
  304. if (!DNInitializeCriticalSection(&(pdnObject->csCallbackThreads)))
  305. {
  306. DPFERR("DNInitializeCriticalSection(csCallbackThreads) failed");
  307. DNCF_FreeObject(pdnObject);
  308. return(E_OUTOFMEMORY);
  309. }
  310. #ifndef DPNBUILD_NOPARAMVAL
  311. pdnObject->dwFlags = DN_OBJECT_FLAG_PARAMVALIDATION;
  312. #endif // !DPNBUILD_NOPARAMVAL
  313. //
  314. // Initialize NameTable
  315. //
  316. if ((hResultCode = pdnObject->NameTable.Initialize(pdnObject)) != DPN_OK)
  317. {
  318. DPFERR("Could not initialize NameTable");
  319. DisplayDNError(0,hResultCode);
  320. DNCF_FreeObject(pdnObject);
  321. return(hResultCode);
  322. }
  323. //
  324. // Create a thread pool work interface
  325. //
  326. #ifdef DPNBUILD_LIBINTERFACE
  327. #if ((defined(DPNBUILD_ONLYONETHREAD)) && (! defined(DPNBUILD_MULTIPLETHREADPOOLS)))
  328. DPTPCF_GetObject(reinterpret_cast<void**>(&pdnObject->pIDPThreadPoolWork));
  329. hResultCode = S_OK;
  330. #else // ! DPNBUILD_ONLYONETHREAD or DPNBUILD_MULTIPLETHREADPOOLS
  331. hResultCode = DPTPCF_CreateObject(reinterpret_cast<void**>(&pdnObject->pIDPThreadPoolWork));
  332. #endif // ! DPNBUILD_ONLYONETHREAD or DPNBUILD_MULTIPLETHREADPOOLS
  333. #else // ! DPNBUILD_LIBINTERFACE
  334. hResultCode = COM_CoCreateInstance(CLSID_DirectPlay8ThreadPool,
  335. NULL,
  336. CLSCTX_INPROC_SERVER,
  337. IID_IDirectPlay8ThreadPoolWork,
  338. reinterpret_cast<void**>(&pdnObject->pIDPThreadPoolWork),
  339. FALSE);
  340. #endif // ! DPNBUILD_LIBINTERFACE
  341. if (hResultCode != S_OK)
  342. {
  343. DPFX(DPFPREP, 0, "Could not create Thread Pool Work interface (err = 0x%lx)!", hResultCode);
  344. DisplayDNError(0,hResultCode);
  345. DNCF_FreeObject(pdnObject);
  346. return(hResultCode);
  347. }
  348. //
  349. // Create Protocol Object
  350. //
  351. hResultCode = DNPProtocolCreate(
  352. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  353. pDP8CreateParams,
  354. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  355. &pdnObject->pdnProtocolData
  356. );
  357. if (FAILED(hResultCode))
  358. {
  359. DPFERR("DNPProtocolCreate() failed");
  360. DNCF_FreeObject(pdnObject);
  361. return(E_OUTOFMEMORY);
  362. }
  363. #if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
  364. if ((hResultCode = DNPProtocolInitialize( pdnObject->pdnProtocolData, pdnObject, &g_ProtocolVTBL,
  365. pdnObject->pIDPThreadPoolWork, FALSE)) != DPN_OK)
  366. {
  367. DPFERR("DNPProtocolInitialize() failed");
  368. DisplayDNError(0,hResultCode);
  369. return(E_OUTOFMEMORY);
  370. }
  371. #endif // DPNBUILD_LIBINTERFACE and DPNBUILD_ONLYONESP
  372. pdnObject->hProtocolShutdownEvent = NULL;
  373. pdnObject->lProtocolRefCount = 0;
  374. #ifndef DPNBUILD_ONLYONESP
  375. // Initialize SP List
  376. pdnObject->m_bilinkServiceProviders.Initialize();
  377. #endif // ! DPNBUILD_ONLYONESP
  378. #ifdef DBG
  379. //
  380. // Initialize AsyncOp List
  381. //
  382. pdnObject->m_bilinkAsyncOps.Initialize();
  383. #endif // DBG
  384. //
  385. // Initialize outstanding CConection list
  386. //
  387. pdnObject->m_bilinkConnections.Initialize();
  388. //
  389. // Initialize pending deletion list
  390. //
  391. pdnObject->m_bilinkPendingDeletions.Initialize();
  392. //
  393. // Initialize active AsyncOp list
  394. //
  395. pdnObject->m_bilinkActiveList.Initialize();
  396. //
  397. // Initialize request AsyncOp list
  398. //
  399. pdnObject->m_bilinkRequestList.Initialize();
  400. #ifndef DPNBUILD_NONSEQUENTIALWORKERQUEUE
  401. //
  402. // Initialize worker thread job list
  403. //
  404. pdnObject->m_bilinkWorkerJobs.Initialize();
  405. pdnObject->fProcessingWorkerJobs = FALSE;
  406. #endif // ! DPNBUILD_NONSEQUENTIALWORKERQUEUE
  407. //
  408. // Initialize indicated connection list
  409. //
  410. pdnObject->m_bilinkIndicated.Initialize();
  411. //
  412. // Initialize callback thread list
  413. //
  414. pdnObject->m_bilinkCallbackThreads.Initialize();
  415. // Setup Flags
  416. #ifdef DPNBUILD_LIBINTERFACE
  417. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  418. switch (pDP8CreateParams->riidInterfaceType)
  419. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  420. switch (riid)
  421. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  422. {
  423. case IID_IDirectPlay8Client:
  424. {
  425. DPFX(DPFPREP, 5,"DirectPlay8 CLIENT");
  426. pdnObject->dwFlags |= DN_OBJECT_FLAG_CLIENT;
  427. pdnObject->lpVtbl = &DN_ClientVtbl;
  428. break;
  429. }
  430. #ifndef DPNBUILD_NOSERVER
  431. case IID_IDirectPlay8Server:
  432. {
  433. DPFX(DPFPREP, 5,"DirectPlay8 SERVER");
  434. pdnObject->dwFlags |= DN_OBJECT_FLAG_SERVER;
  435. pdnObject->lpVtbl = &DN_ServerVtbl;
  436. break;
  437. }
  438. #endif // ! DPNBUILD_NOSERVER
  439. case IID_IDirectPlay8Peer:
  440. {
  441. DPFX(DPFPREP, 5,"DirectPlay8 PEER");
  442. pdnObject->dwFlags |= DN_OBJECT_FLAG_PEER;
  443. pdnObject->lpVtbl = &DN_PeerVtbl;
  444. break;
  445. }
  446. #ifndef DPNBUILD_NOMULTICAST
  447. case IID_IDirectPlay8Multicast:
  448. {
  449. DPFX(DPFPREP, 5,"DirectPlay8 MULTICAST");
  450. pdnObject->dwFlags |= DN_OBJECT_FLAG_MULTICAST;
  451. pdnObject->lpVtbl = &DNMcast_Vtbl;
  452. break;
  453. }
  454. #endif // ! DPNBUILD_NOMULTICAST
  455. default:
  456. {
  457. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  458. DPFX(DPFPREP, 0, "Requesting unknown interface type %x!",
  459. pDP8CreateParams->riidInterfaceType);
  460. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  461. DPFX(DPFPREP, 0, "Requesting unknown interface type %x!",
  462. riid);
  463. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  464. return E_NOINTERFACE;
  465. break;
  466. }
  467. }
  468. #else // ! DPNBUILD_LIBINTERFACE
  469. if (IsEqualIID(riid,IID_IDirectPlay8Client))
  470. {
  471. DPFX(DPFPREP, 5,"DirectPlay8 CLIENT");
  472. pdnObject->dwFlags |= DN_OBJECT_FLAG_CLIENT;
  473. }
  474. #ifndef DPNBUILD_NOSERVER
  475. else if (IsEqualIID(riid,IID_IDirectPlay8Server))
  476. {
  477. DPFX(DPFPREP, 5,"DirectPlay8 SERVER");
  478. pdnObject->dwFlags |= DN_OBJECT_FLAG_SERVER;
  479. }
  480. #endif // DPNBUILD_NOSERVER
  481. else if (IsEqualIID(riid,IID_IDirectPlay8Peer))
  482. {
  483. DPFX(DPFPREP, 5,"DirectPlay8 PEER");
  484. pdnObject->dwFlags |= DN_OBJECT_FLAG_PEER;
  485. }
  486. #ifndef DPNBUILD_NOMULTICAST
  487. else if (IsEqualIID(riid,IID_IDirectPlay8Multicast))
  488. {
  489. DPFX(DPFPREP, 5,"DirectPlay8 MULTICAST");
  490. pdnObject->dwFlags |= DN_OBJECT_FLAG_MULTICAST;
  491. }
  492. #endif // DPNBUILD_NOMULTICAST
  493. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  494. else if (IsEqualIID(riid,IID_IDirectPlay8Protocol))
  495. {
  496. DPFX(DPFPREP, 5,"IDirectPlay8Protocol");
  497. pdnObject->dwFlags |= DN_OBJECT_FLAG_SERVER;
  498. }
  499. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  500. else if( riid == IID_IUnknown )
  501. {
  502. if( pDPClassFactory->clsid == CLSID_DirectPlay8Client )
  503. {
  504. DPFX(DPFPREP, 5,"DirectPlay8 CLIENT via IUnknown");
  505. pdnObject->dwFlags |= DN_OBJECT_FLAG_CLIENT;
  506. }
  507. #ifndef DPNBUILD_NOSERVER
  508. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Server )
  509. {
  510. DPFX(DPFPREP, 5,"DirectPlay8 SERVER via IUnknown");
  511. pdnObject->dwFlags |= DN_OBJECT_FLAG_SERVER;
  512. }
  513. #endif // DPNBUILD_NOSERVER
  514. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Peer )
  515. {
  516. DPFX(DPFPREP, 5,"DirectPlay8 PEER via IUnknown");
  517. pdnObject->dwFlags |= DN_OBJECT_FLAG_PEER;
  518. }
  519. #ifndef DPNBUILD_NOMULTICAST
  520. else if( pDPClassFactory->clsid == CLSID_DirectPlay8Multicast )
  521. {
  522. DPFX(DPFPREP, 5,"DirectPlay8 MULTICAST via IUnknown");
  523. pdnObject->dwFlags |= DN_OBJECT_FLAG_MULTICAST;
  524. }
  525. #endif // DPNBUILD_NOMULTICAST
  526. else
  527. {
  528. DPFX(DPFPREP, 0,"Unknown CLSID!");
  529. DNASSERT( FALSE );
  530. DNCF_FreeObject(pdnObject);
  531. return(E_NOTIMPL);
  532. }
  533. }
  534. else
  535. {
  536. DPFX(DPFPREP, 0,"Invalid DirectPlay8 Interface");
  537. DNCF_FreeObject(pdnObject);
  538. return(E_NOTIMPL);
  539. }
  540. #endif // ! DPNBUILD_LIBINTERFACE
  541. //
  542. // Create lock event
  543. //
  544. if ((pdnObject->hLockEvent = DNCreateEvent(NULL,TRUE,FALSE,NULL)) == NULL)
  545. {
  546. DPFERR("Unable to create lock event");
  547. DNCF_FreeObject(pdnObject);
  548. return(DPNERR_OUTOFMEMORY);
  549. }
  550. //
  551. // Create running operation event (for host migration)
  552. //
  553. if ( pdnObject->dwFlags & DN_OBJECT_FLAG_PEER )
  554. {
  555. if ((pdnObject->hRunningOpEvent = DNCreateEvent(NULL,TRUE,FALSE,NULL)) == NULL)
  556. {
  557. DPFERR("Unable to create running operation event");
  558. DNCF_FreeObject(pdnObject);
  559. return(DPNERR_OUTOFMEMORY);
  560. }
  561. }
  562. #ifndef DPNBUILD_NOMULTICAST
  563. pdnObject->pMulticastSend = NULL;
  564. pdnObject->m_bilinkMulticast.Initialize();
  565. #endif // DPNBUILD_NOMULTICAST
  566. #ifdef DPNBUILD_LIBINTERFACE
  567. #ifdef DPNBUILD_ONLYONESP
  568. hResultCode = DN_SPInstantiate(
  569. pdnObject
  570. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  571. ,pDP8CreateParams
  572. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  573. );
  574. if (hResultCode != S_OK)
  575. {
  576. DPFX(DPFPREP, 0, "Could not instantiate SP (err = 0x%lx)!", hResultCode);
  577. DisplayDNError(0,hResultCode);
  578. DNCF_FreeObject(pdnObject);
  579. return(hResultCode);
  580. }
  581. #endif // DPNBUILD_ONLYONESP
  582. //
  583. // For lib interface builds, the refcount is embedded in object.
  584. //
  585. pdnObject->lRefCount = 1;
  586. #endif // DPNBUILD_LIBINTERFACE
  587. *lplpv = pdnObject;
  588. DPFX(DPFPREP, 4,"Returning: hResultCode = [%lx], *lplpv = [%p]",hResultCode,*lplpv);
  589. return(hResultCode);
  590. }
  591. #ifndef WINCE
  592. #ifdef _XBOX
  593. #undef DPF_MODNAME
  594. #define DPF_MODNAME "XDirectPlay8Create"
  595. HRESULT WINAPI XDirectPlay8Create(
  596. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  597. const XDP8CREATE_PARAMS * const pDP8CreateParams,
  598. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  599. DP8REFIID riidInterfaceType,
  600. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  601. void **ppvInterface
  602. )
  603. {
  604. HRESULT hr;
  605. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  606. XDP8CREATE_PARAMS CreateParamsAdjusted;
  607. DPFX(DPFPREP, 5, "Parameters: pDP8CreateParams[0x%p], ppvInterface[0x%p]", pDP8CreateParams, ppvInterface);
  608. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  609. DPFX(DPFPREP, 5, "Parameters: riidInterfaceType[0x%x], ppvInterface[0x%p]", riidInterfaceType, ppvInterface);
  610. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  611. #ifndef DPNBUILD_NOPARAMVAL
  612. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  613. if ((pDP8CreateParams == NULL) ||
  614. (! DNVALID_READPTR(pDP8CreateParams, sizeof(CreateParamsAdjusted))))
  615. {
  616. DPFX(DPFPREP, 0, "Invalid pointer to Create parameters!");
  617. return DPNERR_INVALIDPOINTER;
  618. }
  619. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  620. if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
  621. {
  622. DPFX(DPFPREP, 0, "Invalid pointer specified to receive interface!");
  623. return DPNERR_INVALIDPOINTER;
  624. }
  625. #endif // ! DPNBUILD_NOPARAMVAL
  626. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  627. memcpy(&CreateParamsAdjusted, pDP8CreateParams, sizeof(CreateParamsAdjusted));
  628. switch (CreateParamsAdjusted.riidInterfaceType)
  629. {
  630. case IID_IDirectPlay8Client:
  631. {
  632. CreateParamsAdjusted.dwMaxNumPlayers = 1;
  633. break;
  634. }
  635. #ifndef DPNBUILD_NOSERVER
  636. case IID_IDirectPlay8Server:
  637. #endif // ! DPNBUILD_NOSERVER
  638. case IID_IDirectPlay8Peer:
  639. {
  640. //
  641. // Include room for hidden All Players group.
  642. //
  643. CreateParamsAdjusted.dwMaxNumGroups++;
  644. break;
  645. }
  646. #ifndef DPNBUILD_NOMULTICAST
  647. case IID_IDirectPlay8Multicast:
  648. {
  649. CreateParamsAdjusted.dwMaxNumGroups = 0;
  650. break;
  651. }
  652. #endif // ! DPNBUILD_NOMULTICAST
  653. #ifndef DPNBUILD_NOPARAMVAL
  654. default:
  655. {
  656. DPFX(DPFPREP, 0, "Requesting unknown interface type %u!", CreateParamsAdjusted.riidInterfaceType);
  657. return E_NOINTERFACE;
  658. break;
  659. }
  660. #endif // ! DPNBUILD_NOPARAMVAL
  661. }
  662. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  663. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  664. DNASSERT(! DNMemoryTrackAreAllocationsAllowed());
  665. DNMemoryTrackAllowAllocations(TRUE);
  666. hr = DNCF_CreateObject(&CreateParamsAdjusted, ppvInterface);
  667. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  668. DNASSERT(DNMemoryTrackAreAllocationsAllowed());
  669. hr = DNCF_CreateObject(riidInterfaceType, ppvInterface);
  670. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  671. if (hr != S_OK)
  672. {
  673. DPFX(DPFPREP, 0, "Couldn't create interface!");
  674. return hr;
  675. }
  676. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  677. //
  678. // Pre-allocate the requested memory.
  679. //
  680. hr = DN_PopulateCorePools((DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(*ppvInterface),
  681. &CreateParamsAdjusted);
  682. if (hr != DPN_OK)
  683. {
  684. DPFX(DPFPREP, 0, "Couldn't populate core pools!");
  685. DNCF_FreeObject((DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(*ppvInterface));
  686. *ppvInterface = NULL;
  687. return hr;
  688. }
  689. DNASSERT(DNMemoryTrackAreAllocationsAllowed());
  690. DNMemoryTrackAllowAllocations(FALSE);
  691. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  692. return DPN_OK;
  693. }
  694. extern STDMETHODIMP DPTP_DoWork(const DWORD dwAllowedTimeSlice,
  695. const DWORD dwFlags);
  696. HRESULT WINAPI XDirectPlay8DoWork(const DWORD dwAllowedTimeSlice)
  697. {
  698. return DPTP_DoWork(dwAllowedTimeSlice, 0);
  699. }
  700. HRESULT WINAPI XDirectPlay8BuildAppDescReservedData(const XNKID * const pSessionID,
  701. const XNKEY * const pKeyExchangeKey,
  702. PVOID pvReservedData,
  703. DWORD * const pcbReservedDataSize)
  704. {
  705. SPSESSIONDATA_XNET * pSessionDataXNet;
  706. #ifndef DPNBUILD_NOPARAMVAL
  707. if ((pSessionID == NULL) ||
  708. (! DNVALID_READPTR(pSessionID, sizeof(XNKID))))
  709. {
  710. DPFERR("Invalid session key ID specified");
  711. return DPNERR_INVALIDPOINTER;
  712. }
  713. if ((pKeyExchangeKey == NULL) ||
  714. (! DNVALID_READPTR(pKeyExchangeKey, sizeof(XNKEY))))
  715. {
  716. DPFERR("Invalid key exchange key specified");
  717. return DPNERR_INVALIDPOINTER;
  718. }
  719. if ((pcbReservedDataSize == NULL) ||
  720. (! DNVALID_WRITEPTR(pcbReservedDataSize, sizeof(DWORD))))
  721. {
  722. DPFERR("Invalid pointer specified for data size");
  723. return DPNERR_INVALIDPOINTER;
  724. }
  725. if ((*pcbReservedDataSize > 0) &&
  726. ((pvReservedData == NULL) || (! DNVALID_WRITEPTR(pvReservedData, *pcbReservedDataSize))))
  727. {
  728. DPFERR("Invalid pointer specified for reserved data buffer");
  729. return DPNERR_INVALIDPOINTER;
  730. }
  731. #endif // ! DPNBUILD_NOPARAMVAL
  732. if (*pcbReservedDataSize < DPN_MAX_APPDESC_RESERVEDDATA_SIZE)
  733. {
  734. *pcbReservedDataSize = DPN_MAX_APPDESC_RESERVEDDATA_SIZE;
  735. return DPNERR_BUFFERTOOSMALL;
  736. }
  737. DBG_CASSERT(sizeof(SPSESSIONDATA_XNET) < DPN_MAX_APPDESC_RESERVEDDATA_SIZE);
  738. pSessionDataXNet = (SPSESSIONDATA_XNET*) pvReservedData;
  739. pSessionDataXNet->dwInfo = SPSESSIONDATAINFO_XNET;
  740. DBG_CASSERT(sizeof(pSessionDataXNet->guidKey) == sizeof(*pKeyExchangeKey));
  741. memcpy(&pSessionDataXNet->guidKey, pKeyExchangeKey, sizeof(pSessionDataXNet->guidKey));
  742. DBG_CASSERT(sizeof(pSessionDataXNet->ullKeyID) == sizeof(*pSessionID));
  743. memcpy(&pSessionDataXNet->ullKeyID, pSessionID, sizeof(pSessionDataXNet->ullKeyID));
  744. //
  745. // Fill in the remainder of the data with deterministic but non-obvious bytes so
  746. // that we can:
  747. // a) overwrite potential stack garbage
  748. // b) prevent the app from being able to assume there will always be less than
  749. // DPN_MAX_APPDESC_RESERVEDDATA_SIZE bytes of data. This gives us a little
  750. // flexibility for forward compatibility.
  751. //
  752. memset((pSessionDataXNet + 1),
  753. (((BYTE*) pSessionID)[1] ^ ((BYTE*) pKeyExchangeKey)[2]),
  754. (DPN_MAX_APPDESC_RESERVEDDATA_SIZE - sizeof(SPSESSIONDATA_XNET)));
  755. *pcbReservedDataSize = DPN_MAX_APPDESC_RESERVEDDATA_SIZE;
  756. return DPN_OK;
  757. }
  758. #undef DPF_MODNAME
  759. #define DPF_MODNAME "XDirectPlay8AddressCreate"
  760. HRESULT WINAPI XDirectPlay8AddressCreate( DPNAREFIID riid, void **ppvInterface )
  761. {
  762. HRESULT hr;
  763. DPFX(DPFPREP, 5, "Parameters: riid[0x%p], ppvInterface[0x%p]", &riid, ppvInterface);
  764. #ifndef DPNBUILD_NOPARAMVAL
  765. if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
  766. {
  767. DPFERR( "Invalid pointer specified to receive interface" );
  768. return DPNERR_INVALIDPOINTER;
  769. }
  770. switch (riid)
  771. {
  772. case IID_IDirectPlay8Address:
  773. {
  774. break;
  775. }
  776. case IID_IDirectPlay8AddressIP:
  777. {
  778. #ifdef DPNBUILD_NOADDRESSIPINTERFACE
  779. DPFX(DPFPREP, 0, "The IDirectPlay8AddressIP interface is not supported!");
  780. return DPNERR_UNSUPPORTED;
  781. #endif // DPNBUILD_NOADDRESSIPINTERFACE
  782. break;
  783. }
  784. default:
  785. {
  786. DPFX(DPFPREP, 0, "Requesting unknown interface type %u!", riid);
  787. return E_NOINTERFACE;
  788. break;
  789. }
  790. }
  791. #endif // ! DPNBUILD_NOPARAMVAL
  792. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  793. DNASSERT(! DNMemoryTrackAreAllocationsAllowed());
  794. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  795. DNASSERT(DNMemoryTrackAreAllocationsAllowed());
  796. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  797. hr = DP8ACF_CreateInstance(riid, ppvInterface);
  798. if (hr != S_OK)
  799. {
  800. DPFX(DPFPREP, 0, "Couldn't create interface!");
  801. return hr;
  802. }
  803. return S_OK;
  804. }
  805. #undef DPF_MODNAME
  806. #define DPF_MODNAME "XDirectPlay8AddressCreateFromXnAddr"
  807. HRESULT WINAPI XDirectPlay8AddressCreateFromXnAddr( XNADDR *pxnaddr, IDirectPlay8Address **ppInterface )
  808. {
  809. HRESULT hr;
  810. TCHAR tszHostname[(sizeof(XNADDR) * 2) + 1]; // 2 characters for every byte + NULL termination
  811. TCHAR * ptszCurrent;
  812. BYTE * pbCurrent;
  813. DWORD dwTemp;
  814. DPFX(DPFPREP, 5, "Parameters: pxnaddr[0x%p], ppInterface[0x%p]", pxnaddr, ppInterface);
  815. #ifndef DPNBUILD_NOPARAMVAL
  816. if( pxnaddr == NULL )
  817. {
  818. DPFERR( "Invalid XNADDR" );
  819. return DPNERR_INVALIDPOINTER;
  820. }
  821. if( ppInterface == NULL || !DNVALID_WRITEPTR( ppInterface, sizeof( IDirectPlay8Address * ) ) )
  822. {
  823. DPFERR( "Invalid pointer specified to receive interface" );
  824. return DPNERR_INVALIDPOINTER;
  825. }
  826. #endif // ! DPNBUILD_NOPARAMVAL
  827. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  828. DNASSERT(! DNMemoryTrackAreAllocationsAllowed());
  829. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  830. DNASSERT(DNMemoryTrackAreAllocationsAllowed());
  831. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  832. hr = DP8ACF_CreateInstance(IID_IDirectPlay8Address, (PVOID*) ppInterface);
  833. if (hr != S_OK)
  834. {
  835. DPFX(DPFPREP, 0, "Couldn't create interface!");
  836. return hr;
  837. }
  838. ptszCurrent = tszHostname;
  839. pbCurrent = (BYTE*) pxnaddr;
  840. for(dwTemp = 0; dwTemp < sizeof(XNADDR); dwTemp++)
  841. {
  842. ptszCurrent += wsprintf(tszHostname, _T("%02X"), (*pbCurrent));
  843. pbCurrent++;
  844. }
  845. DNASSERT(((_tcslen(tszHostname) + 1) * sizeof(TCHAR)) == sizeof(tszHostname));
  846. #ifdef UNICODE
  847. hr = IDirectPlay8Address_AddComponent((*ppInterface),
  848. DPNA_KEY_HOSTNAME,
  849. tszHostname,
  850. sizeof(tszHostname),
  851. DPNA_DATATYPE_STRING);
  852. #else // ! UNICODE
  853. hr = IDirectPlay8Address_AddComponent((*ppInterface),
  854. DPNA_KEY_HOSTNAME,
  855. tszHostname,
  856. sizeof(tszHostname),
  857. DPNA_DATATYPE_STRING_ANSI);
  858. #endif // ! UNICODE
  859. if (hr != DPN_OK)
  860. {
  861. DPFX(DPFPREP, 0, "Couldn't add hostname component!");
  862. IDirectPlay8Address_Release(*ppInterface);
  863. *ppInterface = NULL;
  864. return hr;
  865. }
  866. return S_OK;
  867. }
  868. #else // ! _XBOX
  869. #undef DPF_MODNAME
  870. #define DPF_MODNAME "DirectPlay8Create"
  871. HRESULT WINAPI DirectPlay8Create( const GUID * pcIID, void **ppvInterface, IUnknown *pUnknown)
  872. {
  873. GUID clsid;
  874. DPFX(DPFPREP, 5, "Parameters: pcIID[0x%p], ppvInterface[0x%p], pUnknown[0x%p]", pcIID, ppvInterface, pUnknown);
  875. #ifndef DPNBUILD_NOPARAMVAL
  876. if( pcIID == NULL ||
  877. !DNVALID_READPTR( pcIID, sizeof( GUID ) ) )
  878. {
  879. DPFERR( "Invalid pointer specified for interface GUID" );
  880. return DPNERR_INVALIDPOINTER;
  881. }
  882. if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
  883. {
  884. DPFERR( "Invalid pointer specified to receive interface" );
  885. return DPNERR_INVALIDPOINTER;
  886. }
  887. if( pUnknown != NULL )
  888. {
  889. DPFERR( "Aggregation is not supported by this object yet" );
  890. return DPNERR_INVALIDPARAM;
  891. }
  892. #endif // ! DPNBUILD_NOPARAMVAL
  893. if( *pcIID == IID_IDirectPlay8Client )
  894. {
  895. clsid = CLSID_DirectPlay8Client;
  896. }
  897. #ifndef DPNBUILD_NOSERVER
  898. else if( *pcIID == IID_IDirectPlay8Server )
  899. {
  900. clsid = CLSID_DirectPlay8Server;
  901. }
  902. #endif // ! DPNBUILD_NOSERVER
  903. else if( *pcIID == IID_IDirectPlay8Peer )
  904. {
  905. clsid = CLSID_DirectPlay8Peer;
  906. }
  907. #ifndef DPNBUILD_NOMULTICAST
  908. else if( *pcIID == IID_IDirectPlay8Multicast )
  909. {
  910. clsid = CLSID_DirectPlay8Multicast;
  911. }
  912. #endif // ! DPNBUILD_NOMULTICAST
  913. #ifndef DPNBUILD_NOLOBBY
  914. else if( *pcIID == IID_IDirectPlay8LobbyClient )
  915. {
  916. clsid = CLSID_DirectPlay8LobbyClient;
  917. }
  918. else if( *pcIID == IID_IDirectPlay8LobbiedApplication )
  919. {
  920. clsid = CLSID_DirectPlay8LobbiedApplication;
  921. }
  922. #endif // ! DPNBUILD_NOLOBBY
  923. else if( *pcIID == IID_IDirectPlay8Address )
  924. {
  925. clsid = CLSID_DirectPlay8Address;
  926. }
  927. #ifndef DPNBUILD_NOADDRESSIPINTERFACE
  928. else if( *pcIID == IID_IDirectPlay8AddressIP )
  929. {
  930. clsid = CLSID_DirectPlay8Address;
  931. }
  932. #endif // ! DPNBUILD_NOADDRESSIPINTERFACE
  933. else
  934. {
  935. DPFERR( "Invalid IID specified" );
  936. return DPNERR_INVALIDPARAM;
  937. }
  938. return COM_CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, *pcIID, ppvInterface, TRUE );
  939. }
  940. #endif // ! _XBOX
  941. #endif // ! WINCE
  942. #undef DPF_MODNAME
  943. #define DPF_MODNAME "DNCF_FreeObject"
  944. HRESULT DNCF_FreeObject(PVOID pInterface)
  945. {
  946. HRESULT hResultCode = S_OK;
  947. DIRECTNETOBJECT *pdnObject;
  948. DPFX(DPFPREP, 4,"Parameters: pInterface [0x%p]",pInterface);
  949. #pragma BUGBUG(minara,"Do I need to delete the fixed pools here ?")
  950. if (pInterface == NULL)
  951. {
  952. return(DPNERR_INVALIDPARAM);
  953. }
  954. pdnObject = static_cast<DIRECTNETOBJECT*>(pInterface);
  955. DNASSERT(pdnObject != NULL);
  956. #ifdef DPNBUILD_LIBINTERFACE
  957. //
  958. // For lib interface builds, the reference is embedded in the object directly.
  959. //
  960. DNASSERT(pdnObject->lRefCount == 0);
  961. #ifdef DPNBUILD_ONLYONESP
  962. DN_SPReleaseAll(pdnObject);
  963. #endif // DPNBUILD_ONLYONESP
  964. #endif // DPNBUILD_LIBINTERFACE
  965. //
  966. // No connect SP
  967. //
  968. DNASSERT(pdnObject->pConnectSP == NULL);
  969. //
  970. // No outstanding listens
  971. //
  972. DNASSERT(pdnObject->pListenParent == NULL);
  973. //
  974. // No outstanding connect
  975. //
  976. DNASSERT(pdnObject->pConnectParent == NULL);
  977. //
  978. // Host migration target
  979. //
  980. DNASSERT(pdnObject->pNewHost == NULL);
  981. //
  982. // Protocol shutdown event
  983. //
  984. DNASSERT(pdnObject->hProtocolShutdownEvent == NULL);
  985. //
  986. // Lock event
  987. //
  988. if (pdnObject->hLockEvent)
  989. {
  990. DNCloseHandle(pdnObject->hLockEvent);
  991. }
  992. //
  993. // Running operations
  994. //
  995. if (pdnObject->hRunningOpEvent)
  996. {
  997. DNCloseHandle(pdnObject->hRunningOpEvent);
  998. }
  999. #ifdef DPNBUILD_ONLYONETHREAD
  1000. #ifndef DPNBUILD_NONSEQUENTIALWORKERQUEUE
  1001. DNASSERT(pdnObject->ThreadPoolShutDownEvent == NULL);
  1002. DNASSERT(pdnObject->lThreadPoolRefCount == 0);
  1003. #endif // DPNBUILD_NONSEQUENTIALWORKERQUEUE
  1004. #endif // DPNBUILD_ONLYONETHREAD
  1005. // pIDPThreadPoolWork will be NULL if we failed CoCreate'ing the thread pool in DNCF_CreateObject
  1006. if (pdnObject->pIDPThreadPoolWork != NULL)
  1007. {
  1008. IDirectPlay8ThreadPoolWork_Release(pdnObject->pIDPThreadPoolWork);
  1009. pdnObject->pIDPThreadPoolWork = NULL;
  1010. }
  1011. #ifndef DPNBUILD_NONSEQUENTIALWORKERQUEUE
  1012. DNDeleteCriticalSection(&pdnObject->csWorkerQueue);
  1013. #endif // ! DPNBUILD_NONSEQUENTIALWORKERQUEUE
  1014. //
  1015. // Protocol
  1016. //
  1017. #if ((defined(DPNBUILD_LIBINTERFACE)) && (defined(DPNBUILD_ONLYONESP)))
  1018. if ((hResultCode = DNPProtocolShutdown(pdnObject->pdnProtocolData)) != DPN_OK)
  1019. {
  1020. DPFERR("Could not shut down Protocol Layer !");
  1021. DisplayDNError(0,hResultCode);
  1022. DNASSERT(FALSE);
  1023. }
  1024. #endif // DPNBUILD_LIBINTERFACE and DPNBUILD_ONLYONESP
  1025. DNPProtocolDestroy(pdnObject->pdnProtocolData);
  1026. pdnObject->pdnProtocolData = NULL;
  1027. //
  1028. // Deinitialize NameTable
  1029. //
  1030. DPFX(DPFPREP, 3,"Deinitializing NameTable");
  1031. pdnObject->NameTable.Deinitialize();
  1032. // Active AsyncOp List Critical Section
  1033. DNDeleteCriticalSection(&pdnObject->csActiveList);
  1034. // NameTable operation list Critical Section
  1035. DNDeleteCriticalSection(&pdnObject->csNameTableOpList);
  1036. // Service Providers Critical Section
  1037. DNDeleteCriticalSection(&pdnObject->csServiceProviders);
  1038. #ifdef DBG
  1039. // Async Ops Critical Section
  1040. DNDeleteCriticalSection(&pdnObject->csAsyncOperations);
  1041. #endif // DBG
  1042. // Connection Critical Section
  1043. DNDeleteCriticalSection(&pdnObject->csConnectionList);
  1044. #ifndef DPNBUILD_NOVOICE
  1045. // Voice Critical Section
  1046. DNDeleteCriticalSection(&pdnObject->csVoice);
  1047. #endif // !DPNBUILD_NOVOICE
  1048. // Callback Thread List Critical Section
  1049. DNDeleteCriticalSection(&pdnObject->csCallbackThreads);
  1050. #ifndef DPNBUILD_NOLOBBY
  1051. if( pdnObject->pIDP8LobbiedApplication)
  1052. {
  1053. IDirectPlay8LobbiedApplication_Release( pdnObject->pIDP8LobbiedApplication );
  1054. pdnObject->pIDP8LobbiedApplication = NULL;
  1055. }
  1056. #endif // ! DPNBUILD_NOLOBBY
  1057. // Delete DirectNet critical section
  1058. DNDeleteCriticalSection(&pdnObject->csDirectNetObject);
  1059. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  1060. if (pdnObject->fPoolsPrepopulated)
  1061. {
  1062. pdnObject->EnumReplyMemoryBlockPool.DeInitialize();
  1063. pdnObject->fPoolsPrepopulated = FALSE;
  1064. }
  1065. #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
  1066. DPFX(DPFPREP, 5,"free pdnObject [%p]",pdnObject);
  1067. DNFree(pdnObject);
  1068. DPFX(DPFPREP, 4,"Returning: [%lx]",hResultCode);
  1069. return(hResultCode);
  1070. }
  1071. #ifdef DPNBUILD_LIBINTERFACE
  1072. #undef DPF_MODNAME
  1073. #define DPF_MODNAME "DN_QueryInterface"
  1074. STDMETHODIMP DN_QueryInterface(void *pInterface,
  1075. DP8REFIID riid,
  1076. void **ppv)
  1077. {
  1078. HRESULT hResultCode;
  1079. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p], riid [0x%p], ppv [0x%p]",pInterface,&riid,ppv);
  1080. DPFX(DPFPREP, 0, "Querying for an interface is not supported!");
  1081. hResultCode = DPNERR_UNSUPPORTED;
  1082. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  1083. return(hResultCode);
  1084. }
  1085. #undef DPF_MODNAME
  1086. #define DPF_MODNAME "DN_AddRef"
  1087. STDMETHODIMP_(ULONG) DN_AddRef(void *pInterface)
  1088. {
  1089. DIRECTNETOBJECT *pdnObject;
  1090. LONG lRefCount;
  1091. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p]",pInterface);
  1092. #ifndef DPNBUILD_NOPARAMVAL
  1093. if (pInterface == NULL)
  1094. {
  1095. DPFERR("Invalid COM interface specified");
  1096. lRefCount = 0;
  1097. goto Exit;
  1098. }
  1099. #endif // ! DPNBUILD_NOPARAMVAL
  1100. pdnObject = static_cast<DIRECTNETOBJECT*>(pInterface);
  1101. lRefCount = DNInterlockedIncrement( &pdnObject->lRefCount );
  1102. DPFX(DPFPREP, 5,"New lRefCount [%ld]",lRefCount);
  1103. #ifndef DPNBUILD_NOPARAMVAL
  1104. Exit:
  1105. #endif // ! DPNBUILD_NOPARAMVAL
  1106. DPFX(DPFPREP, 2,"Returning: lRefCount [%ld]",lRefCount);
  1107. return(lRefCount);
  1108. }
  1109. #undef DPF_MODNAME
  1110. #define DPF_MODNAME "DN_Release"
  1111. STDMETHODIMP_(ULONG) DN_Release(void *pInterface)
  1112. {
  1113. DIRECTNETOBJECT *pdnObject;
  1114. LONG lRefCount;
  1115. DPFX(DPFPREP, 2,"Parameters: pInterface [%p]",pInterface);
  1116. #ifndef DPNBUILD_NOPARAMVAL
  1117. if (pInterface == NULL)
  1118. {
  1119. DPFERR("Invalid COM interface specified");
  1120. lRefCount = 0;
  1121. goto Exit;
  1122. }
  1123. #endif // ! DPNBUILD_NOPARAMVAL
  1124. pdnObject = static_cast<DIRECTNETOBJECT*>(pInterface);
  1125. lRefCount = DNInterlockedDecrement( &pdnObject->lRefCount );
  1126. DPFX(DPFPREP, 5,"New lRefCount [%ld]",lRefCount);
  1127. if (lRefCount == 0)
  1128. {
  1129. //
  1130. // Ensure we're properly closed
  1131. //
  1132. DN_Close(pdnObject, 0);
  1133. // Free object here
  1134. DPFX(DPFPREP, 5,"Free object");
  1135. DNCF_FreeObject(pdnObject);
  1136. }
  1137. #ifndef DPNBUILD_NOPARAMVAL
  1138. Exit:
  1139. #endif // ! DPNBUILD_NOPARAMVAL
  1140. DPFX(DPFPREP, 2,"Returning: lRefCount [%ld]",lRefCount);
  1141. return(lRefCount);
  1142. }
  1143. #else // ! DPNBUILD_LIBINTERFACE
  1144. #undef DPF_MODNAME
  1145. #define DPF_MODNAME "DNCORECF_CreateInstance"
  1146. STDMETHODIMP DNCORECF_CreateInstance(IClassFactory *pInterface,
  1147. LPUNKNOWN lpUnkOuter,
  1148. REFIID riid,
  1149. void **ppv)
  1150. {
  1151. HRESULT hResultCode;
  1152. INTERFACE_LIST *pIntList;
  1153. OBJECT_DATA *pObjectData;
  1154. DPFX(DPFPREP, 6,"Parameters: pInterface [%p], lpUnkOuter [%p], riid [%p], ppv [%p]",pInterface,lpUnkOuter,&riid,ppv);
  1155. #ifndef DPNBUILD_NOPARAMVAL
  1156. if (pInterface == NULL)
  1157. {
  1158. DPFERR("Invalid COM interface specified");
  1159. hResultCode = E_INVALIDARG;
  1160. goto Exit;
  1161. }
  1162. if (lpUnkOuter != NULL)
  1163. {
  1164. hResultCode = CLASS_E_NOAGGREGATION;
  1165. goto Exit;
  1166. }
  1167. if (ppv == NULL)
  1168. {
  1169. DPFERR("Invalid target interface pointer specified");
  1170. hResultCode = E_INVALIDARG;
  1171. goto Exit;
  1172. }
  1173. #endif // ! DPNBUILD_NOPARAMVAL
  1174. pObjectData = NULL;
  1175. pIntList = NULL;
  1176. if ((pObjectData = static_cast<OBJECT_DATA*>(DNMalloc(sizeof(OBJECT_DATA)))) == NULL)
  1177. {
  1178. DPFERR("Could not allocate object");
  1179. hResultCode = E_OUTOFMEMORY;
  1180. goto Failure;
  1181. }
  1182. // Object creation and initialization
  1183. if ((hResultCode = DNCF_CreateObject(pInterface, riid, &pObjectData->pvData)) != S_OK)
  1184. {
  1185. DPFERR("Could not create object");
  1186. goto Failure;
  1187. }
  1188. DPFX(DPFPREP, 7,"Created and initialized object");
  1189. // Get requested interface
  1190. if ((hResultCode = DN_CreateInterface(pObjectData,riid,&pIntList)) != S_OK)
  1191. {
  1192. DNCF_FreeObject(pObjectData->pvData);
  1193. goto Failure;
  1194. }
  1195. DPFX(DPFPREP, 7,"Found interface");
  1196. pObjectData->pIntList = pIntList;
  1197. pObjectData->lRefCount = 1;
  1198. DN_AddRef( pIntList );
  1199. DNInterlockedIncrement(&g_lCoreObjectCount);
  1200. *ppv = pIntList;
  1201. DPFX(DPFPREP, 7,"*ppv = [0x%p]",*ppv);
  1202. hResultCode = S_OK;
  1203. Exit:
  1204. DPFX(DPFPREP, 6,"Returning: [0x%lx]",hResultCode);
  1205. return(hResultCode);
  1206. Failure:
  1207. if (pObjectData)
  1208. {
  1209. DNFree(pObjectData);
  1210. pObjectData = NULL;
  1211. }
  1212. goto Exit;
  1213. }
  1214. #undef DPF_MODNAME
  1215. #define DPF_MODNAME "DN_CreateInterface"
  1216. HRESULT DN_CreateInterface(OBJECT_DATA *pObject,
  1217. REFIID riid,
  1218. INTERFACE_LIST **const ppv)
  1219. {
  1220. INTERFACE_LIST *pIntNew;
  1221. PVOID lpVtbl;
  1222. HRESULT hResultCode;
  1223. DPFX(DPFPREP, 6,"Parameters: pObject [%p], riid [%p], ppv [%p]",pObject,&riid,ppv);
  1224. DNASSERT(pObject != NULL);
  1225. DNASSERT(ppv != NULL);
  1226. const DIRECTNETOBJECT* pdnObject = ((DIRECTNETOBJECT *)pObject->pvData);
  1227. if (IsEqualIID(riid,IID_IUnknown))
  1228. {
  1229. DPFX(DPFPREP, 7,"riid = IID_IUnknown");
  1230. lpVtbl = &DN_UnknownVtbl;
  1231. }
  1232. #ifndef DPNBUILD_NOVOICE
  1233. else if (IsEqualIID(riid,IID_IDirectPlayVoiceTransport))
  1234. {
  1235. DPFX(DPFPREP, 7,"riid = IID_IDirectPlayVoiceTransport");
  1236. lpVtbl = &DN_VoiceTbl;
  1237. }
  1238. #endif // !DPNBUILD_NOVOICE
  1239. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  1240. else if (IsEqualIID(riid,IID_IDirectPlay8Protocol))
  1241. {
  1242. DPFX(DPFPREP, 7,"riid = IID_IDirectPlay8Protocol");
  1243. lpVtbl = &DN_ProtocolVtbl;
  1244. }
  1245. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  1246. else if (IsEqualIID(riid,IID_IDirectPlay8Client) &&
  1247. pdnObject->dwFlags & DN_OBJECT_FLAG_CLIENT )
  1248. {
  1249. DPFX(DPFPREP, 7,"riid = IID_IDirectPlay8Client");
  1250. lpVtbl = &DN_ClientVtbl;
  1251. }
  1252. #ifndef DPNBUILD_NOSERVER
  1253. else if (IsEqualIID(riid,IID_IDirectPlay8Server) &&
  1254. pdnObject->dwFlags & DN_OBJECT_FLAG_SERVER )
  1255. {
  1256. DPFX(DPFPREP, 7,"riid = IID_IDirectPlay8Server");
  1257. lpVtbl = &DN_ServerVtbl;
  1258. }
  1259. #endif // DPNBUILD_NOSERVER
  1260. else if (IsEqualIID(riid,IID_IDirectPlay8Peer) &&
  1261. pdnObject->dwFlags & DN_OBJECT_FLAG_PEER )
  1262. {
  1263. DPFX(DPFPREP, 7,"riid = IID_IDirectPlay8Peer");
  1264. lpVtbl = &DN_PeerVtbl;
  1265. }
  1266. #ifndef DPNBUILD_NOMULTICAST
  1267. else if (IsEqualIID(riid,IID_IDirectPlay8Multicast) &&
  1268. pdnObject->dwFlags & DN_OBJECT_FLAG_MULTICAST )
  1269. {
  1270. DPFX(DPFPREP, 7,"riid = IID_IDirectPlay8Multicast");
  1271. lpVtbl = &DNMcast_Vtbl;
  1272. }
  1273. #endif // DPNBUILD_NOMULTICAST
  1274. else
  1275. {
  1276. DPFERR("riid not found !");
  1277. hResultCode = E_NOINTERFACE;
  1278. goto Exit;
  1279. }
  1280. if ((pIntNew = static_cast<INTERFACE_LIST*>(DNMalloc(sizeof(INTERFACE_LIST)))) == NULL)
  1281. {
  1282. DPFERR("Could not allocate interface");
  1283. hResultCode = E_OUTOFMEMORY;
  1284. goto Exit;
  1285. }
  1286. pIntNew->lpVtbl = lpVtbl;
  1287. pIntNew->lRefCount = 0;
  1288. pIntNew->pIntNext = NULL;
  1289. DBG_CASSERT( sizeof( pIntNew->iid ) == sizeof( riid ) );
  1290. memcpy( &(pIntNew->iid), &riid, sizeof( pIntNew->iid ) );
  1291. pIntNew->pObject = pObject;
  1292. *ppv = pIntNew;
  1293. DPFX(DPFPREP, 7,"*ppv = [0x%p]",*ppv);
  1294. hResultCode = S_OK;
  1295. Exit:
  1296. DPFX(DPFPREP, 6,"Returning: hResultCode = [%lx]",hResultCode);
  1297. return(hResultCode);
  1298. }
  1299. #undef DPF_MODNAME
  1300. #define DPF_MODNAME "DN_FindInterface"
  1301. INTERFACE_LIST *DN_FindInterface(void *pInterface,
  1302. REFIID riid)
  1303. {
  1304. INTERFACE_LIST *pIntList;
  1305. DPFX(DPFPREP, 6,"Parameters: pInterface [%p], riid [%p]",pInterface,&riid);
  1306. DNASSERT(pInterface != NULL);
  1307. pIntList = (static_cast<INTERFACE_LIST*>(pInterface))->pObject->pIntList; // Find first interface
  1308. while (pIntList != NULL)
  1309. {
  1310. if (IsEqualIID(riid,pIntList->iid))
  1311. break;
  1312. pIntList = pIntList->pIntNext;
  1313. }
  1314. DPFX(DPFPREP, 6,"Returning: pIntList [0x%p]",pIntList);
  1315. return(pIntList);
  1316. }
  1317. #undef DPF_MODNAME
  1318. #define DPF_MODNAME "DN_QueryInterface"
  1319. STDMETHODIMP DN_QueryInterface(void *pInterface,
  1320. DP8REFIID riid,
  1321. void **ppv)
  1322. {
  1323. INTERFACE_LIST *pIntList;
  1324. INTERFACE_LIST *pIntNew;
  1325. HRESULT hResultCode;
  1326. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p], riid [0x%p], ppv [0x%p]",pInterface,&riid,ppv);
  1327. #ifndef DPNBUILD_NOPARAMVAL
  1328. if (pInterface == NULL)
  1329. {
  1330. DPFERR("Invalid COM interface specified");
  1331. hResultCode = E_INVALIDARG;
  1332. goto Exit;
  1333. }
  1334. if (ppv == NULL)
  1335. {
  1336. DPFERR("Invalid target interface pointer specified");
  1337. hResultCode = E_POINTER;
  1338. goto Exit;
  1339. }
  1340. #endif // ! DPNBUILD_NOPARAMVAL
  1341. if ((pIntList = DN_FindInterface(pInterface,riid)) == NULL)
  1342. { // Interface must be created
  1343. pIntList = (static_cast<INTERFACE_LIST*>(pInterface))->pObject->pIntList;
  1344. if ((hResultCode = DN_CreateInterface(pIntList->pObject,riid,&pIntNew)) != S_OK)
  1345. {
  1346. goto Exit;
  1347. }
  1348. pIntNew->pIntNext = pIntList;
  1349. pIntList->pObject->pIntList = pIntNew;
  1350. pIntList = pIntNew;
  1351. }
  1352. if (pIntList->lRefCount == 0) // New interface exposed
  1353. {
  1354. DNInterlockedIncrement( &pIntList->pObject->lRefCount );
  1355. }
  1356. DNInterlockedIncrement( &pIntList->lRefCount );
  1357. *ppv = static_cast<void*>(pIntList);
  1358. DPFX(DPFPREP, 5,"*ppv = [0x%p]", *ppv);
  1359. hResultCode = S_OK;
  1360. Exit:
  1361. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  1362. return(hResultCode);
  1363. }
  1364. #undef DPF_MODNAME
  1365. #define DPF_MODNAME "DN_AddRef"
  1366. STDMETHODIMP_(ULONG) DN_AddRef(void *pInterface)
  1367. {
  1368. INTERFACE_LIST *pIntList;
  1369. LONG lRefCount;
  1370. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p]",pInterface);
  1371. #ifndef DPNBUILD_NOPARAMVAL
  1372. if (pInterface == NULL)
  1373. {
  1374. DPFERR("Invalid COM interface specified");
  1375. lRefCount = 0;
  1376. goto Exit;
  1377. }
  1378. #endif // ! DPNBUILD_NOPARAMVAL
  1379. pIntList = static_cast<INTERFACE_LIST*>(pInterface);
  1380. lRefCount = DNInterlockedIncrement( &pIntList->lRefCount );
  1381. DPFX(DPFPREP, 5,"New lRefCount [%ld]",lRefCount);
  1382. #ifndef DPNBUILD_NOPARAMVAL
  1383. Exit:
  1384. #endif // ! DPNBUILD_NOPARAMVAL
  1385. DPFX(DPFPREP, 2,"Returning: lRefCount [%ld]",lRefCount);
  1386. return(lRefCount);
  1387. }
  1388. #undef DPF_MODNAME
  1389. #define DPF_MODNAME "DN_Release"
  1390. STDMETHODIMP_(ULONG) DN_Release(void *pInterface)
  1391. {
  1392. INTERFACE_LIST *pIntList;
  1393. INTERFACE_LIST *pIntCurrent;
  1394. LONG lRefCount;
  1395. LONG lObjRefCount;
  1396. DPFX(DPFPREP, 2,"Parameters: pInterface [%p]",pInterface);
  1397. #ifndef DPNBUILD_NOPARAMVAL
  1398. if (pInterface == NULL)
  1399. {
  1400. DPFERR("Invalid COM interface specified");
  1401. lRefCount = 0;
  1402. goto Exit;
  1403. }
  1404. #endif // ! DPNBUILD_NOPARAMVAL
  1405. pIntList = static_cast<INTERFACE_LIST*>(pInterface);
  1406. lRefCount = DNInterlockedDecrement( &pIntList->lRefCount );
  1407. DPFX(DPFPREP, 5,"New lRefCount [%ld]",lRefCount);
  1408. if (lRefCount == 0)
  1409. {
  1410. //
  1411. // Decrease object's interface count
  1412. //
  1413. lObjRefCount = DNInterlockedDecrement( &pIntList->pObject->lRefCount );
  1414. //
  1415. // Free object and interfaces
  1416. //
  1417. if (lObjRefCount == 0)
  1418. {
  1419. //
  1420. // Ensure we're properly closed
  1421. //
  1422. DN_Close(pInterface, 0);
  1423. // Free object here
  1424. DPFX(DPFPREP, 5,"Free object");
  1425. DNCF_FreeObject(pIntList->pObject->pvData);
  1426. pIntList = pIntList->pObject->pIntList; // Get head of interface list
  1427. DNFree(pIntList->pObject);
  1428. // Free Interfaces
  1429. DPFX(DPFPREP, 5,"Free interfaces");
  1430. while(pIntList != NULL)
  1431. {
  1432. pIntCurrent = pIntList;
  1433. pIntList = pIntList->pIntNext;
  1434. DNFree(pIntCurrent);
  1435. }
  1436. DNInterlockedDecrement(&g_lCoreObjectCount);
  1437. }
  1438. }
  1439. #ifndef DPNBUILD_NOPARAMVAL
  1440. Exit:
  1441. #endif // ! DPNBUILD_NOPARAMVAL
  1442. DPFX(DPFPREP, 2,"Returning: lRefCount [%ld]",lRefCount);
  1443. return(lRefCount);
  1444. }
  1445. #endif // ! DPNBUILD_LIBINTERFACE