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.

309 lines
10 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Enum.cpp
  6. * Content: This file contains support enuming sessions.
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 01/10/00 jtk Created
  12. * 07/01/2000 masonb Assumed Ownership
  13. *
  14. ****************************************************************************/
  15. #include "dnproti.h"
  16. //**********************************************************************
  17. // Constant definitions
  18. //**********************************************************************
  19. //**********************************************************************
  20. // Macro definitions
  21. //**********************************************************************
  22. //**********************************************************************
  23. // Structure definitions
  24. //**********************************************************************
  25. //**********************************************************************
  26. // Variable definitions
  27. //**********************************************************************
  28. //**********************************************************************
  29. // Function prototypes
  30. //**********************************************************************
  31. //**********************************************************************
  32. // Function definitions
  33. //**********************************************************************
  34. /*
  35. ** Send Enum Query
  36. **
  37. ** This routine will send out a broadcast to everyone that can hear
  38. ** indicating this side's interest in finding listening connections.
  39. ** Interested connections will respond through IndicateEnumResponse.
  40. */
  41. #undef DPF_MODNAME
  42. #define DPF_MODNAME "DNPEnumQuery"
  43. HRESULT
  44. DNPEnumQuery(HANDLE hProtocolData, IDirectPlay8Address* paHostAddress, IDirectPlay8Address* paDeviceAddress, HANDLE hSPHandle, BUFFERDESC* pBuffers, DWORD dwBufferCount, DWORD dwRetryCount, DWORD dwRetryInterval, DWORD dwTimeout, DWORD dwFlags, VOID* pvUserContext, VOID* pvSessionData, DWORD dwSessionDataSize, HANDLE* phEnumHandle)
  45. {
  46. ProtocolData* pPData;
  47. PSPD pSPD;
  48. PMSD pMSD;
  49. SPENUMQUERYDATA EnumData;
  50. HRESULT hr;
  51. #ifdef DBG
  52. ULONG ulAllowedFlags;
  53. #endif // DBG
  54. DPFX(DPFPREP,DPF_CALLIN_LVL, "Parameters: hProtocolData[%p], paHostAddress[%p], paDeviceAddress[%p], hSPHandle[%p], pBuffers[%p], dwBufferCount[%x], dwRetryCount[%x], dwRetryInterval[%x], dwTimeout[%x], dwFlags[%x], pvUserContext[%p], pvSessionData[%p], dwSessionDataSize[%u], phEnumHandle[%p]", hProtocolData, paHostAddress, paDeviceAddress, hSPHandle, pBuffers, dwBufferCount, dwRetryCount, dwRetryInterval, dwTimeout, dwFlags, pvUserContext, pvSessionData, dwSessionDataSize, phEnumHandle);
  55. hr = DPNERR_PENDING;
  56. pPData = (ProtocolData*)hProtocolData;
  57. ASSERT_PPD(pPData);
  58. pSPD = (PSPD) hSPHandle;
  59. ASSERT_SPD(pSPD);
  60. // Core should not call any Protocol APIs after calling DNPRemoveServiceProvider
  61. ASSERT(!(pSPD->ulSPFlags & SPFLAGS_TERMINATING));
  62. // We use an MSD to describe this Op even though it isn't technically a message
  63. if((pMSD = (PMSD)POOLALLOC(MEMID_ENUMQUERY_MSD, &MSDPool)) == NULL)
  64. {
  65. DPFX(DPFPREP,0, "Failed to allocate MSD");
  66. hr = DPNERR_OUTOFMEMORY;
  67. goto Exit;
  68. }
  69. pMSD->CommandID = COMMAND_ID_ENUM;
  70. pMSD->pSPD = pSPD;
  71. pMSD->Context = pvUserContext;
  72. EnumData.pAddressHost = paHostAddress;
  73. EnumData.pAddressDeviceInfo = paDeviceAddress;
  74. EnumData.pBuffers = pBuffers;
  75. EnumData.dwBufferCount = dwBufferCount;
  76. EnumData.dwTimeout = dwTimeout;
  77. EnumData.dwRetryCount = dwRetryCount;
  78. EnumData.dwRetryInterval = dwRetryInterval;
  79. #ifdef DBG
  80. ulAllowedFlags = DN_ENUMQUERYFLAGS_NOBROADCASTFALLBACK | DN_ENUMQUERYFLAGS_SESSIONDATA;
  81. #ifndef DPNBUILD_NOSPUI
  82. ulAllowedFlags |= DN_ENUMQUERYFLAGS_OKTOQUERYFORADDRESSING;
  83. #endif // ! DPNBUILD_NOSPUI
  84. #ifndef DPNBUILD_ONLYONEADAPTER
  85. ulAllowedFlags |= DN_ENUMQUERYFLAGS_ADDITIONALMULTIPLEXADAPTERS;
  86. #endif // ! DPNBUILD_ONLYONEADAPTER
  87. DNASSERT( ( dwFlags & ~(ulAllowedFlags) ) == 0 );
  88. #endif // DBG
  89. EnumData.dwFlags = 0;
  90. #ifndef DPNBUILD_NOSPUI
  91. if ( ( dwFlags & DN_ENUMQUERYFLAGS_OKTOQUERYFORADDRESSING ) != 0 )
  92. {
  93. EnumData.dwFlags |= DPNSPF_OKTOQUERY;
  94. }
  95. #endif // ! DPNBUILD_NOSPUI
  96. if ( ( dwFlags & DN_ENUMQUERYFLAGS_NOBROADCASTFALLBACK ) != 0 )
  97. {
  98. EnumData.dwFlags |= DPNSPF_NOBROADCASTFALLBACK;
  99. }
  100. #ifndef DPNBUILD_ONLYONEADAPTER
  101. if ( ( dwFlags & DN_ENUMQUERYFLAGS_ADDITIONALMULTIPLEXADAPTERS ) != 0 )
  102. {
  103. EnumData.dwFlags |= DPNSPF_ADDITIONALMULTIPLEXADAPTERS;
  104. }
  105. #endif // ! DPNBUILD_ONLYONEADAPTER
  106. if ( ( dwFlags & DN_ENUMQUERYFLAGS_SESSIONDATA) != 0 )
  107. {
  108. EnumData.dwFlags |= DPNSPF_SESSIONDATA;
  109. EnumData.pvSessionData = pvSessionData;
  110. EnumData.dwSessionDataSize = dwSessionDataSize;
  111. }
  112. EnumData.pvContext = pMSD;
  113. EnumData.hCommand = NULL;
  114. *phEnumHandle = pMSD;
  115. #ifdef DBG
  116. Lock(&pSPD->SPLock);
  117. pMSD->blSPLinkage.InsertBefore( &pSPD->blMessageList); // Dont support timeouts for Listen
  118. pMSD->ulMsgFlags1 |= MFLAGS_ONE_ON_GLOBAL_LIST;
  119. Unlock(&pSPD->SPLock);
  120. #endif // DBG
  121. pMSD->ulMsgFlags1 |= MFLAGS_ONE_IN_SERVICE_PROVIDER;
  122. LOCK_MSD(pMSD, "SP Ref"); // AddRef for SP
  123. LOCK_MSD(pMSD, "Temp Ref");
  124. AssertNoCriticalSectionsFromGroupTakenByThisThread(&g_blProtocolCritSecsHeld);
  125. DPFX(DPFPREP,DPF_CALLOUT_LVL, "Calling SP->EnumQuery, pSPD[%p], pMSD[%p]", pSPD, pMSD);
  126. /**/hr = IDP8ServiceProvider_EnumQuery(pSPD->IISPIntf, &EnumData); /** CALL SP **/
  127. if(hr != DPNERR_PENDING)
  128. {
  129. // This should always Pend or else be in error
  130. DPFX(DPFPREP,1, "Calling SP->EnumQuery Failed, return is not DPNERR_PENDING, hr[%x], pMSD[%p], pSPD[%p]", hr, pMSD, pSPD);
  131. // DPNERR_PENDING is the only success code we accept
  132. ASSERT(FAILED(hr));
  133. Lock(&pMSD->CommandLock);
  134. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_IN_SERVICE_PROVIDER);
  135. #ifdef DBG
  136. Lock(&pSPD->SPLock);
  137. pMSD->blSPLinkage.RemoveFromList(); // knock this off the pending list
  138. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_ON_GLOBAL_LIST);
  139. Unlock(&pSPD->SPLock);
  140. #endif // DBG
  141. DECREMENT_MSD(pMSD, "Temp Ref");
  142. DECREMENT_MSD(pMSD, "SP Ref"); // release once for SP
  143. RELEASE_MSD(pMSD, "Release On Fail"); // release again to return resource
  144. goto Exit;
  145. }
  146. Lock(&pMSD->CommandLock);
  147. pMSD->hCommand = EnumData.hCommand; // retain SP command handle
  148. pMSD->dwCommandDesc = EnumData.dwCommandDescriptor;
  149. RELEASE_MSD(pMSD, "Temp Ref"); // Unlocks CommandLock
  150. Exit:
  151. DPFX(DPFPREP,DPF_CALLIN_LVL, "Returning hr[%x], pMSD[%p]", hr, pMSD);
  152. AssertNoCriticalSectionsFromGroupTakenByThisThread(&g_blProtocolCritSecsHeld);
  153. return hr;
  154. }
  155. /*
  156. ** Enum Respond
  157. **
  158. ** This routine will send out a response to a received enum query.
  159. */
  160. #undef DPF_MODNAME
  161. #define DPF_MODNAME "DNPEnumRespond"
  162. HRESULT
  163. DNPEnumRespond(HANDLE hProtocolData, HANDLE hSPHandle, HANDLE hQueryHandle, BUFFERDESC* pBuffers, DWORD dwBufferCount, DWORD dwFlags, VOID* pvUserContext, HANDLE* phEnumHandle)
  164. {
  165. ProtocolData* pPData;
  166. PSPD pSPD;
  167. PMSD pMSD;
  168. SPENUMRESPONDDATA EnumRespondData;
  169. HRESULT hr;
  170. DPFX(DPFPREP,DPF_CALLIN_LVL, "Parameters: hProtocolData[%p], hSPHandle[%p], hQueryHandle[%p], pBuffers[%p], dwBufferCount[%x], dwFlags[%x], pvUserContext[%p], phEnumHandle[%p]", hProtocolData, hSPHandle, hQueryHandle, pBuffers, dwBufferCount, dwFlags, pvUserContext, phEnumHandle);
  171. hr = DPNERR_PENDING;
  172. pPData = (ProtocolData*)hProtocolData;
  173. ASSERT_PPD(pPData);
  174. pSPD = (PSPD)hSPHandle;
  175. ASSERT_SPD(pSPD);
  176. ASSERT(hQueryHandle);
  177. // Core should not call any Protocol APIs after calling DNPRemoveServiceProvider
  178. ASSERT(!(pSPD->ulSPFlags & SPFLAGS_TERMINATING));
  179. // We use an MSD to describe this Op even though it isn't technically a message
  180. if((pMSD = (PMSD)POOLALLOC(MEMID_ENUMRESP_MSD, &MSDPool)) == NULL)
  181. {
  182. DPFX(DPFPREP,0, "Failed to allocate MSD");
  183. hr = DPNERR_OUTOFMEMORY;
  184. goto Exit;
  185. }
  186. pMSD->CommandID = COMMAND_ID_ENUMRESP;
  187. pMSD->pSPD = pSPD;
  188. pMSD->Context = pvUserContext;
  189. EnumRespondData.pBuffers = pBuffers;
  190. EnumRespondData.dwBufferCount = dwBufferCount;
  191. EnumRespondData.dwFlags = dwFlags;
  192. EnumRespondData.pvContext = pMSD;
  193. EnumRespondData.hCommand = NULL;
  194. EnumRespondData.pQuery = (SPIE_QUERY*)hQueryHandle;
  195. *phEnumHandle = pMSD;
  196. #ifdef DBG
  197. Lock(&pSPD->SPLock);
  198. pMSD->blSPLinkage.InsertBefore( &pSPD->blMessageList);
  199. pMSD->ulMsgFlags1 |= MFLAGS_ONE_ON_GLOBAL_LIST;
  200. Unlock(&pSPD->SPLock);
  201. #endif // DBG
  202. pMSD->ulMsgFlags1 |= MFLAGS_ONE_IN_SERVICE_PROVIDER;
  203. LOCK_MSD(pMSD, "SP Ref"); // AddRef for SP
  204. LOCK_MSD(pMSD, "Temp Ref");
  205. AssertNoCriticalSectionsFromGroupTakenByThisThread(&g_blProtocolCritSecsHeld);
  206. DPFX(DPFPREP,DPF_CALLOUT_LVL, "Calling SP->EnumRespond, pSPD[%p], pMSD[%p]", pSPD, pMSD);
  207. /**/hr = IDP8ServiceProvider_EnumRespond(pSPD->IISPIntf, &EnumRespondData); /** CALL SP **/
  208. // This should always Pend or else be in error
  209. if(hr != DPNERR_PENDING)
  210. {
  211. DPFX(DPFPREP,1, "Calling SP->EnumRespond, return is not DPNERR_PENDING, hr[%x], pMSD[%p], pSPD[%p]", hr, pMSD, pSPD);
  212. // DPNERR_PENDING is the only success code we accept
  213. ASSERT(FAILED(hr));
  214. Lock(&pMSD->CommandLock);
  215. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_IN_SERVICE_PROVIDER);
  216. #ifdef DBG
  217. Lock(&pSPD->SPLock);
  218. pMSD->blSPLinkage.RemoveFromList(); // knock this off the pending list
  219. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_ON_GLOBAL_LIST);
  220. Unlock(&pSPD->SPLock);
  221. #endif // DBG
  222. DECREMENT_MSD(pMSD, "Temp Ref");
  223. DECREMENT_MSD(pMSD, "SP Ref"); // release once for SP
  224. RELEASE_MSD(pMSD, "Release On Non-Pend"); // release again to return resource
  225. goto Exit;
  226. }
  227. Lock(&pMSD->CommandLock);
  228. pMSD->hCommand = EnumRespondData.hCommand; // retain SP command handle
  229. pMSD->dwCommandDesc = EnumRespondData.dwCommandDescriptor;
  230. RELEASE_MSD(pMSD, "Temp Ref"); // Unlocks CommandLock
  231. Exit:
  232. DPFX(DPFPREP,DPF_CALLIN_LVL, "Returning hr[%x], pMSD[%p]", hr, pMSD);
  233. AssertNoCriticalSectionsFromGroupTakenByThisThread(&g_blProtocolCritSecsHeld);
  234. return hr;
  235. }
  236. //**********************************************************************