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.

821 lines
20 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: NTEntry.cpp
  6. * Content: NameTable Entry Objects
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/10/00 mjn Created
  12. * 04/06/00 mjn Added AvailableEvent to block pre-ADD_PLAYER-notification sends
  13. * 05/05/00 mjn Added GetConnectionRef()
  14. * 05/16/00 mjn Better locking during User notifications
  15. * 06/27/00 rmt Added COM abstraction
  16. * 07/22/00 mjn Pack/Unpack DNET version in DN_NAMETABLE_ENTRY_INFO
  17. * 07/26/00 mjn Fix PackInfo() to handle NULL names and data
  18. * 08/03/00 rmt Bug #41386 - Getting player info when no name and/or user data returns garbage in
  19. * name / data field.
  20. * 09/06/00 mjn Changed SetAddress() to return void instead of HRESULT
  21. * 09/13/00 mjn Added PerformQueuedOperations()
  22. * 09/17/00 mjn Added NotifyAddRef() and NotifyRelease()
  23. * 09/28/00 mjn Flag AutoDestruct groups in PackInfo()
  24. * 10/11/00 mjn Don't take locks in PackInfo()
  25. * 01/25/01 mjn Fixed 64-bit alignment problem when unpacking entries
  26. * 04/19/01 mjn Lock entry when packing in PackEntryInfo()
  27. * 07/24/01 mjn Added DPNBUILD_NOSERVER compile flag
  28. *@@END_MSINTERNAL
  29. *
  30. ***************************************************************************/
  31. #include "dncorei.h"
  32. //**********************************************************************
  33. // Constant definitions
  34. //**********************************************************************
  35. //**********************************************************************
  36. // Macro definitions
  37. //**********************************************************************
  38. //**********************************************************************
  39. // Structure definitions
  40. //**********************************************************************
  41. //**********************************************************************
  42. // Variable definitions
  43. //**********************************************************************
  44. //**********************************************************************
  45. // Function prototypes
  46. //**********************************************************************
  47. //**********************************************************************
  48. // Function definitions
  49. //**********************************************************************
  50. void CNameTableEntry::ReturnSelfToPool( void )
  51. {
  52. g_NameTableEntryPool.Release( this );
  53. };
  54. #undef DPF_MODNAME
  55. #define DPF_MODNAME "CNameTableEntry::Release"
  56. void CNameTableEntry::Release(void)
  57. {
  58. LONG lRefCount;
  59. DNASSERT(m_lRefCount > 0);
  60. lRefCount = DNInterlockedDecrement(const_cast<LONG*>(&m_lRefCount));
  61. DPFX(DPFPREP, 3,"NameTableEntry::Release [0x%p] RefCount [0x%lx]",this,lRefCount);
  62. if (lRefCount == 0)
  63. {
  64. DNASSERT(!(m_dwFlags & NAMETABLE_ENTRY_FLAG_AVAILABLE));
  65. DNASSERT(m_bilinkDeleted.IsEmpty());
  66. DNASSERT(m_bilinkMembership.IsEmpty());
  67. DNASSERT(m_bilinkConnections.IsEmpty());
  68. DNASSERT(m_bilinkQueuedMsgs.IsEmpty());
  69. if (m_pAddress)
  70. {
  71. IDirectPlay8Address_Release(m_pAddress);
  72. m_pAddress = NULL;
  73. }
  74. if (m_pConnection)
  75. {
  76. m_pConnection->Release();
  77. m_pConnection = NULL;
  78. }
  79. if (m_pwszName)
  80. {
  81. DNFree(m_pwszName);
  82. m_pwszName = NULL;
  83. }
  84. if (m_pvData)
  85. {
  86. DNFree(m_pvData);
  87. m_pvData = NULL;
  88. m_dwDataSize = 0;
  89. }
  90. m_dwFlags = 0;
  91. m_lRefCount = 0;
  92. ReturnSelfToPool();
  93. }
  94. }
  95. #undef DPF_MODNAME
  96. #define DPF_MODNAME "CNameTableEntry::NotifyAddRef"
  97. void CNameTableEntry::NotifyAddRef( void )
  98. {
  99. LONG lRefCount;
  100. lRefCount = DNInterlockedIncrement( const_cast<LONG*>(&m_lNotifyRefCount) );
  101. DNASSERT( lRefCount >= 0 );
  102. }
  103. #undef DPF_MODNAME
  104. #define DPF_MODNAME "CNameTableEntry::NotifyRelease"
  105. void CNameTableEntry::NotifyRelease( void )
  106. {
  107. LONG lRefCount;
  108. lRefCount = DNInterlockedDecrement( const_cast<LONG*>(&m_lNotifyRefCount) );
  109. DNASSERT( lRefCount >= 0 );
  110. if (lRefCount == 0)
  111. {
  112. Lock();
  113. // DNASSERT(IsDisconnecting());
  114. if (IsNeedToDestroy())
  115. {
  116. Unlock();
  117. //
  118. // Generate notifications
  119. //
  120. if (IsGroup())
  121. {
  122. if (!IsAllPlayersGroup())
  123. {
  124. DNUserDestroyGroup(m_pdnObject,this);
  125. }
  126. }
  127. else
  128. {
  129. if (IsIndicated() && !IsCreated())
  130. {
  131. DNUserIndicatedConnectAborted(m_pdnObject,m_pvContext);
  132. }
  133. else
  134. {
  135. DNASSERT(IsCreated());
  136. DNUserDestroyPlayer(m_pdnObject,this);
  137. }
  138. }
  139. m_pdnObject->NameTable.WriteLock();
  140. Lock();
  141. m_bilinkDeleted.RemoveFromList();
  142. m_pdnObject->NameTable.Unlock();
  143. ClearNeedToDestroy();
  144. ClearCreated();
  145. }
  146. Unlock();
  147. }
  148. }
  149. #undef DPF_MODNAME
  150. #define DPF_MODNAME "CNameTableEntry::UpdateEntryInfo"
  151. HRESULT CNameTableEntry::UpdateEntryInfo(UNALIGNED WCHAR *const pwszName,
  152. const DWORD dwNameSize,
  153. void *const pvData,
  154. const DWORD dwDataSize,
  155. const DWORD dwInfoFlags,
  156. BOOL fNotify)
  157. {
  158. PWSTR pwszTempName;
  159. DWORD dwTempNameSize;
  160. void *pvTempData;
  161. DWORD dwTempDataSize;
  162. Lock();
  163. if (dwInfoFlags & DPNINFO_NAME)
  164. {
  165. if (pwszName && dwNameSize)
  166. {
  167. if ((pwszTempName = static_cast<WCHAR*>(DNMalloc(dwNameSize))) == NULL)
  168. {
  169. return(DPNERR_OUTOFMEMORY);
  170. }
  171. memcpy(pwszTempName,pwszName,dwNameSize);
  172. dwTempNameSize = dwNameSize;
  173. }
  174. else
  175. {
  176. pwszTempName = NULL;
  177. dwTempNameSize = 0;
  178. }
  179. if (m_pwszName)
  180. {
  181. DNFree(m_pwszName);
  182. }
  183. m_pwszName = pwszTempName;
  184. m_dwNameSize = dwTempNameSize;
  185. }
  186. if (dwInfoFlags & DPNINFO_DATA)
  187. {
  188. if (pvData && dwDataSize)
  189. {
  190. if ((pvTempData = DNMalloc(dwDataSize)) == NULL)
  191. {
  192. return(DPNERR_OUTOFMEMORY);
  193. }
  194. memcpy(pvTempData,pvData,dwDataSize);
  195. dwTempDataSize = dwDataSize;
  196. }
  197. else
  198. {
  199. pvTempData = NULL;
  200. dwTempDataSize = 0;
  201. }
  202. if (m_pvData)
  203. {
  204. DNFree(m_pvData);
  205. }
  206. m_pvData = pvTempData;
  207. m_dwDataSize = dwTempDataSize;
  208. }
  209. // Generate notifications
  210. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_AVAILABLE && fNotify)
  211. {
  212. DPNID dpnid = m_dpnid;
  213. PVOID pvContext = m_pvContext;
  214. DIRECTNETOBJECT* pdnObject = m_pdnObject;
  215. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_GROUP)
  216. {
  217. Unlock();
  218. DNUserUpdateGroupInfo(pdnObject,dpnid,pvContext);
  219. }
  220. else
  221. {
  222. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_PEER)
  223. {
  224. Unlock();
  225. DNUserUpdatePeerInfo(pdnObject,dpnid,pvContext);
  226. }
  227. #ifndef DPNBUILD_NOSERVER
  228. else if (m_dwFlags & NAMETABLE_ENTRY_FLAG_CLIENT && pdnObject->dwFlags & DN_OBJECT_FLAG_SERVER)
  229. {
  230. Unlock();
  231. DNUserUpdateClientInfo(pdnObject,dpnid,pvContext);
  232. }
  233. #endif // DPNBUILD_NOSERVER
  234. else if (m_dwFlags & NAMETABLE_ENTRY_FLAG_SERVER && pdnObject->dwFlags & DN_OBJECT_FLAG_CLIENT)
  235. {
  236. Unlock();
  237. // Clients do not get to see server's DPNID or context
  238. DNUserUpdateServerInfo(pdnObject,0,0);
  239. }
  240. else
  241. {
  242. Unlock();
  243. DNASSERT(FALSE);
  244. }
  245. }
  246. }
  247. else
  248. {
  249. Unlock();
  250. }
  251. return(DPN_OK);
  252. }
  253. #undef DPF_MODNAME
  254. #define DPF_MODNAME "CNameTableEntry::SetAddress"
  255. void CNameTableEntry::SetAddress( IDirectPlay8Address *const pAddress )
  256. {
  257. if (pAddress)
  258. {
  259. IDirectPlay8Address_AddRef(pAddress);
  260. }
  261. if (m_pAddress)
  262. {
  263. IDirectPlay8Address_Release(m_pAddress);
  264. m_pAddress = NULL;
  265. }
  266. m_pAddress = pAddress;
  267. }
  268. #undef DPF_MODNAME
  269. #define DPF_MODNAME "CNameTableEntry::SetConnection"
  270. void CNameTableEntry::SetConnection( CConnection *const pConnection )
  271. {
  272. if (pConnection)
  273. {
  274. pConnection->AddRef();
  275. }
  276. m_pConnection = pConnection;
  277. }
  278. #undef DPF_MODNAME
  279. #define DPF_MODNAME "CNameTableEntry::GetConnectionRef"
  280. HRESULT CNameTableEntry::GetConnectionRef( CConnection **const ppConnection )
  281. {
  282. HRESULT hResultCode;
  283. DNASSERT( ppConnection != NULL);
  284. Lock();
  285. if ( m_pConnection && !m_pConnection->IsInvalid())
  286. {
  287. m_pConnection->AddRef();
  288. *ppConnection = m_pConnection;
  289. hResultCode = DPN_OK;
  290. }
  291. else
  292. {
  293. hResultCode = DPNERR_NOCONNECTION;
  294. }
  295. Unlock();
  296. return( hResultCode );
  297. }
  298. #undef DPF_MODNAME
  299. #define DPF_MODNAME "CNameTableEntry::PackInfo"
  300. HRESULT CNameTableEntry::PackInfo(CPackedBuffer *const pPackedBuffer)
  301. {
  302. HRESULT hResultCode;
  303. DPN_PLAYER_INFO *pPlayerInfo;
  304. DPN_GROUP_INFO *pGroupInfo;
  305. DNASSERT(pPackedBuffer != NULL);
  306. // Lock();
  307. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_GROUP)
  308. {
  309. pGroupInfo = static_cast<DPN_GROUP_INFO*>(pPackedBuffer->GetHeadAddress());
  310. hResultCode = pPackedBuffer->AddToFront(NULL,sizeof(DPN_GROUP_INFO));
  311. //
  312. // Add data
  313. //
  314. if ((m_pvData) && (m_dwDataSize != 0))
  315. {
  316. if ((hResultCode = pPackedBuffer->AddToBack(m_pvData,m_dwDataSize)) == DPN_OK)
  317. {
  318. pGroupInfo->pvData = pPackedBuffer->GetTailAddress();
  319. pGroupInfo->dwDataSize = m_dwDataSize;
  320. }
  321. }
  322. else
  323. {
  324. if (pGroupInfo)
  325. {
  326. pGroupInfo->pvData = NULL;
  327. pGroupInfo->dwDataSize = 0;
  328. }
  329. }
  330. //
  331. // Add name
  332. //
  333. if ((m_pwszName) && (m_dwNameSize != 0))
  334. {
  335. if ((hResultCode = pPackedBuffer->AddToBack(m_pwszName,m_dwNameSize)) == DPN_OK)
  336. {
  337. pGroupInfo->pwszName = static_cast<WCHAR*>(pPackedBuffer->GetTailAddress());
  338. }
  339. }
  340. else
  341. {
  342. if (pGroupInfo)
  343. {
  344. pGroupInfo->pwszName = NULL;
  345. }
  346. }
  347. //
  348. // Update flags
  349. //
  350. if (hResultCode == DPN_OK)
  351. {
  352. if (pGroupInfo)
  353. {
  354. pGroupInfo->dwSize = sizeof(DPN_GROUP_INFO);
  355. pGroupInfo->dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
  356. pGroupInfo->dwGroupFlags = 0;
  357. if (IsAutoDestructGroup())
  358. {
  359. pGroupInfo->dwGroupFlags |= DPNGROUP_AUTODESTRUCT;
  360. }
  361. }
  362. }
  363. }
  364. else
  365. {
  366. pPlayerInfo = static_cast<DPN_PLAYER_INFO*>(pPackedBuffer->GetHeadAddress());
  367. hResultCode = pPackedBuffer->AddToFront(NULL,sizeof(DPN_PLAYER_INFO));
  368. if( !m_dwDataSize )
  369. {
  370. if( pPlayerInfo )
  371. {
  372. pPlayerInfo->pvData = NULL;
  373. pPlayerInfo->dwDataSize = 0;
  374. }
  375. }
  376. else
  377. {
  378. if ((hResultCode = pPackedBuffer->AddToBack(m_pvData,m_dwDataSize)) == DPN_OK)
  379. {
  380. pPlayerInfo->pvData = pPackedBuffer->GetTailAddress();
  381. pPlayerInfo->dwDataSize = m_dwDataSize;
  382. }
  383. }
  384. if( !m_pwszName )
  385. {
  386. if( pPlayerInfo )
  387. {
  388. pPlayerInfo->pwszName = NULL;
  389. }
  390. }
  391. else
  392. {
  393. if ((hResultCode = pPackedBuffer->AddToBack(m_pwszName,m_dwNameSize)) == DPN_OK)
  394. {
  395. pPlayerInfo->pwszName = static_cast<WCHAR*>(pPackedBuffer->GetTailAddress());
  396. }
  397. }
  398. if (hResultCode == DPN_OK)
  399. {
  400. pPlayerInfo->dwSize = sizeof(DPN_PLAYER_INFO);
  401. pPlayerInfo->dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
  402. pPlayerInfo->dwPlayerFlags = 0;
  403. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_HOST)
  404. {
  405. pPlayerInfo->dwPlayerFlags |= DPNPLAYER_HOST;
  406. }
  407. if (m_dwFlags & NAMETABLE_ENTRY_FLAG_LOCAL)
  408. {
  409. pPlayerInfo->dwPlayerFlags |= DPNPLAYER_LOCAL;
  410. }
  411. }
  412. }
  413. // Unlock();
  414. return(hResultCode);
  415. }
  416. #undef DPF_MODNAME
  417. #define DPF_MODNAME "CNameTableEntry::PackEntryInfo"
  418. HRESULT CNameTableEntry::PackEntryInfo(CPackedBuffer *const pPackedBuffer)
  419. {
  420. DWORD dwURLSize;
  421. HRESULT hResultCode;
  422. DN_NAMETABLE_ENTRY_INFO dnEntryInfo;
  423. DPFX(DPFPREP, 6,"Attempting to pack [0x%lx]",m_dpnid);
  424. DNASSERT(pPackedBuffer != NULL);
  425. Lock();
  426. dnEntryInfo.dpnid = m_dpnid;
  427. dnEntryInfo.dpnidOwner = m_dpnidOwner;
  428. dnEntryInfo.dwFlags = m_dwFlags & ( NAMETABLE_ENTRY_FLAG_HOST
  429. | NAMETABLE_ENTRY_FLAG_ALL_PLAYERS_GROUP
  430. | NAMETABLE_ENTRY_FLAG_GROUP
  431. | NAMETABLE_ENTRY_FLAG_GROUP_AUTODESTRUCT
  432. | NAMETABLE_ENTRY_FLAG_PEER
  433. | NAMETABLE_ENTRY_FLAG_CLIENT
  434. | NAMETABLE_ENTRY_FLAG_SERVER );
  435. dnEntryInfo.dwVersion = m_dwVersion;
  436. dnEntryInfo.dwVersionNotUsed = m_dwVersionNotUsed;
  437. dnEntryInfo.dwDNETVersion = m_dwDNETVersion;
  438. // Entry name
  439. if (m_pwszName != NULL)
  440. {
  441. if ((hResultCode = pPackedBuffer->AddToBack(m_pwszName,m_dwNameSize)) == DPN_OK)
  442. {
  443. dnEntryInfo.dwNameOffset = pPackedBuffer->GetTailOffset();
  444. dnEntryInfo.dwNameSize = m_dwNameSize;
  445. }
  446. }
  447. else
  448. {
  449. dnEntryInfo.dwNameOffset = 0;
  450. dnEntryInfo.dwNameSize = 0;
  451. }
  452. // Entry data
  453. if (m_pvData != NULL && m_dwDataSize != 0)
  454. {
  455. if ((hResultCode = pPackedBuffer->AddToBack(m_pvData,m_dwDataSize)) == DPN_OK)
  456. {
  457. dnEntryInfo.dwDataOffset = pPackedBuffer->GetTailOffset();
  458. dnEntryInfo.dwDataSize = m_dwDataSize;
  459. }
  460. }
  461. else
  462. {
  463. dnEntryInfo.dwDataOffset = 0;
  464. dnEntryInfo.dwDataSize = 0;
  465. }
  466. // Entry address (URL)
  467. if ((m_pdnObject->dwFlags & DN_OBJECT_FLAG_PEER) && (m_pAddress != NULL))
  468. {
  469. dwURLSize = 0;
  470. hResultCode = IDirectPlay8Address_GetURLA(m_pAddress,NULL,&dwURLSize);
  471. if (hResultCode != DPN_OK && hResultCode != DPNERR_BUFFERTOOSMALL)
  472. {
  473. DPFERR("Could not determine URL size");
  474. DisplayDNError(0,hResultCode);
  475. Unlock();
  476. goto EXIT_PackEntry;
  477. }
  478. if (dwURLSize != 0)
  479. {
  480. if ((hResultCode = pPackedBuffer->AddToBack(NULL,dwURLSize)) == DPN_OK)
  481. {
  482. if ((hResultCode = IDirectPlay8Address_GetURLA(m_pAddress,
  483. static_cast<char*>(pPackedBuffer->GetTailAddress()),&dwURLSize)) == DPN_OK)
  484. {
  485. dnEntryInfo.dwURLOffset = pPackedBuffer->GetTailOffset();
  486. dnEntryInfo.dwURLSize = dwURLSize;
  487. }
  488. else
  489. {
  490. DPFERR("Could not extract URL from DirectPlayAddress");
  491. DisplayDNError(0,hResultCode);
  492. Unlock();
  493. goto EXIT_PackEntry;
  494. }
  495. }
  496. }
  497. else
  498. {
  499. dnEntryInfo.dwURLOffset = 0;
  500. dnEntryInfo.dwURLSize = 0;
  501. }
  502. }
  503. else
  504. {
  505. dnEntryInfo.dwURLOffset = 0;
  506. dnEntryInfo.dwURLSize = 0;
  507. }
  508. hResultCode = pPackedBuffer->AddToFront(&dnEntryInfo,sizeof(DN_NAMETABLE_ENTRY_INFO));
  509. Unlock();
  510. EXIT_PackEntry:
  511. DPFX(DPFPREP, 6,"Returning: [0x%lx]",hResultCode);
  512. return(hResultCode);
  513. }
  514. #undef DPF_MODNAME
  515. #define DPF_MODNAME "CNameTableEntry::UnpackEntryInfo"
  516. HRESULT CNameTableEntry::UnpackEntryInfo(UNALIGNED const DN_NAMETABLE_ENTRY_INFO *const pdnEntryInfo,
  517. BYTE *const pBufferStart)
  518. {
  519. HRESULT hResultCode;
  520. PWSTR pwszName;
  521. DWORD dwNameSize;
  522. void *pvData;
  523. DWORD dwDataSize;
  524. IDirectPlay8Address *pAddress;
  525. DNASSERT(m_pwszName == NULL);
  526. DNASSERT(m_pvData == NULL);
  527. DNASSERT(m_pAddress == NULL);
  528. if (pdnEntryInfo->dwNameOffset && pdnEntryInfo->dwNameSize)
  529. {
  530. pwszName = reinterpret_cast<WCHAR*>(pBufferStart + pdnEntryInfo->dwNameOffset);
  531. dwNameSize = pdnEntryInfo->dwNameSize;
  532. }
  533. else
  534. {
  535. pwszName = NULL;
  536. dwNameSize = 0;
  537. }
  538. if (pdnEntryInfo->dwDataOffset && pdnEntryInfo->dwDataSize)
  539. {
  540. pvData = static_cast<void*>(pBufferStart + pdnEntryInfo->dwDataOffset);
  541. dwDataSize = pdnEntryInfo->dwDataSize;
  542. }
  543. else
  544. {
  545. pvData = NULL;
  546. dwDataSize = 0;
  547. }
  548. // This function takes the lock internally
  549. UpdateEntryInfo(pwszName,dwNameSize,pvData,dwDataSize,DPNINFO_NAME|DPNINFO_DATA, FALSE);
  550. pAddress = NULL;
  551. if (pdnEntryInfo->dwURLOffset)
  552. {
  553. #ifdef DPNBUILD_LIBINTERFACE
  554. hResultCode = DP8ACF_CreateInstance(IID_IDirectPlay8Address,
  555. reinterpret_cast<void**>(&pAddress));
  556. #else // ! DPNBUILD_LIBINTERFACE
  557. hResultCode = COM_CoCreateInstance(CLSID_DirectPlay8Address,
  558. NULL,
  559. CLSCTX_INPROC_SERVER,
  560. IID_IDirectPlay8Address,
  561. reinterpret_cast<void**>(&pAddress),
  562. FALSE);
  563. #endif // ! DPNBUILD_LIBINTERFACE
  564. if (hResultCode != S_OK)
  565. {
  566. DPFERR("Could not create empty DirectPlayAddress");
  567. DisplayDNError(0,hResultCode);
  568. return(DPNERR_OUTOFMEMORY);
  569. }
  570. hResultCode = IDirectPlay8Address_BuildFromURLA(pAddress,reinterpret_cast<char*>(pBufferStart + pdnEntryInfo->dwURLOffset));
  571. if (hResultCode != DPN_OK)
  572. {
  573. DPFERR("Could not build URL");
  574. DisplayDNError(0,hResultCode);
  575. DNASSERT(FALSE);
  576. IDirectPlay8Address_Release(pAddress);
  577. pAddress = NULL;
  578. return(hResultCode);
  579. }
  580. SetAddress(pAddress);
  581. IDirectPlay8Address_Release(pAddress);
  582. pAddress = NULL;
  583. }
  584. m_dpnid = pdnEntryInfo->dpnid;
  585. m_dpnidOwner = pdnEntryInfo->dpnidOwner;
  586. m_dwFlags = pdnEntryInfo->dwFlags;
  587. m_dwDNETVersion = pdnEntryInfo->dwDNETVersion;
  588. m_dwVersion = pdnEntryInfo->dwVersion;
  589. m_dwVersionNotUsed = pdnEntryInfo->dwVersionNotUsed;
  590. return(DPN_OK);
  591. }
  592. #undef DPF_MODNAME
  593. #define DPF_MODNAME "CNameTableEntry::PerformQueuedOperations"
  594. void CNameTableEntry::PerformQueuedOperations( void )
  595. {
  596. HRESULT hResultCode;
  597. CQueuedMsg *pQueuedMsg;
  598. BOOL fDestroy;
  599. DPFX(DPFPREP, 6,"Parameters: (none)");
  600. fDestroy = FALSE;
  601. Lock();
  602. fDestroy = IsNeedToDestroy();
  603. //
  604. // This assumes that the InUse flag is set. We will clear it before returning.
  605. //
  606. #ifdef DBG
  607. DNASSERT( IsInUse() );
  608. if (!m_bilinkQueuedMsgs.IsEmpty())
  609. {
  610. DPFX(DPFPREP, 7, "Nametable entry 0x%p has %i queued messages.", this, m_lNumQueuedMsgs);
  611. }
  612. #endif // DBG
  613. while (!m_bilinkQueuedMsgs.IsEmpty())
  614. {
  615. pQueuedMsg = CONTAINING_OBJECT(m_bilinkQueuedMsgs.GetNext(),CQueuedMsg,m_bilinkQueuedMsgs);
  616. pQueuedMsg->m_bilinkQueuedMsgs.RemoveFromList();
  617. DEBUG_ONLY(m_lNumQueuedMsgs--);
  618. Unlock();
  619. switch (pQueuedMsg->GetOpType())
  620. {
  621. case RECEIVE:
  622. {
  623. HRESULT hrProcess;
  624. DNASSERT(pQueuedMsg->GetAsyncOp() != NULL);
  625. DNASSERT(pQueuedMsg->GetAsyncOp()->GetHandle() != 0);
  626. #ifndef DPNBUILD_NOVOICE
  627. if (pQueuedMsg->IsVoiceMessage())
  628. {
  629. hrProcess = Voice_Receive( m_pdnObject,
  630. GetDPNID(),
  631. 0,
  632. pQueuedMsg->GetBuffer(),
  633. pQueuedMsg->GetBufferSize());
  634. NotifyRelease();
  635. }
  636. else
  637. #endif // DPNBUILD_NOVOICE
  638. {
  639. hrProcess = DNUserReceive( m_pdnObject,
  640. this,
  641. pQueuedMsg->GetBuffer(),
  642. pQueuedMsg->GetBufferSize(),
  643. pQueuedMsg->GetAsyncOp()->GetHandle());
  644. if (pQueuedMsg->GetCompletionOp() != 0)
  645. {
  646. //
  647. // Send completion message
  648. //
  649. CConnection *pConnection;
  650. pConnection = NULL;
  651. if ((hResultCode = GetConnectionRef( &pConnection )) == DPN_OK)
  652. {
  653. hResultCode = DNSendUserProcessCompletion( m_pdnObject,
  654. pConnection,
  655. pQueuedMsg->GetCompletionOp());
  656. }
  657. pConnection->Release();
  658. pConnection = NULL;
  659. }
  660. }
  661. //
  662. // See if we can return this buffer now
  663. //
  664. if (hrProcess == DPNERR_PENDING)
  665. {
  666. pQueuedMsg->GetAsyncOp()->Release();
  667. pQueuedMsg->SetAsyncOp( NULL );
  668. }
  669. else
  670. {
  671. DNEnterCriticalSection(&m_pdnObject->csActiveList);
  672. pQueuedMsg->GetAsyncOp()->m_bilinkActiveList.RemoveFromList();
  673. DNLeaveCriticalSection(&m_pdnObject->csActiveList);
  674. pQueuedMsg->GetAsyncOp()->Lock();
  675. if (!pQueuedMsg->GetAsyncOp()->IsCancelled() && !pQueuedMsg->GetAsyncOp()->IsComplete())
  676. {
  677. pQueuedMsg->GetAsyncOp()->SetComplete();
  678. pQueuedMsg->GetAsyncOp()->Unlock();
  679. if (SUCCEEDED(m_pdnObject->HandleTable.Destroy( pQueuedMsg->GetAsyncOp()->GetHandle(), NULL )))
  680. {
  681. // Release the HandleTable reference
  682. pQueuedMsg->GetAsyncOp()->Release();
  683. }
  684. }
  685. else
  686. {
  687. pQueuedMsg->GetAsyncOp()->Unlock();
  688. }
  689. pQueuedMsg->GetAsyncOp()->Release();
  690. pQueuedMsg->SetAsyncOp( NULL );
  691. }
  692. break;
  693. }
  694. default:
  695. {
  696. DPFERR("Invalid Queued Operation");
  697. DNASSERT(FALSE);
  698. break;
  699. }
  700. }
  701. //
  702. // Return this queued message
  703. //
  704. pQueuedMsg->ReturnSelfToPool();
  705. pQueuedMsg = NULL;
  706. Lock();
  707. fDestroy = IsNeedToDestroy();
  708. }
  709. //
  710. // No longer processing
  711. //
  712. ClearInUse();
  713. Unlock();
  714. DPFX(DPFPREP, 6,"Returning");
  715. }