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.

1524 lines
41 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 2001 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: spcallbackobj.cpp
  6. *
  7. * Content: DP8SIM callback interface object class.
  8. *
  9. * History:
  10. * Date By Reason
  11. * ======== ======== =========
  12. * 04/23/01 VanceO Created.
  13. *
  14. ***************************************************************************/
  15. #include "dp8simi.h"
  16. #undef DPF_MODNAME
  17. #define DPF_MODNAME "CDP8SimCB::CDP8SimCB"
  18. //=============================================================================
  19. // CDP8SimCB constructor
  20. //-----------------------------------------------------------------------------
  21. //
  22. // Description: Initializes the new CDP8SimCB object.
  23. //
  24. // Arguments:
  25. // CDP8SimSP * pOwningDP8SimSP - Pointer to owning CDP8SimSP object.
  26. // IDP8SPCallback * pDP8SPCB - Pointer to real DPlay callback interface
  27. // being intercepted.
  28. //
  29. // Returns: None (the object).
  30. //=============================================================================
  31. CDP8SimCB::CDP8SimCB(CDP8SimSP * pOwningDP8SimSP, IDP8SPCallback * pDP8SPCB)
  32. {
  33. this->m_Sig[0] = 'S';
  34. this->m_Sig[1] = 'P';
  35. this->m_Sig[2] = 'C';
  36. this->m_Sig[3] = 'B';
  37. this->m_lRefCount = 1; // someone must have a pointer to this object
  38. pOwningDP8SimSP->AddRef();
  39. this->m_pOwningDP8SimSP = pOwningDP8SimSP;
  40. pDP8SPCB->AddRef();
  41. this->m_pDP8SPCB = pDP8SPCB;
  42. } // CDP8SimCB::CDP8SimCB
  43. #undef DPF_MODNAME
  44. #define DPF_MODNAME "CDP8SimCB::~CDP8SimCB"
  45. //=============================================================================
  46. // CDP8SimCB destructor
  47. //-----------------------------------------------------------------------------
  48. //
  49. // Description: Frees the CDP8SimCB object.
  50. //
  51. // Arguments: None.
  52. //
  53. // Returns: None.
  54. //=============================================================================
  55. CDP8SimCB::~CDP8SimCB(void)
  56. {
  57. DNASSERT(this->m_lRefCount == 0);
  58. this->m_pOwningDP8SimSP->Release();
  59. this->m_pOwningDP8SimSP = NULL;
  60. this->m_pDP8SPCB->Release();
  61. this->m_pDP8SPCB = NULL;
  62. //
  63. // For grins, change the signature before deleting the object.
  64. //
  65. this->m_Sig[3] = 'b';
  66. } // CDP8SimCB::~CDP8SimCB
  67. #undef DPF_MODNAME
  68. #define DPF_MODNAME "CDP8SimCB::QueryInterface"
  69. //=============================================================================
  70. // CDP8SimCB::QueryInterface
  71. //-----------------------------------------------------------------------------
  72. //
  73. // Description: Retrieves a new reference for an interfaces supported by this
  74. // CDP8SimCB object.
  75. //
  76. // Arguments:
  77. // REFIID riid - Reference to interface ID GUID.
  78. // LPVOID * ppvObj - Place to store pointer to object.
  79. //
  80. // Returns: HRESULT
  81. // S_OK - Returning a valid interface pointer.
  82. // DPNHERR_INVALIDOBJECT - The interface object is invalid.
  83. // DPNHERR_INVALIDPOINTER - The destination pointer is invalid.
  84. // E_NOINTERFACE - Invalid interface was specified.
  85. //=============================================================================
  86. STDMETHODIMP CDP8SimCB::QueryInterface(REFIID riid, LPVOID * ppvObj)
  87. {
  88. HRESULT hr = DPN_OK;
  89. DPFX(DPFPREP, 3, "(0x%p) Parameters: (REFIID, 0x%p)", this, ppvObj);
  90. //
  91. // Validate the object.
  92. //
  93. if (! this->IsValidObject())
  94. {
  95. DPFX(DPFPREP, 0, "Invalid DP8Sim object!");
  96. hr = DPNERR_INVALIDOBJECT;
  97. goto Failure;
  98. }
  99. //
  100. // Validate the parameters.
  101. //
  102. if ((! IsEqualIID(riid, IID_IUnknown)) &&
  103. (! IsEqualIID(riid, IID_IDP8SPCallback)))
  104. {
  105. DPFX(DPFPREP, 0, "Unsupported interface!");
  106. hr = E_NOINTERFACE;
  107. goto Failure;
  108. }
  109. if ((ppvObj == NULL) ||
  110. (IsBadWritePtr(ppvObj, sizeof(void*))))
  111. {
  112. DPFX(DPFPREP, 0, "Invalid interface pointer specified!");
  113. hr = DPNERR_INVALIDPOINTER;
  114. goto Failure;
  115. }
  116. //
  117. // Add a reference, and return the interface pointer (which is actually
  118. // just the object pointer, they line up because CDP8SimCB inherits from
  119. // the interface declaration).
  120. //
  121. this->AddRef();
  122. (*ppvObj) = this;
  123. Exit:
  124. DPFX(DPFPREP, 3, "(0x%p) Returning: [0x%lx]", this, hr);
  125. return hr;
  126. Failure:
  127. goto Exit;
  128. } // CDP8SimCB::QueryInterface
  129. #undef DPF_MODNAME
  130. #define DPF_MODNAME "CDP8SimCB::AddRef"
  131. //=============================================================================
  132. // CDP8SimCB::AddRef
  133. //-----------------------------------------------------------------------------
  134. //
  135. // Description: Adds a reference to this CDP8SimCB object.
  136. //
  137. // Arguments: None.
  138. //
  139. // Returns: New refcount.
  140. //=============================================================================
  141. STDMETHODIMP_(ULONG) CDP8SimCB::AddRef(void)
  142. {
  143. LONG lRefCount;
  144. DNASSERT(this->IsValidObject());
  145. //
  146. // There must be at least 1 reference to this object, since someone is
  147. // calling AddRef.
  148. //
  149. DNASSERT(this->m_lRefCount > 0);
  150. lRefCount = InterlockedIncrement(&this->m_lRefCount);
  151. DPFX(DPFPREP, 3, "[0x%p] RefCount [0x%lx]", this, lRefCount);
  152. return lRefCount;
  153. } // CDP8SimCB::AddRef
  154. #undef DPF_MODNAME
  155. #define DPF_MODNAME "CDP8SimCB::Release"
  156. //=============================================================================
  157. // CDP8SimCB::Release
  158. //-----------------------------------------------------------------------------
  159. //
  160. // Description: Removes a reference to this CDP8SimCB object. When the
  161. // refcount reaches 0, this object is destroyed.
  162. // You must NULL out your pointer to this object after calling
  163. // this function.
  164. //
  165. // Arguments: None.
  166. //
  167. // Returns: New refcount.
  168. //=============================================================================
  169. STDMETHODIMP_(ULONG) CDP8SimCB::Release(void)
  170. {
  171. LONG lRefCount;
  172. DNASSERT(this->IsValidObject());
  173. //
  174. // There must be at least 1 reference to this object, since someone is
  175. // calling Release.
  176. //
  177. DNASSERT(this->m_lRefCount > 0);
  178. lRefCount = InterlockedDecrement(&this->m_lRefCount);
  179. //
  180. // Was that the last reference? If so, we're going to destroy this object.
  181. //
  182. if (lRefCount == 0)
  183. {
  184. DPFX(DPFPREP, 3, "[0x%p] RefCount hit 0, destroying object.", this);
  185. //
  186. // Uninitialize the object.
  187. //
  188. this->UninitializeObject();
  189. //
  190. // Finally delete this (!) object.
  191. //
  192. delete this;
  193. }
  194. else
  195. {
  196. DPFX(DPFPREP, 3, "[0x%p] RefCount [0x%lx]", this, lRefCount);
  197. }
  198. return lRefCount;
  199. } // CDP8SimCB::Release
  200. #undef DPF_MODNAME
  201. #define DPF_MODNAME "CDP8SimCB::IndicateEvent"
  202. //=============================================================================
  203. // CDP8SimCB::IndicateEvent
  204. //-----------------------------------------------------------------------------
  205. //
  206. // Description: ?
  207. //
  208. // Arguments:
  209. // SP_EVENT_TYPE EventType - Event being indicated.
  210. // PVOID pvMessage - Event specific message.
  211. //
  212. // Returns: HRESULT
  213. //=============================================================================
  214. STDMETHODIMP CDP8SimCB::IndicateEvent(SP_EVENT_TYPE EventType, PVOID pvMessage)
  215. {
  216. HRESULT hr;
  217. CDP8SimEndpoint * pDP8SimEndpoint;
  218. CDP8SimCommand * pDP8SimCommand;
  219. DPFX(DPFPREP, 2, "(0x%p) Parameters: (%u, 0x%p)", this, EventType, pvMessage);
  220. //
  221. // Validate (actually assert) the object.
  222. //
  223. DNASSERT(this->IsValidObject());
  224. //
  225. // Switch on the type of event being indicated.
  226. //
  227. switch (EventType)
  228. {
  229. case SPEV_DATA:
  230. {
  231. SPIE_DATA * pData;
  232. DP8SIM_PARAMETERS dp8sp;
  233. SPIE_DATA DataModified;
  234. CDP8SimReceive * pDP8SimReceive;
  235. DWORD dwBandwidthDelay;
  236. DWORD dwLatencyDelay;
  237. pData = (SPIE_DATA*) pvMessage;
  238. DNASSERT(pData->pReceivedData->pNext == NULL);
  239. pDP8SimEndpoint = (CDP8SimEndpoint*) pData->pEndpointContext;
  240. DNASSERT(pDP8SimEndpoint->IsValidObject());
  241. //
  242. // If the endpoint is disconnecting, drop the receive.
  243. //
  244. pDP8SimEndpoint->Lock();
  245. if (pDP8SimEndpoint->IsDisconnecting())
  246. {
  247. pDP8SimEndpoint->Unlock();
  248. DPFX(DPFPREP, 1, "Endpoint 0x%p is disconnecting, dropping receive.",
  249. pDP8SimEndpoint);
  250. hr = DPN_OK;
  251. }
  252. else
  253. {
  254. pDP8SimEndpoint->Unlock();
  255. //
  256. // Get the current receive settings.
  257. //
  258. ZeroMemory(&dp8sp, sizeof(dp8sp));
  259. dp8sp.dwSize = sizeof(dp8sp);
  260. this->m_pOwningDP8SimSP->GetAllReceiveParameters(&dp8sp);
  261. //
  262. // Determine if we need to drop this receive.
  263. //
  264. if (this->m_pOwningDP8SimSP->ShouldDrop(dp8sp.fPacketLossPercent))
  265. {
  266. DPFX(DPFPREP, 2, "Dropping %u bytes of data from endpoint 0x%p.",
  267. pData->pReceivedData->BufferDesc.dwBufferSize, pDP8SimEndpoint);
  268. //
  269. // Update the statistics.
  270. //
  271. this->m_pOwningDP8SimSP->IncrementStatsReceiveDropped(pData->pReceivedData->BufferDesc.dwBufferSize);
  272. //
  273. // Let the SP reclaim the buffer.
  274. //
  275. hr = DPN_OK;
  276. }
  277. else
  278. {
  279. //
  280. // Figure out how much latency needs to be added based on
  281. // the bandwidth and random latency settings.
  282. //
  283. // If we're not supposed to delay the receives, indicate it
  284. // now. Otherwise submit a timed job to be performed
  285. // later.
  286. //
  287. if (! this->m_pOwningDP8SimSP->GetDelay(dp8sp.dwBandwidthBPS,
  288. dp8sp.dwPacketHeaderSize,
  289. pData->pReceivedData->BufferDesc.dwBufferSize,
  290. dp8sp.dwMinLatencyMS,
  291. dp8sp.dwMaxLatencyMS,
  292. &dwBandwidthDelay,
  293. &dwLatencyDelay))
  294. {
  295. //
  296. // Modify the message before indicating to the caller.
  297. //
  298. ZeroMemory(&DataModified, sizeof(DataModified));
  299. DataModified.hEndpoint = (HANDLE) pDP8SimEndpoint;
  300. DataModified.pEndpointContext = pDP8SimEndpoint->GetUserContext();
  301. DataModified.pReceivedData = pData->pReceivedData;
  302. //
  303. // Indicate the event to the real callback interface.
  304. //
  305. DPFX(DPFPREP, 2, "Indicating event SPEV_DATA (message = 0x%p, data size = %u) to interface 0x%p.",
  306. pData, pData->pReceivedData->BufferDesc.dwBufferSize,
  307. this->m_pDP8SPCB);
  308. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_DATA, &DataModified);
  309. DPFX(DPFPREP, 2, "Returning from event SPEV_DATA [0x%lx].", hr);
  310. //
  311. // Update the statistics.
  312. //
  313. this->m_pOwningDP8SimSP->IncrementStatsReceiveTransmitted(pData->pReceivedData->BufferDesc.dwBufferSize,
  314. 0);
  315. }
  316. else
  317. {
  318. DPFX(DPFPREP, 6, "Delaying %u byte receive for %u + %u ms.",
  319. pData->pReceivedData->BufferDesc.dwBufferSize,
  320. dwBandwidthDelay, dwLatencyDelay);
  321. //
  322. // Get a receive object, duplicating the received data
  323. // structure given to us by our caller for indication
  324. // some time in the future.
  325. //
  326. pDP8SimReceive = (CDP8SimReceive*)g_FPOOLReceive.Get(pData);
  327. if (pDP8SimReceive == NULL)
  328. {
  329. hr = DPNERR_OUTOFMEMORY;
  330. }
  331. else
  332. {
  333. DPFX(DPFPREP, 7, "New delayed receive 0x%p.", pDP8SimReceive);
  334. //
  335. // Store the latency that is about be added to this
  336. // receive.
  337. //
  338. pDP8SimReceive->SetLatencyAdded(dwBandwidthDelay + dwLatencyDelay);
  339. //
  340. // Transfer local pDP8SimReceive reference to the
  341. // job queue.
  342. //
  343. //
  344. // Increment the receive counter.
  345. //
  346. this->m_pOwningDP8SimSP->IncReceivesPending();
  347. //
  348. // Queue it to be indicated at a later time,
  349. // depending on the latency value requested. If
  350. // there's a bandwidth restriction, enforce the
  351. // receiving order as well so that earlier messages
  352. // that are still pending hold up later ones.
  353. //
  354. hr = AddWorkerJob(DP8SIMJOBTYPE_DELAYEDRECEIVE,
  355. pDP8SimReceive,
  356. this->m_pOwningDP8SimSP,
  357. dwBandwidthDelay,
  358. dwLatencyDelay,
  359. DP8SIMJOBFLAG_PERFORMBLOCKINGPHASELAST);
  360. if (hr != DPN_OK)
  361. {
  362. DPFX(DPFPREP, 0, "Couldn't add delayed receive worker job (0x%p)!",
  363. pDP8SimReceive);
  364. //
  365. // Remove the receive counter.
  366. //
  367. this->m_pOwningDP8SimSP->DecReceivesPending();
  368. //
  369. // Release the delayed receive reference.
  370. //
  371. DPFX(DPFPREP, 7, "Releasing aborted delayed receive 0x%p.", pDP8SimReceive);
  372. pDP8SimReceive->Release();
  373. pDP8SimReceive = NULL;
  374. }
  375. else
  376. {
  377. //
  378. // Let the real SP know that we're keeping the
  379. // buffer.
  380. //
  381. hr = DPNSUCCESS_PENDING;
  382. }
  383. } // end else (successfully got receive object)
  384. } // end else (delaying receives)
  385. } // end else (not dropping receive)
  386. } // end else (endpoint is not disconnecting yet)
  387. break;
  388. }
  389. case SPEV_CONNECT:
  390. {
  391. SPIE_CONNECT * pConnect;
  392. SPIE_CONNECT ConnectModified;
  393. pConnect = (SPIE_CONNECT*) pvMessage;
  394. pDP8SimCommand = (CDP8SimCommand*) pConnect->pCommandContext;
  395. DNASSERT(pDP8SimCommand->IsValidObject());
  396. DNASSERT((pDP8SimCommand->GetType() == CMDTYPE_CONNECT) || (pDP8SimCommand->GetType() == CMDTYPE_LISTEN));
  397. //
  398. // Get a new endpoint object from the pool.
  399. //
  400. pDP8SimEndpoint = (CDP8SimEndpoint*)g_FPOOLEndpoint.Get(pConnect->hEndpoint);
  401. if (pDP8SimEndpoint == NULL)
  402. {
  403. hr = DPNERR_OUTOFMEMORY;
  404. }
  405. else
  406. {
  407. DPFX(DPFPREP, 7, "New %s endpoint 0x%p.",
  408. ((pDP8SimCommand->GetType() == CMDTYPE_CONNECT) ? _T("outbound") : _T("inbound")),
  409. pDP8SimEndpoint);
  410. //
  411. // Modify the message before indicating to the caller.
  412. //
  413. ZeroMemory(&ConnectModified, sizeof(ConnectModified));
  414. ConnectModified.hEndpoint = (HANDLE) pDP8SimEndpoint;
  415. //ConnectModified.pEndpointContext = NULL; // the user fills this in
  416. ConnectModified.pCommandContext = pDP8SimCommand->GetUserContext();
  417. //
  418. // Indicate the event to the real callback interface.
  419. //
  420. DPFX(DPFPREP, 2, "Indicating event SPEV_CONNECT (message = 0x%p) to interface 0x%p.",
  421. &ConnectModified, this->m_pDP8SPCB);
  422. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_CONNECT, &ConnectModified);
  423. DPFX(DPFPREP, 2, "Returning from event SPEV_CONNECT [0x%lx].", hr);
  424. if (hr == DPN_OK)
  425. {
  426. //
  427. // Update the endpoint context with what the user returned.
  428. //
  429. pDP8SimEndpoint->SetUserContext(ConnectModified.pEndpointContext);
  430. //
  431. // Return our endpoint context.
  432. //
  433. pConnect->pEndpointContext = pDP8SimEndpoint;
  434. }
  435. else
  436. {
  437. //
  438. // Release the endpoint reference.
  439. //
  440. DPFX(DPFPREP, 7, "Releasing aborted endpoint 0x%p.", pDP8SimEndpoint);
  441. pDP8SimEndpoint->Release();
  442. pDP8SimEndpoint = NULL;
  443. }
  444. }
  445. break;
  446. }
  447. case SPEV_DISCONNECT:
  448. {
  449. SPIE_DISCONNECT * pDisconnect;
  450. SPIE_DISCONNECT DisconnectModified;
  451. pDisconnect = (SPIE_DISCONNECT*) pvMessage;
  452. pDP8SimEndpoint = (CDP8SimEndpoint*) pDisconnect->pEndpointContext;
  453. DNASSERT(pDP8SimEndpoint->IsValidObject());
  454. //
  455. // Mark the endpoint as disconnecting to prevent additional sends
  456. // or receives.
  457. //
  458. pDP8SimEndpoint->Lock();
  459. pDP8SimEndpoint->NoteDisconnecting();
  460. pDP8SimEndpoint->Unlock();
  461. //
  462. // Modify the message before indicating to the caller.
  463. //
  464. ZeroMemory(&DisconnectModified, sizeof(DisconnectModified));
  465. DisconnectModified.hEndpoint = (HANDLE) pDP8SimEndpoint;
  466. DisconnectModified.pEndpointContext = pDP8SimEndpoint->GetUserContext();
  467. //
  468. // Quickly indicate any delayed receives from this endpoint that
  469. // are still pending.
  470. //
  471. FlushAllDelayedReceivesFromEndpoint(pDP8SimEndpoint, FALSE);
  472. //
  473. // Kill off any delayed sends that would have gone to this
  474. // endpoint.
  475. //
  476. FlushAllDelayedSendsToEndpoint(pDP8SimEndpoint, TRUE);
  477. //
  478. // Indicate the event to the real callback interface.
  479. //
  480. DPFX(DPFPREP, 2, "Indicating event SPEV_DISCONNECT (message = 0x%p) to interface 0x%p.",
  481. &DisconnectModified, this->m_pDP8SPCB);
  482. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_DISCONNECT, &DisconnectModified);
  483. DPFX(DPFPREP, 2, "Returning from event SPEV_DISCONNECT [0x%lx].", hr);
  484. //
  485. // Release the endpoint reference.
  486. //
  487. DPFX(DPFPREP, 7, "Releasing endpoint 0x%p.", pDP8SimEndpoint);
  488. pDP8SimEndpoint->Release();
  489. pDP8SimEndpoint = NULL;
  490. break;
  491. }
  492. case SPEV_LISTENSTATUS:
  493. {
  494. SPIE_LISTENSTATUS * pListenStatus;
  495. SPIE_LISTENSTATUS ListenStatusModified;
  496. pListenStatus = (SPIE_LISTENSTATUS*) pvMessage;
  497. pDP8SimCommand = (CDP8SimCommand*) pListenStatus->pUserContext;
  498. DNASSERT(pDP8SimCommand->IsValidObject());
  499. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_LISTEN);
  500. //
  501. // Get a new endpoint object from the pool.
  502. //
  503. pDP8SimEndpoint = (CDP8SimEndpoint*)g_FPOOLEndpoint.Get(pListenStatus->hEndpoint);
  504. if (pDP8SimEndpoint == NULL)
  505. {
  506. hr = DPNERR_OUTOFMEMORY;
  507. }
  508. else
  509. {
  510. DPFX(DPFPREP, 7, "New listen endpoint 0x%p, adding reference for listen command.",
  511. pDP8SimEndpoint);
  512. //
  513. // Store an endpoint reference with the command.
  514. //
  515. pDP8SimEndpoint->AddRef();
  516. pDP8SimCommand->SetListenEndpoint(pDP8SimEndpoint);
  517. //
  518. // Modify the message before indicating to the caller.
  519. //
  520. ZeroMemory(&ListenStatusModified, sizeof(ListenStatusModified));
  521. ListenStatusModified.ListenAdapter = pListenStatus->ListenAdapter;
  522. ListenStatusModified.hResult = pListenStatus->hResult;
  523. ListenStatusModified.hCommand = (HANDLE) pDP8SimCommand;
  524. ListenStatusModified.pUserContext = pDP8SimCommand->GetUserContext();
  525. ListenStatusModified.hEndpoint = (HANDLE) pDP8SimEndpoint;
  526. //
  527. // Indicate the event to the real callback interface.
  528. //
  529. DPFX(DPFPREP, 2, "Indicating event SPEV_LISTENSTATUS (message = 0x%p) to interface 0x%p.",
  530. &ListenStatusModified, this->m_pDP8SPCB);
  531. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_LISTENSTATUS, &ListenStatusModified);
  532. DPFX(DPFPREP, 2, "Returning from event SPEV_LISTENSTATUS [0x%lx].", hr);
  533. //
  534. // Release the reference we got from new, since we only needed
  535. // it while we indicated the endpoint up to the user. The
  536. // listen command object has the reference it needs.
  537. //
  538. DPFX(DPFPREP, 7, "Releasing local listen endpoint 0x%p reference.",
  539. pDP8SimEndpoint);
  540. pDP8SimEndpoint->Release();
  541. pDP8SimEndpoint = NULL;
  542. }
  543. break;
  544. }
  545. case SPEV_ENUMQUERY:
  546. {
  547. SPIE_QUERY * pQuery;
  548. ENUMQUERYDATAWRAPPER QueryWrapper;
  549. pQuery = (SPIE_QUERY*) pvMessage;
  550. DNASSERT(pQuery->pAddressSender != NULL);
  551. DNASSERT(pQuery->pAddressDevice != NULL);
  552. pDP8SimCommand = (CDP8SimCommand*) pQuery->pUserContext;
  553. DNASSERT(pDP8SimCommand->IsValidObject());
  554. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_LISTEN);
  555. //
  556. // Modify the message before indicating to the caller. We need a
  557. // wrapper so that ProxyEnumQuery can parse back out the original
  558. // query data pointer.
  559. //
  560. ZeroMemory(&QueryWrapper, sizeof(QueryWrapper));
  561. QueryWrapper.m_Sig[0] = 'E';
  562. QueryWrapper.m_Sig[1] = 'Q';
  563. QueryWrapper.m_Sig[2] = 'E';
  564. QueryWrapper.m_Sig[3] = 'W';
  565. QueryWrapper.pOriginalQuery = pQuery;
  566. hr = pQuery->pAddressSender->Duplicate(&QueryWrapper.QueryForUser.pAddressSender);
  567. if (hr != DPN_OK)
  568. {
  569. DPFX(DPFPREP, 0, "Couldn't duplicate enum query sender's address!");
  570. }
  571. else
  572. {
  573. hr = QueryWrapper.QueryForUser.pAddressSender->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  574. if (hr != DPN_OK)
  575. {
  576. DPFX(DPFPREP, 0, "Couldn't change enum query sender's address' SP!");
  577. }
  578. else
  579. {
  580. hr = pQuery->pAddressDevice->Duplicate(&QueryWrapper.QueryForUser.pAddressDevice);
  581. if (hr != DPN_OK)
  582. {
  583. DPFX(DPFPREP, 0, "Couldn't duplicate enum query device address!");
  584. }
  585. else
  586. {
  587. hr = QueryWrapper.QueryForUser.pAddressDevice->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  588. if (hr != DPN_OK)
  589. {
  590. DPFX(DPFPREP, 0, "Couldn't change enum query device address' SP!");
  591. }
  592. else
  593. {
  594. QueryWrapper.QueryForUser.pReceivedData = pQuery->pReceivedData;
  595. QueryWrapper.QueryForUser.pUserContext = pDP8SimCommand->GetUserContext();
  596. //
  597. // Indicate the event to the real callback interface.
  598. //
  599. DPFX(DPFPREP, 2, "Indicating SPEV_ENUMQUERY (message = 0x%p) to interface 0x%p.",
  600. &QueryWrapper.QueryForUser, this->m_pDP8SPCB);
  601. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_ENUMQUERY, &QueryWrapper.QueryForUser);
  602. DPFX(DPFPREP, 2, "Returning from SPEV_ENUMQUERY [0x%lx].", hr);
  603. }
  604. QueryWrapper.QueryForUser.pAddressDevice->Release();
  605. QueryWrapper.QueryForUser.pAddressDevice = NULL;
  606. }
  607. }
  608. QueryWrapper.QueryForUser.pAddressSender->Release();
  609. QueryWrapper.QueryForUser.pAddressSender = NULL;
  610. }
  611. break;
  612. }
  613. case SPEV_QUERYRESPONSE:
  614. {
  615. SPIE_QUERYRESPONSE * pQueryResponse;
  616. SPIE_QUERYRESPONSE QueryResponseModified;
  617. pQueryResponse = (SPIE_QUERYRESPONSE*) pvMessage;
  618. DNASSERT(pQueryResponse->pAddressSender != NULL);
  619. DNASSERT(pQueryResponse->pAddressDevice != NULL);
  620. pDP8SimCommand = (CDP8SimCommand*) pQueryResponse->pUserContext;
  621. DNASSERT(pDP8SimCommand->IsValidObject());
  622. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_ENUMQUERY);
  623. //
  624. // Modify the message before indicating to the caller.
  625. //
  626. ZeroMemory(&QueryResponseModified, sizeof(QueryResponseModified));
  627. hr = pQueryResponse->pAddressSender->Duplicate(&QueryResponseModified.pAddressSender);
  628. if (hr != DPN_OK)
  629. {
  630. DPFX(DPFPREP, 0, "Couldn't duplicate query response sender's address!");
  631. }
  632. else
  633. {
  634. hr = QueryResponseModified.pAddressSender->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  635. if (hr != DPN_OK)
  636. {
  637. DPFX(DPFPREP, 0, "Couldn't change query response sender's address' SP!");
  638. }
  639. else
  640. {
  641. hr = pQueryResponse->pAddressDevice->Duplicate(&QueryResponseModified.pAddressDevice);
  642. if (hr != DPN_OK)
  643. {
  644. DPFX(DPFPREP, 0, "Couldn't duplicate query response device address!");
  645. }
  646. else
  647. {
  648. hr = QueryResponseModified.pAddressDevice->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  649. if (hr != DPN_OK)
  650. {
  651. DPFX(DPFPREP, 0, "Couldn't change query response device address' SP!");
  652. }
  653. else
  654. {
  655. QueryResponseModified.pReceivedData = pQueryResponse->pReceivedData;
  656. QueryResponseModified.dwRoundTripTime = pQueryResponse->dwRoundTripTime;
  657. QueryResponseModified.pUserContext = pDP8SimCommand->GetUserContext();
  658. //
  659. // Indicate the event to the real callback interface.
  660. //
  661. DPFX(DPFPREP, 2, "Indicating SPEV_QUERYRESPONSE (message = 0x%p) to interface 0x%p.",
  662. &QueryResponseModified, this->m_pDP8SPCB);
  663. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_QUERYRESPONSE, &QueryResponseModified);
  664. DPFX(DPFPREP, 2, "Returning from SPEV_QUERYRESPONSE [0x%lx].", hr);
  665. }
  666. QueryResponseModified.pAddressDevice->Release();
  667. QueryResponseModified.pAddressDevice = NULL;
  668. }
  669. }
  670. QueryResponseModified.pAddressSender->Release();
  671. QueryResponseModified.pAddressSender = NULL;
  672. }
  673. break;
  674. }
  675. case SPEV_LISTENADDRESSINFO:
  676. {
  677. SPIE_LISTENADDRESSINFO * pListenAddressInfo;
  678. SPIE_LISTENADDRESSINFO ListenAddressInfoModified;
  679. pListenAddressInfo = (SPIE_LISTENADDRESSINFO*) pvMessage;
  680. DNASSERT(pListenAddressInfo->pDeviceAddress != NULL);
  681. pDP8SimCommand = (CDP8SimCommand*) pListenAddressInfo->pCommandContext;
  682. DNASSERT(pDP8SimCommand->IsValidObject());
  683. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_LISTEN);
  684. //
  685. // Modify the message before indicating to the caller.
  686. //
  687. ZeroMemory(&ListenAddressInfoModified, sizeof(ListenAddressInfoModified));
  688. hr = pListenAddressInfo->pDeviceAddress->Duplicate(&ListenAddressInfoModified.pDeviceAddress);
  689. if (hr != DPN_OK)
  690. {
  691. DPFX(DPFPREP, 0, "Couldn't duplicate listen address info device address!");
  692. }
  693. else
  694. {
  695. hr = ListenAddressInfoModified.pDeviceAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  696. if (hr != DPN_OK)
  697. {
  698. DPFX(DPFPREP, 0, "Couldn't change listen address info device address' SP!");
  699. }
  700. else
  701. {
  702. ListenAddressInfoModified.hCommandStatus = pListenAddressInfo->hCommandStatus;
  703. ListenAddressInfoModified.pCommandContext = pDP8SimCommand->GetUserContext();
  704. //
  705. // Indicate the event to the real callback interface.
  706. //
  707. DPFX(DPFPREP, 2, "Indicating SPEV_LISTENADDRESSINFO (message = 0x%p) to interface 0x%p.",
  708. &ListenAddressInfoModified, this->m_pDP8SPCB);
  709. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_LISTENADDRESSINFO, &ListenAddressInfoModified);
  710. DPFX(DPFPREP, 2, "Returning from SPEV_LISTENADDRESSINFO [0x%lx].", hr);
  711. }
  712. ListenAddressInfoModified.pDeviceAddress->Release();
  713. ListenAddressInfoModified.pDeviceAddress = NULL;
  714. }
  715. break;
  716. }
  717. case SPEV_ENUMADDRESSINFO:
  718. {
  719. SPIE_ENUMADDRESSINFO * pEnumAddressInfo;
  720. SPIE_ENUMADDRESSINFO EnumAddressInfoModified;
  721. pEnumAddressInfo = (SPIE_ENUMADDRESSINFO*) pvMessage;
  722. DNASSERT(pEnumAddressInfo->pHostAddress != NULL);
  723. DNASSERT(pEnumAddressInfo->pDeviceAddress != NULL);
  724. pDP8SimCommand = (CDP8SimCommand*) pEnumAddressInfo->pCommandContext;
  725. DNASSERT(pDP8SimCommand->IsValidObject());
  726. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_ENUMQUERY);
  727. //
  728. // Modify the message before indicating to the caller.
  729. //
  730. ZeroMemory(&EnumAddressInfoModified, sizeof(EnumAddressInfoModified));
  731. hr = pEnumAddressInfo->pHostAddress->Duplicate(&EnumAddressInfoModified.pHostAddress);
  732. if (hr != DPN_OK)
  733. {
  734. DPFX(DPFPREP, 0, "Couldn't duplicate enum address info host's address!");
  735. }
  736. else
  737. {
  738. hr = EnumAddressInfoModified.pHostAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  739. if (hr != DPN_OK)
  740. {
  741. DPFX(DPFPREP, 0, "Couldn't change enum address info host's address' SP!");
  742. }
  743. else
  744. {
  745. hr = pEnumAddressInfo->pDeviceAddress->Duplicate(&EnumAddressInfoModified.pDeviceAddress);
  746. if (hr != DPN_OK)
  747. {
  748. DPFX(DPFPREP, 0, "Couldn't duplicate enum address info device address!");
  749. }
  750. else
  751. {
  752. hr = EnumAddressInfoModified.pDeviceAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  753. if (hr != DPN_OK)
  754. {
  755. DPFX(DPFPREP, 0, "Couldn't change enum address info device address' SP!");
  756. }
  757. else
  758. {
  759. EnumAddressInfoModified.hCommandStatus = pEnumAddressInfo->hCommandStatus;
  760. EnumAddressInfoModified.pCommandContext = pDP8SimCommand->GetUserContext();
  761. //
  762. // Indicate the event to the real callback interface.
  763. //
  764. DPFX(DPFPREP, 2, "Indicating SPEV_ENUMADDRESSINFO (message = 0x%p) to interface 0x%p.",
  765. &EnumAddressInfoModified, this->m_pDP8SPCB);
  766. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_ENUMADDRESSINFO, &EnumAddressInfoModified);
  767. DPFX(DPFPREP, 2, "Returning from SPEV_ENUMADDRESSINFO [0x%lx].", hr);
  768. }
  769. EnumAddressInfoModified.pDeviceAddress->Release();
  770. EnumAddressInfoModified.pDeviceAddress = NULL;
  771. }
  772. }
  773. EnumAddressInfoModified.pHostAddress->Release();
  774. EnumAddressInfoModified.pHostAddress = NULL;
  775. }
  776. break;
  777. }
  778. case SPEV_CONNECTADDRESSINFO:
  779. {
  780. SPIE_CONNECTADDRESSINFO * pConnectAddressInfo;
  781. SPIE_CONNECTADDRESSINFO ConnectAddressInfoModified;
  782. pConnectAddressInfo = (SPIE_CONNECTADDRESSINFO*) pvMessage;
  783. DNASSERT(pConnectAddressInfo->pHostAddress != NULL);
  784. DNASSERT(pConnectAddressInfo->pDeviceAddress != NULL);
  785. pDP8SimCommand = (CDP8SimCommand*) pConnectAddressInfo->pCommandContext;
  786. DNASSERT(pDP8SimCommand->IsValidObject());
  787. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_CONNECT);
  788. //
  789. // Modify the message before indicating to the caller.
  790. //
  791. ZeroMemory(&ConnectAddressInfoModified, sizeof(ConnectAddressInfoModified));
  792. hr = pConnectAddressInfo->pHostAddress->Duplicate(&ConnectAddressInfoModified.pHostAddress);
  793. if (hr != DPN_OK)
  794. {
  795. DPFX(DPFPREP, 0, "Couldn't duplicate connect address info host's address!");
  796. }
  797. else
  798. {
  799. hr = ConnectAddressInfoModified.pHostAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  800. if (hr != DPN_OK)
  801. {
  802. DPFX(DPFPREP, 0, "Couldn't change connect address info host's address' SP!");
  803. }
  804. else
  805. {
  806. hr = pConnectAddressInfo->pDeviceAddress->Duplicate(&ConnectAddressInfoModified.pDeviceAddress);
  807. if (hr != DPN_OK)
  808. {
  809. DPFX(DPFPREP, 0, "Couldn't duplicate connect address info device address!");
  810. }
  811. else
  812. {
  813. hr = ConnectAddressInfoModified.pDeviceAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  814. if (hr != DPN_OK)
  815. {
  816. DPFX(DPFPREP, 0, "Couldn't change connect address info device address' SP!");
  817. }
  818. else
  819. {
  820. ConnectAddressInfoModified.hCommandStatus = pConnectAddressInfo->hCommandStatus;
  821. ConnectAddressInfoModified.pCommandContext = pDP8SimCommand->GetUserContext();
  822. //
  823. // Indicate the event to the real callback interface.
  824. //
  825. DPFX(DPFPREP, 2, "Indicating SPEV_CONNECTADDRESSINFO (message = 0x%p) to interface 0x%p.",
  826. &ConnectAddressInfoModified, this->m_pDP8SPCB);
  827. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_CONNECTADDRESSINFO, &ConnectAddressInfoModified);
  828. DPFX(DPFPREP, 2, "Returning from SPEV_CONNECTADDRESSINFO [0x%lx].", hr);
  829. }
  830. ConnectAddressInfoModified.pDeviceAddress->Release();
  831. ConnectAddressInfoModified.pDeviceAddress = NULL;
  832. }
  833. }
  834. ConnectAddressInfoModified.pHostAddress->Release();
  835. ConnectAddressInfoModified.pHostAddress = NULL;
  836. }
  837. break;
  838. }
  839. case SPEV_DATA_UNCONNECTED:
  840. {
  841. SPIE_DATA_UNCONNECTED * pDataUnconnected;
  842. SPIE_DATA_UNCONNECTED DataUnconnectedModified;
  843. pDataUnconnected = (SPIE_DATA_UNCONNECTED*) pvMessage;
  844. DNASSERT(pDataUnconnected->pvReplyBuffer != NULL);
  845. DNASSERT(pDataUnconnected->dwReplyBufferSize > 0);
  846. pDP8SimCommand = (CDP8SimCommand*) pDataUnconnected->pvListenCommandContext;
  847. DNASSERT(pDP8SimCommand->IsValidObject());
  848. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_LISTEN);
  849. //
  850. // Modify the message before indicating to the caller.
  851. //
  852. ZeroMemory(&DataUnconnectedModified, sizeof(DataUnconnectedModified));
  853. DataUnconnectedModified.pvListenCommandContext = pDP8SimCommand->GetUserContext();
  854. DataUnconnectedModified.pReceivedData = pDataUnconnected->pReceivedData;
  855. DataUnconnectedModified.dwSenderAddressHash = pDataUnconnected->dwSenderAddressHash;
  856. DataUnconnectedModified.pvReplyBuffer = pDataUnconnected->pvReplyBuffer;
  857. DataUnconnectedModified.dwReplyBufferSize = pDataUnconnected->dwReplyBufferSize;
  858. //
  859. // Indicate the event to the real callback interface.
  860. //
  861. DPFX(DPFPREP, 2, "Indicating event SPEV_DATA_UNCONNECTED (message = 0x%p) to interface 0x%p.",
  862. &DataUnconnectedModified, this->m_pDP8SPCB);
  863. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_DATA_UNCONNECTED, &DataUnconnectedModified);
  864. DPFX(DPFPREP, 2, "Returning from event SPEV_DATA_UNCONNECTED [0x%lx].", hr);
  865. if (hr == DPNSUCCESS_PENDING)
  866. {
  867. //
  868. // Update the reply buffer size with what the user returned.
  869. //
  870. DNASSERT(DataUnconnectedModified.dwReplyBufferSize > 0);
  871. DNASSERT(DataUnconnectedModified.dwReplyBufferSize <= pDataUnconnected->dwReplyBufferSize);
  872. pDataUnconnected->dwReplyBufferSize = DataUnconnectedModified.dwReplyBufferSize;
  873. }
  874. break;
  875. }
  876. #ifndef DPNBUILD_NOMULTICAST
  877. case SPEV_DATA_UNKNOWNSENDER:
  878. {
  879. SPIE_DATA_UNKNOWNSENDER * pDataUnknownSender;
  880. SPIE_DATA_UNKNOWNSENDER DataUnknownSenderModified;
  881. pDataUnknownSender = (SPIE_DATA_UNKNOWNSENDER*) pvMessage;
  882. DNASSERT(pDataUnknownSender->pSenderAddress != NULL);
  883. pDP8SimCommand = (CDP8SimCommand*) pDataUnknownSender->pvListenCommandContext;
  884. DNASSERT(pDP8SimCommand->IsValidObject());
  885. DNASSERT(pDP8SimCommand->GetType() == CMDTYPE_LISTEN);
  886. //
  887. // Modify the message before indicating to the caller.
  888. //
  889. ZeroMemory(&DataUnknownSenderModified, sizeof(DataUnknownSenderModified));
  890. hr = pDataUnknownSender->pSenderAddress->Duplicate(&DataUnknownSenderModified.pSenderAddress);
  891. if (hr != DPN_OK)
  892. {
  893. DPFX(DPFPREP, 0, "Couldn't duplicate listen address info device address!");
  894. }
  895. else
  896. {
  897. hr = DataUnknownSenderModified.pSenderAddress->SetSP(this->m_pOwningDP8SimSP->GetFakeSP());
  898. if (hr != DPN_OK)
  899. {
  900. DPFX(DPFPREP, 0, "Couldn't change listen address info device address' SP!");
  901. }
  902. else
  903. {
  904. DataUnknownSenderModified.pvListenCommandContext = pDP8SimCommand->GetUserContext();
  905. DataUnknownSenderModified.pReceivedData = pDataUnknownSender->pReceivedData;
  906. //
  907. // Indicate the event to the real callback interface.
  908. //
  909. DPFX(DPFPREP, 2, "Indicating SPEV_DATA_UNKNOWNSENDER (message = 0x%p) to interface 0x%p.",
  910. &DataUnknownSenderModified, this->m_pDP8SPCB);
  911. hr = this->m_pDP8SPCB->IndicateEvent(SPEV_DATA_UNKNOWNSENDER, &DataUnknownSenderModified);
  912. DPFX(DPFPREP, 2, "Returning from SPEV_DATA_UNKNOWNSENDER [0x%lx].", hr);
  913. }
  914. DataUnknownSenderModified.pSenderAddress->Release();
  915. DataUnknownSenderModified.pSenderAddress = NULL;
  916. }
  917. break;
  918. }
  919. #endif // ! DPNBUILD_NOMULTICAST
  920. default:
  921. {
  922. DPFX(DPFPREP, 0, "Unrecognized event type %u!", EventType);
  923. DNASSERT(FALSE);
  924. hr = E_NOTIMPL;
  925. break;
  926. }
  927. }
  928. DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
  929. return hr;
  930. } // CDP8SimCB::IndicateEvent
  931. #undef DPF_MODNAME
  932. #define DPF_MODNAME "CDP8SimCB::CommandComplete"
  933. //=============================================================================
  934. // CDP8SimCB::CommandComplete
  935. //-----------------------------------------------------------------------------
  936. //
  937. // Description: ?
  938. //
  939. // Arguments:
  940. // HANDLE hCommand - Handle of command that's completing.
  941. // HRESULT hrResult - Result code for completing operation.
  942. // PVOID pvContext - Pointer to user context for command.
  943. //
  944. // Returns: HRESULT
  945. //=============================================================================
  946. STDMETHODIMP CDP8SimCB::CommandComplete(HANDLE hCommand, HRESULT hrResult, PVOID pvContext)
  947. {
  948. HRESULT hr;
  949. CDP8SimCommand * pDP8SimCommand = (CDP8SimCommand*) pvContext;
  950. DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%lx, 0x%p)",
  951. this, hCommand, hrResult, pvContext);
  952. //
  953. // Validate (actually assert) the object.
  954. //
  955. DNASSERT(this->IsValidObject());
  956. //
  957. // Assert the parameters.
  958. //
  959. DNASSERT(pDP8SimCommand->IsValidObject());
  960. //
  961. // Switch on the command type.
  962. //
  963. switch (pDP8SimCommand->GetType())
  964. {
  965. case CMDTYPE_SENDDATA_IMMEDIATE:
  966. {
  967. //
  968. // Update the statistics.
  969. //
  970. if (hrResult == DPN_OK)
  971. {
  972. this->m_pOwningDP8SimSP->IncrementStatsSendTransmitted(pDP8SimCommand->GetMessageSize(),
  973. 0);
  974. }
  975. else
  976. {
  977. //
  978. // The send failed. Currently we don't track this.
  979. //
  980. }
  981. pDP8SimCommand->SetMessageSize(0);
  982. //
  983. // Indicate the completion to the real callback interface.
  984. //
  985. DPFX(DPFPREP, 2, "Indicating immediate send command 0x%p complete (result = 0x%lx, context = 0x%p) to interface 0x%p.",
  986. pDP8SimCommand, hrResult,
  987. pDP8SimCommand->GetUserContext(),
  988. this->m_pDP8SPCB);
  989. hr = this->m_pDP8SPCB->CommandComplete(pDP8SimCommand,
  990. hrResult,
  991. pDP8SimCommand->GetUserContext());
  992. DPFX(DPFPREP, 2, "Returning from command complete [0x%lx].", hr);
  993. //
  994. // Remove the send counter.
  995. //
  996. this->m_pOwningDP8SimSP->DecSendsPending();
  997. break;
  998. }
  999. case CMDTYPE_SENDDATA_DELAYED:
  1000. {
  1001. CDP8SimSend * pDP8SimSend;
  1002. //
  1003. // Handle the completion. It never gets indicated to the user
  1004. // though.
  1005. //
  1006. pDP8SimSend = (CDP8SimSend*) pDP8SimCommand->GetUserContext();
  1007. DNASSERT(pDP8SimSend->IsValidObject());
  1008. DPFX(DPFPREP, 5, "Send 0x%p (command 0x%p) completed.",
  1009. pDP8SimSend, pDP8SimCommand);
  1010. //
  1011. // Update the statistics.
  1012. //
  1013. if (hrResult == DPN_OK)
  1014. {
  1015. this->m_pOwningDP8SimSP->IncrementStatsSendTransmitted(pDP8SimSend->GetMessageSize(),
  1016. pDP8SimSend->GetLatencyAdded());
  1017. }
  1018. else
  1019. {
  1020. //
  1021. // The send failed. We don't truly track this, but since we
  1022. // already indicated a successful send to the user, we'll count
  1023. // it as a drop.
  1024. //
  1025. this->m_pOwningDP8SimSP->IncrementStatsSendDropped(pDP8SimSend->GetMessageSize());
  1026. }
  1027. //
  1028. // Remove the send counter.
  1029. //
  1030. this->m_pOwningDP8SimSP->DecSendsPending();
  1031. pDP8SimSend->Release();
  1032. pDP8SimSend = NULL;
  1033. hr = DPN_OK;
  1034. break;
  1035. }
  1036. case CMDTYPE_CONNECT:
  1037. case CMDTYPE_DISCONNECT:
  1038. case CMDTYPE_LISTEN:
  1039. case CMDTYPE_ENUMQUERY:
  1040. case CMDTYPE_ENUMRESPOND:
  1041. {
  1042. //
  1043. // Indicate the completion to the real callback interface.
  1044. //
  1045. DPFX(DPFPREP, 2, "Indicating command 0x%p complete (type = %u, result = 0x%lx, context = 0x%p) to interface 0x%p.",
  1046. pDP8SimCommand, pDP8SimCommand->GetType(), hrResult,
  1047. pDP8SimCommand->GetUserContext(), this->m_pDP8SPCB);
  1048. hr = this->m_pDP8SPCB->CommandComplete(pDP8SimCommand,
  1049. hrResult,
  1050. pDP8SimCommand->GetUserContext());
  1051. DPFX(DPFPREP, 2, "Returning from command complete [0x%lx].", hr);
  1052. //
  1053. // If this was a listen, we need to kill the listen endpoint.
  1054. //
  1055. if (pDP8SimCommand->GetType() == CMDTYPE_LISTEN)
  1056. {
  1057. CDP8SimEndpoint * pDP8SimEndpoint;
  1058. pDP8SimEndpoint = pDP8SimCommand->GetListenEndpoint();
  1059. DNASSERT(pDP8SimEndpoint != NULL);
  1060. pDP8SimCommand->SetListenEndpoint(NULL);
  1061. DPFX(DPFPREP, 7, "Releasing listen endpoint 0x%p.",
  1062. pDP8SimEndpoint);
  1063. pDP8SimEndpoint->Release();
  1064. pDP8SimEndpoint = NULL;
  1065. }
  1066. break;
  1067. }
  1068. default:
  1069. {
  1070. DPFX(DPFPREP, 0, "Unrecognized command type %u!", pDP8SimCommand->GetType());
  1071. DNASSERT(FALSE);
  1072. hr = E_NOTIMPL;
  1073. break;
  1074. }
  1075. }
  1076. //
  1077. // Destroy the object.
  1078. //
  1079. DPFX(DPFPREP, 7, "Releasing completed command 0x%p.", pDP8SimCommand);
  1080. pDP8SimCommand->Release();
  1081. pDP8SimCommand = NULL;
  1082. DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
  1083. return hr;
  1084. } // CDP8SimCB::CommandComplete
  1085. #undef DPF_MODNAME
  1086. #define DPF_MODNAME "CDP8SimCB::InitializeObject"
  1087. //=============================================================================
  1088. // CDP8SimCB::InitializeObject
  1089. //-----------------------------------------------------------------------------
  1090. //
  1091. // Description: Sets up the object for use like the constructor, but may
  1092. // fail with OUTOFMEMORY. Should only be called by class factory
  1093. // creation routine.
  1094. //
  1095. // Arguments: None.
  1096. //
  1097. // Returns: HRESULT
  1098. // S_OK - Initialization was successful.
  1099. // E_OUTOFMEMORY - There is not enough memory to initialize.
  1100. //=============================================================================
  1101. HRESULT CDP8SimCB::InitializeObject(void)
  1102. {
  1103. HRESULT hr;
  1104. DPFX(DPFPREP, 5, "(0x%p) Enter", this);
  1105. DNASSERT(this->IsValidObject());
  1106. //
  1107. // Create the lock.
  1108. //
  1109. if (! DNInitializeCriticalSection(&this->m_csLock))
  1110. {
  1111. hr = E_OUTOFMEMORY;
  1112. goto Failure;
  1113. }
  1114. //
  1115. // Don't allow critical section reentry.
  1116. //
  1117. DebugSetCriticalSectionRecursionCount(&this->m_csLock, 0);
  1118. hr = S_OK;
  1119. Exit:
  1120. DPFX(DPFPREP, 5, "(0x%p) Returning: [0x%lx]", this, hr);
  1121. return hr;
  1122. Failure:
  1123. goto Exit;
  1124. } // CDP8SimCB::InitializeObject
  1125. #undef DPF_MODNAME
  1126. #define DPF_MODNAME "CDP8SimCB::UninitializeObject"
  1127. //=============================================================================
  1128. // CDP8SimCB::UninitializeObject
  1129. //-----------------------------------------------------------------------------
  1130. //
  1131. // Description: Cleans up the object like the destructor, mostly to balance
  1132. // InitializeObject.
  1133. //
  1134. // Arguments: None.
  1135. //
  1136. // Returns: None.
  1137. //=============================================================================
  1138. void CDP8SimCB::UninitializeObject(void)
  1139. {
  1140. DPFX(DPFPREP, 5, "(0x%p) Enter", this);
  1141. DNASSERT(this->IsValidObject());
  1142. DNDeleteCriticalSection(&this->m_csLock);
  1143. DPFX(DPFPREP, 5, "(0x%p) Returning", this);
  1144. } // CDP8SimCB::UninitializeObject