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.

379 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1998 - 2000 Microsoft Corporation
  3. Module Name:
  4. cblist.cpp
  5. Abstract:
  6. Definitions of methods for CALL_BRIDGE_LIST container.
  7. Revision History:
  8. 1. 31-Jul-1998 -- File creation Ajay Chitturi (ajaych)
  9. 2. 15-Jul-1999 -- Arlie Davis (arlied)
  10. 3. 14-Feb-2000 -- Added method to remove call Ilya Kleyman (ilyak)
  11. bridges by connected interface
  12. --*/
  13. #include "stdafx.h"
  14. CALL_BRIDGE_LIST CallBridgeList;
  15. CALL_BRIDGE_LIST::CALL_BRIDGE_LIST (
  16. void
  17. )
  18. /*++
  19. Routine Description:
  20. Constructor for CALL_BRIDGE_LIST class
  21. Arguments:
  22. None
  23. Return Values:
  24. None
  25. Notes:
  26. --*/
  27. {
  28. IsEnabled = FALSE;
  29. } // CALL_BRIDGE_LIST::CALL_BRIDGE_LIST
  30. CALL_BRIDGE_LIST::~CALL_BRIDGE_LIST (
  31. void
  32. )
  33. /*++
  34. Routine Description:
  35. Destructor for CALL_BRIDGE_LIST class
  36. Arguments:
  37. None
  38. Return Values:
  39. None
  40. Notes:
  41. --*/
  42. {
  43. assert (!IsEnabled);
  44. assert (CallArray.Length == 0);
  45. CallArray.Free();
  46. } // CALL_BRIDGE_LIST::~CALL_BRIDGE_LIST
  47. void
  48. CALL_BRIDGE_LIST::Start (
  49. void
  50. )
  51. /*++
  52. Routine Description:
  53. Activates the container
  54. Arguments:
  55. None
  56. Return Values:
  57. None
  58. Notes:
  59. --*/
  60. {
  61. Lock();
  62. IsEnabled = TRUE;
  63. Unlock();
  64. } // CALL_BRIDGE_LIST::Start
  65. void
  66. CALL_BRIDGE_LIST::Stop (
  67. void
  68. )
  69. /*++
  70. Routine Description:
  71. Deactivates the container. Terminates and removes
  72. all contained items.
  73. Arguments:
  74. None
  75. Return Values:
  76. None
  77. Notes:
  78. --*/
  79. {
  80. CALL_BRIDGE * CallBridge;
  81. Lock ();
  82. IsEnabled = FALSE;
  83. while (CallArray.GetLength()) {
  84. CallBridge = CallArray [0].CallBridge;
  85. CallBridge -> AddRef ();
  86. Unlock();
  87. CallBridge -> TerminateExternal();
  88. Lock();
  89. CallBridge -> Release ();
  90. }
  91. CallArray.Free();
  92. Unlock();
  93. } // CALL_BRIDGE_LIST::Stop
  94. HRESULT
  95. CALL_BRIDGE_LIST::InsertCallBridge (
  96. IN CALL_BRIDGE * CallBridge
  97. )
  98. /*++
  99. Routine Description:
  100. Insert an item into the container
  101. Arguments:
  102. CallBridge -- item to be inserted
  103. Return Values:
  104. S_OK - if insertion was successful
  105. E_OUTOFMEMORY - if insertion failed due to the lack of memory
  106. E_FAIL - if insertion failed because the container was not enabled
  107. E_ABORT - if insertion failed because maximum number of concurrent
  108. H.323 connections is exceeded
  109. Notes:
  110. --*/
  111. {
  112. CALL_BRIDGE_ENTRY * Entry;
  113. HRESULT Result;
  114. DWORD Index;
  115. Lock();
  116. if (IsEnabled) {
  117. if (CallArray.Length <= MAX_NUM_CALL_BRIDGES) {
  118. if (CallArray.BinarySearch ((SEARCH_FUNC_CALL_BRIDGE_ENTRY)CALL_BRIDGE_LIST::BinarySearchFunc,
  119. CallBridge, &Index)) {
  120. DebugF (_T("H323: 0x%x already exists in CallBridgeList.\n"), CallBridge);
  121. Result = S_OK;
  122. }
  123. else {
  124. Entry = CallArray.AllocAtPos (Index);
  125. if (Entry) {
  126. Entry -> CallBridge = CallBridge;
  127. Entry -> CallBridge -> AddRef();
  128. Result = S_OK;
  129. }
  130. else {
  131. DebugF (_T("H323: 0x%x allocation failure when inserting in CallBridgeList.\n"), CallBridge);
  132. Result = E_OUTOFMEMORY;
  133. }
  134. }
  135. } else {
  136. return E_ABORT;
  137. }
  138. } else {
  139. Result = E_FAIL;
  140. }
  141. Unlock();
  142. return Result;
  143. } // CALL_BRIDGE_LIST::InsertCallBridge
  144. HRESULT
  145. CALL_BRIDGE_LIST::RemoveCallBridge (
  146. IN CALL_BRIDGE * CallBridge
  147. )
  148. /*++
  149. Routine Description:
  150. Removes an entry from the container
  151. Arguments:
  152. CallBridge - item to removed
  153. Return Values:
  154. S_OK - if removal was successful
  155. S_FALSE - if removal failed because the entry
  156. was not in the container
  157. Notes:
  158. --*/
  159. {
  160. DWORD Index;
  161. HRESULT Result;
  162. Lock();
  163. if (CallArray.BinarySearch ((SEARCH_FUNC_CALL_BRIDGE_ENTRY)CALL_BRIDGE_LIST::BinarySearchFunc,
  164. CallBridge, &Index)) {
  165. CallArray.DeleteAtPos (Index);
  166. Result = S_OK;
  167. }
  168. else {
  169. DebugF (_T("H323: 0x%x could not be removed from the array because it is not there.\n"), CallBridge);
  170. Result = S_FALSE;
  171. }
  172. Unlock();
  173. if (Result == S_OK)
  174. CallBridge -> Release ();
  175. return Result;
  176. } // CALL_BRIDGE_LIST::RemoveCallBridge
  177. void
  178. CALL_BRIDGE_LIST::OnInterfaceShutdown (
  179. IN DWORD InterfaceAddress // host order
  180. )
  181. /*++
  182. Routine Description:
  183. Searches through the list of CALL_BRIDGES, and terminates
  184. all of them that proxy a connection through the interface specified.
  185. Arguments:
  186. InterfaceAddress - address of the interface, H.323 connections
  187. through which are to be terminated.
  188. Return Values:
  189. Notes:
  190. --*/
  191. {
  192. DWORD ArrayIndex = 0;
  193. CALL_BRIDGE* CallBridge;
  194. CALL_BRIDGE** CallBridgeHolder;
  195. DYNAMIC_ARRAY <CALL_BRIDGE*> TempArray;
  196. Lock ();
  197. while (ArrayIndex < CallArray.GetLength()) {
  198. CallBridge = CallArray[ArrayIndex].CallBridge;
  199. if (CallBridge -> IsConnectionThrough (InterfaceAddress))
  200. {
  201. DebugF (_T("Q931: 0x%x terminating (killing all connections through %08X).\n"),
  202. CallBridge, InterfaceAddress);
  203. CallBridgeHolder = TempArray.AllocAtEnd ();
  204. if (NULL == CallBridgeHolder) {
  205. Debug (_T("CALL_BRIDGE_LIST::OnInterfaceShutdown - unable to grow array.\n"));
  206. } else {
  207. CallBridge -> AddRef ();
  208. *CallBridgeHolder = CallBridge;
  209. }
  210. }
  211. ArrayIndex++;
  212. }
  213. Unlock ();
  214. ArrayIndex = 0;
  215. while (ArrayIndex < TempArray.GetLength ()) {
  216. CallBridge = TempArray[ArrayIndex];
  217. CallBridge -> OnInterfaceShutdown ();
  218. CallBridge -> Release ();
  219. ArrayIndex++;
  220. }
  221. } // CALL_BRIDGE_LIST::OnInterfaceShutdown
  222. // static
  223. INT
  224. CALL_BRIDGE_LIST::BinarySearchFunc (
  225. IN const CALL_BRIDGE * SearchKey,
  226. IN const CALL_BRIDGE_ENTRY * Comparand
  227. )
  228. /*++
  229. Routine Description:
  230. Compares an entry with a key. Used by a binary search
  231. procedure.
  232. Arguments:
  233. SearchKey - self-explanatory
  234. Comparand - self-explanatory
  235. Return Values:
  236. 1 if SearchKey is considered greater than Comparand
  237. -1 if SearchKey is considered less than Comparand
  238. 0 if SearchKey is considered equal to Comparand
  239. Notes:
  240. Static method
  241. --*/
  242. {
  243. const CALL_BRIDGE * ComparandA;
  244. const CALL_BRIDGE * ComparandB;
  245. ComparandA = SearchKey;
  246. ComparandB = Comparand -> CallBridge;
  247. if (ComparandA < ComparandB) return -1;
  248. if (ComparandA > ComparandB) return 1;
  249. return 0;
  250. } // CALL_BRIDGE_LIST::BinarySearchFunc