Source code of Windows XP (NT5)
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.

289 lines
9.4 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 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. // ------------------------------
  36. // DNPEnumQuery - enum sessions
  37. //
  38. // Entry: Pointer to this interface
  39. // Pointer to device address
  40. // Pointer to host address
  41. // Pointer to user data buffers
  42. // Count of user data buffers
  43. // Retry count
  44. // Retry interval (milliseconds)
  45. // Timeout (milliseconds)
  46. // Command flags
  47. // Pointer to user context
  48. // Pointer to command handle destination
  49. //
  50. // Exit: Boolean inficating whether the GUID is a serial GUID
  51. // ------------------------------
  52. #undef DPF_MODNAME
  53. #define DPF_MODNAME "DNPEnumQuery"
  54. HRESULT DNPEnumQuery( PProtocolData pPData,
  55. IDirectPlay8Address *const pHostAddress,
  56. IDirectPlay8Address *const pDeviceAddress,
  57. const HANDLE hSPHandle,
  58. BUFFERDESC *const pBuffers,
  59. const DWORD dwBufferCount,
  60. const DWORD dwRetryCount,
  61. const DWORD dwRetryInterval,
  62. const DWORD dwTimeout,
  63. const DWORD dwFlags,
  64. void *const pUserContext,
  65. HANDLE *const pCommandHandle )
  66. {
  67. PSPD pSPD;
  68. PMSD pMSD;
  69. SPENUMQUERYDATA EnumData;
  70. HRESULT hr;
  71. DPFX(DPFPREP,DPF_CALLIN_LVL, "Parameters: pPData[%p], pHostAddr[%p], pDeviceAddr[%p], hSPHandle[%x], pBuffers[%p], dwBufferCount[%x], dwRetryCount[%x], dwRetryInterval[%x], dwTimeout[%x], dwFlags[%x], pUserContext[%p], pCommandHandle[%p]", pPData, pHostAddress, pDeviceAddress, hSPHandle, pBuffers, dwBufferCount, dwRetryCount, dwRetryInterval, dwTimeout, dwFlags, pUserContext, pCommandHandle);
  72. pSPD = (PSPD) hSPHandle;
  73. ASSERT_SPD(pSPD);
  74. // Core should not call any Protocol APIs after calling DNPRemoveServiceProvider
  75. ASSERT(!(pSPD->ulSPFlags & SPFLAGS_TERMINATING));
  76. // We use an MSD to describe this Op even tho it
  77. if((pMSD = static_cast<PMSD>( MSDPool->Get(MSDPool) )) == NULL)
  78. {
  79. DPFX(DPFPREP,0, "Failed to allocate MSD");
  80. Unlock(&pSPD->SPLock);
  81. return DPNERR_OUTOFMEMORY; // .. isnt technically a message
  82. }
  83. pMSD->CommandID = COMMAND_ID_ENUM;
  84. pMSD->pSPD = pSPD;
  85. pMSD->Context = pUserContext;
  86. EnumData.pAddressHost = pHostAddress;
  87. EnumData.pAddressDeviceInfo = pDeviceAddress;
  88. EnumData.pBuffers = pBuffers;
  89. EnumData.dwBufferCount = dwBufferCount;
  90. EnumData.dwTimeout = dwTimeout;
  91. EnumData.dwRetryCount = dwRetryCount;
  92. EnumData.dwRetryInterval = dwRetryInterval;
  93. EnumData.dwFlags = 0;
  94. if ( ( dwFlags & DN_ENUMQUERYFLAGS_OKTOQUERYFORADDRESSING ) != 0 )
  95. {
  96. EnumData.dwFlags |= DPNSPF_OKTOQUERY;
  97. }
  98. if ( ( dwFlags & DN_ENUMQUERYFLAGS_NOBROADCASTFALLBACK ) != 0 )
  99. {
  100. EnumData.dwFlags |= DPNSPF_NOBROADCASTFALLBACK;
  101. }
  102. if ( ( dwFlags & DN_ENUMQUERYFLAGS_ADDITIONALMULTIPLEXADAPTERS ) != 0 )
  103. {
  104. EnumData.dwFlags |= DPNSPF_ADDITIONALMULTIPLEXADAPTERS;
  105. }
  106. EnumData.pvContext = pMSD;
  107. EnumData.hCommand = NULL;
  108. *pCommandHandle = pMSD;
  109. #ifdef DEBUG
  110. Lock(&pSPD->SPLock);
  111. pMSD->blSPLinkage.InsertBefore( &pSPD->blMessageList); // Dont support timeouts for Listen
  112. pMSD->ulMsgFlags1 |= MFLAGS_ONE_ON_GLOBAL_LIST;
  113. Unlock(&pSPD->SPLock);
  114. #endif
  115. pMSD->ulMsgFlags1 |= MFLAGS_ONE_IN_SERVICE_PROVIDER;
  116. LOCK_MSD(pMSD, "SP Ref"); // AddRef for SP
  117. LOCK_MSD(pMSD, "Temp Ref");
  118. DPFX(DPFPREP,DPF_CALLOUT_LVL, "Calling SP->EnumQuery, pSPD[%p], pMSD[%p]", pSPD, pMSD);
  119. /**/hr = IDP8ServiceProvider_EnumQuery(pSPD->IISPIntf, &EnumData); /** CALL SP **/
  120. if(hr != DPNERR_PENDING)
  121. {
  122. // This should always Pend or else be in error
  123. DPFX(DPFPREP,1, "Calling SP->EnumQuery Failed, return is not DPNERR_PENDING, hr[%x], pMSD[%p], pSPD[%p]", hr, pMSD, pSPD);
  124. Lock(&pMSD->CommandLock);
  125. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_IN_SERVICE_PROVIDER);
  126. #ifdef DEBUG
  127. Lock(&pSPD->SPLock);
  128. pMSD->blSPLinkage.RemoveFromList(); // knock this off the pending list
  129. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_ON_GLOBAL_LIST);
  130. Unlock(&pSPD->SPLock);
  131. #endif
  132. DECREMENT_MSD(pMSD, "Temp Ref");
  133. DECREMENT_MSD(pMSD, "SP Ref"); // release once for SP
  134. RELEASE_MSD(pMSD, "Release On Fail"); // release again to return resource
  135. return hr;
  136. }
  137. Lock(&pMSD->CommandLock);
  138. pMSD->hCommand = EnumData.hCommand; // retain SP command handle
  139. pMSD->dwCommandDesc = EnumData.dwCommandDescriptor;
  140. RELEASE_MSD(pMSD, "Temp Ref"); // Unlocks CommandLock
  141. DPFX(DPFPREP,DPF_CALLIN_LVL, "Returning DPNERR_PENDING, pMSD[%p]", pMSD);
  142. return DPNERR_PENDING;
  143. }
  144. //**********************************************************************
  145. //**********************************************************************
  146. // ------------------------------
  147. // DNPEnumRespond - respond to an enum query
  148. //
  149. // Entry: Pointer to this interface
  150. // Handle of enum to respond to (pointer to SPIE_ENUMQUERY structure)
  151. // Pointer data buffers to send
  152. // Count of data buffers to send
  153. // Flags
  154. // User context for this operation
  155. // Pointer to command handle destination
  156. //
  157. // Exit: Boolean inficating whether the GUID is a serial GUID
  158. // ------------------------------
  159. #undef DPF_MODNAME
  160. #define DPF_MODNAME "DNPEnumRespond"
  161. HRESULT DNPEnumRespond( PProtocolData pPData,
  162. const HANDLE hSPHandle,
  163. const HANDLE hQueryHandle, // handle of enum query being responded to
  164. BUFFERDESC *const pResponseBuffers,
  165. const DWORD dwResponseBufferCount,
  166. const DWORD dwFlags,
  167. void *const pUserContext,
  168. HANDLE *const pCommandHandle )
  169. {
  170. PSPD pSPD;
  171. PMSD pMSD;
  172. SPENUMRESPONDDATA EnumRespondData;
  173. HRESULT hr;
  174. DPFX(DPFPREP,DPF_CALLIN_LVL, "Parameters: pPData[%p], hSPHandle[%x], hQueryHandle[%x], pResponseBuffers[%p], dwResponseBufferCount[%x], dwFlags[%x], pUserContext[%p], pCommandHandle[%p]", pPData, hSPHandle, hQueryHandle, pResponseBuffers, dwResponseBufferCount, dwFlags, pUserContext, pCommandHandle);
  175. EnumRespondData.pQuery = static_cast<SPIE_QUERY*>( hQueryHandle );
  176. DNASSERT( EnumRespondData.pQuery != NULL );
  177. pSPD = (PSPD) hSPHandle;
  178. ASSERT_SPD(pSPD);
  179. // Core should not call any Protocol APIs after calling DNPRemoveServiceProvider
  180. ASSERT(!(pSPD->ulSPFlags & SPFLAGS_TERMINATING));
  181. // We use an MSD to describe this Op even tho it
  182. if((pMSD = static_cast<PMSD>( MSDPool->Get(MSDPool) )) == NULL)
  183. {
  184. DPFX(DPFPREP,0, "Failed to allocate MSD");
  185. Unlock(&pSPD->SPLock);
  186. return DPNERR_OUTOFMEMORY; // .. isnt technically a message
  187. }
  188. pMSD->CommandID = COMMAND_ID_ENUMRESP;
  189. pMSD->pSPD = pSPD;
  190. pMSD->Context = pUserContext;
  191. EnumRespondData.pBuffers = pResponseBuffers;
  192. EnumRespondData.dwBufferCount = dwResponseBufferCount;
  193. EnumRespondData.dwFlags = dwFlags;
  194. EnumRespondData.pvContext = pMSD;
  195. EnumRespondData.hCommand = NULL;
  196. *pCommandHandle = pMSD;
  197. #ifdef DEBUG
  198. Lock(&pSPD->SPLock);
  199. pMSD->blSPLinkage.InsertBefore( &pSPD->blMessageList);
  200. pMSD->ulMsgFlags1 |= MFLAGS_ONE_ON_GLOBAL_LIST;
  201. Unlock(&pSPD->SPLock);
  202. #endif
  203. pMSD->ulMsgFlags1 |= MFLAGS_ONE_IN_SERVICE_PROVIDER;
  204. LOCK_MSD(pMSD, "SP Ref"); // AddRef for SP
  205. LOCK_MSD(pMSD, "Temp Ref");
  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. Lock(&pMSD->CommandLock);
  213. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_IN_SERVICE_PROVIDER);
  214. #ifdef DEBUG
  215. Lock(&pSPD->SPLock);
  216. pMSD->blSPLinkage.RemoveFromList(); // knock this off the pending list
  217. pMSD->ulMsgFlags1 &= ~(MFLAGS_ONE_ON_GLOBAL_LIST);
  218. Unlock(&pSPD->SPLock);
  219. #endif
  220. DECREMENT_MSD(pMSD, "Temp Ref");
  221. DECREMENT_MSD(pMSD, "SP Ref"); // release once for SP
  222. RELEASE_MSD(pMSD, "Release On Fail"); // release again to return resource
  223. return hr;
  224. }
  225. Lock(&pMSD->CommandLock);
  226. pMSD->hCommand = EnumRespondData.hCommand; // retain SP command handle
  227. pMSD->dwCommandDesc = EnumRespondData.dwCommandDescriptor;
  228. RELEASE_MSD(pMSD, "Temp Ref"); // Unlocks CommandLock
  229. DPFX(DPFPREP,DPF_CALLIN_LVL, "Returning DPNERR_PENDING, pMSD[%p]", pMSD);
  230. return DPNERR_PENDING;
  231. }
  232. //**********************************************************************