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.

397 lines
9.3 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1995 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: connobj.c
  7. //
  8. // Description: Routines to manipulate CONNECTION_OBJECTs
  9. //
  10. // History: May 11,1995 NarenG Created original version.
  11. //
  12. #include "ddm.h"
  13. #include "handlers.h"
  14. #include "objects.h"
  15. #include <raserror.h>
  16. #include <dimif.h>
  17. #include "rasmanif.h"
  18. #include <objbase.h>
  19. #include <stdlib.h>
  20. //**
  21. //
  22. // Call: ConnObjAllocateAndInit
  23. //
  24. // Returns: CONNECTION_OBJECT * - Success
  25. // NULL - Failure
  26. //
  27. // Description: Allocates and initializes a CONNECTION_OBJECT structure
  28. //
  29. CONNECTION_OBJECT *
  30. ConnObjAllocateAndInit(
  31. IN HANDLE hDIMInterface,
  32. IN HCONN hConnection
  33. )
  34. {
  35. CONNECTION_OBJECT * pConnObj;
  36. pConnObj = (CONNECTION_OBJECT *)LOCAL_ALLOC( LPTR,
  37. sizeof( CONNECTION_OBJECT ) );
  38. if ( pConnObj == (CONNECTION_OBJECT *)NULL )
  39. {
  40. return( (CONNECTION_OBJECT *)NULL );
  41. }
  42. pConnObj->hConnection = hConnection;
  43. pConnObj->hDIMInterface = hDIMInterface;
  44. pConnObj->cDeviceListSize = 5;
  45. pConnObj->pDeviceList = (PDEVICE_OBJECT *)LOCAL_ALLOC( LPTR,
  46. pConnObj->cDeviceListSize
  47. * sizeof( PDEVICE_OBJECT ) );
  48. if ( pConnObj->pDeviceList == (PDEVICE_OBJECT *)NULL )
  49. {
  50. LOCAL_FREE( pConnObj );
  51. return( (CONNECTION_OBJECT *)NULL );
  52. }
  53. pConnObj->PppProjectionResult.ip.dwError =ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  54. pConnObj->PppProjectionResult.ipx.dwError=ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  55. pConnObj->PppProjectionResult.nbf.dwError=ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  56. pConnObj->PppProjectionResult.ccp.dwError=ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  57. pConnObj->PppProjectionResult.at.dwError =ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  58. if(S_OK != CoCreateGuid( &(pConnObj->guid) ))
  59. {
  60. LOCAL_FREE(pConnObj->pDeviceList);
  61. LOCAL_FREE(pConnObj);
  62. pConnObj = NULL;
  63. }
  64. return( pConnObj );
  65. }
  66. //**
  67. //
  68. // Call: ConnObjInsertInTable
  69. //
  70. // Returns: None
  71. //
  72. // Description: Will insert a connection object into the connection object
  73. // hash table.
  74. //
  75. VOID
  76. ConnObjInsertInTable(
  77. IN CONNECTION_OBJECT * pConnObj
  78. )
  79. {
  80. DWORD dwBucketIndex = ConnObjHashConnHandleToBucket(pConnObj->hConnection);
  81. pConnObj->pNext = gblDeviceTable.ConnectionBucket[dwBucketIndex];
  82. gblDeviceTable.ConnectionBucket[dwBucketIndex] = pConnObj;
  83. gblDeviceTable.NumConnectionNodes++;
  84. }
  85. //**
  86. //
  87. // Call: ConnObjGetPointer
  88. //
  89. // Returns: Pointer to the required Connection Object.
  90. //
  91. // Description: Will look up the connection hash table and return a pointer
  92. // to the connection object with the passed in connection handle.
  93. //
  94. CONNECTION_OBJECT *
  95. ConnObjGetPointer(
  96. IN HCONN hConnection
  97. )
  98. {
  99. DWORD dwBucketIndex;
  100. CONNECTION_OBJECT * pConnObj;
  101. dwBucketIndex = ConnObjHashConnHandleToBucket( hConnection );
  102. for( pConnObj = gblDeviceTable.ConnectionBucket[dwBucketIndex];
  103. pConnObj != (CONNECTION_OBJECT *)NULL;
  104. pConnObj = pConnObj->pNext )
  105. {
  106. if ( pConnObj->hConnection == hConnection )
  107. {
  108. return( pConnObj );
  109. }
  110. }
  111. return( (CONNECTION_OBJECT *)NULL );
  112. }
  113. //**
  114. //
  115. // Call: ConnObjHashConnHandleToBucket
  116. //
  117. // Returns: Will return the bucket number that the connection handle
  118. // hashes to. Starting from 0.
  119. //
  120. // Description: Will hash a connection handle to a bucket in the connection
  121. // object hash table.
  122. //
  123. DWORD
  124. ConnObjHashConnHandleToBucket(
  125. IN HCONN hConnection
  126. )
  127. {
  128. return( ((DWORD)HandleToUlong(hConnection)) % gblDeviceTable.NumConnectionBuckets );
  129. }
  130. //**
  131. //
  132. // Call: ConnObjRemove
  133. //
  134. // Returns: Pointer to the CONNECTION_OBJECT that is removed from the
  135. // table - Success
  136. // NULL - Failure
  137. //
  138. // Description: Will remove a connection object from the connection hash table.
  139. // The object is not freed.
  140. //
  141. PCONNECTION_OBJECT
  142. ConnObjRemove(
  143. IN HCONN hConnection
  144. )
  145. {
  146. DWORD dwBucketIndex;
  147. CONNECTION_OBJECT * pConnObj;
  148. CONNECTION_OBJECT * pConnObjPrev;
  149. dwBucketIndex = ConnObjHashConnHandleToBucket( hConnection );
  150. pConnObj = gblDeviceTable.ConnectionBucket[dwBucketIndex];
  151. pConnObjPrev = pConnObj;
  152. while( pConnObj != (CONNECTION_OBJECT *)NULL )
  153. {
  154. if ( pConnObj->hConnection == hConnection )
  155. {
  156. if ( gblDeviceTable.ConnectionBucket[dwBucketIndex] == pConnObj )
  157. {
  158. gblDeviceTable.ConnectionBucket[dwBucketIndex]=pConnObj->pNext;
  159. }
  160. else
  161. {
  162. pConnObjPrev->pNext = pConnObj->pNext;
  163. }
  164. gblDeviceTable.NumConnectionNodes--;
  165. return( pConnObj );
  166. }
  167. pConnObjPrev = pConnObj;
  168. pConnObj = pConnObj->pNext;
  169. }
  170. return( NULL );
  171. }
  172. //**
  173. //
  174. // Call: ConnObjRemoveAndDeAllocate
  175. //
  176. // Returns: None
  177. //
  178. // Description: Will remove a connection object from the connection hash table
  179. // and free it.
  180. //
  181. VOID
  182. ConnObjRemoveAndDeAllocate(
  183. IN HCONN hConnection
  184. )
  185. {
  186. CONNECTION_OBJECT * pConnObj = ConnObjRemove( hConnection );
  187. if ( pConnObj != (CONNECTION_OBJECT *)NULL )
  188. {
  189. if ( pConnObj->pDeviceList != (PDEVICE_OBJECT *)NULL )
  190. {
  191. LOCAL_FREE( pConnObj->pDeviceList );
  192. }
  193. LOCAL_FREE( pConnObj );
  194. }
  195. }
  196. //**
  197. //
  198. // Call: ConnObjAddLink
  199. //
  200. // Returns: NO_ERROR - Success
  201. // ERROR_NOT_ENOUGH_MEMORY - Failure
  202. //
  203. // Description: Will add a link to the connection object
  204. //
  205. DWORD
  206. ConnObjAddLink(
  207. IN CONNECTION_OBJECT * pConnObj,
  208. IN DEVICE_OBJECT * pDeviceObj
  209. )
  210. {
  211. DWORD dwIndex;
  212. //
  213. // First check to see if the link is not already added
  214. //
  215. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  216. {
  217. if ( pConnObj->pDeviceList[dwIndex] == pDeviceObj )
  218. {
  219. return( NO_ERROR );
  220. }
  221. }
  222. //
  223. // A connection object for this handle exists, try to insert the link
  224. //
  225. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  226. {
  227. if ( pConnObj->pDeviceList[dwIndex] == (DEVICE_OBJECT *)NULL )
  228. {
  229. pConnObj->pDeviceList[dwIndex] = pDeviceObj;
  230. break;
  231. }
  232. }
  233. //
  234. // No space for the new link so allocate more memory.
  235. //
  236. if ( dwIndex == pConnObj->cDeviceListSize )
  237. {
  238. pConnObj->cDeviceListSize += 5;
  239. pConnObj->pDeviceList = (PDEVICE_OBJECT *)LOCAL_REALLOC(
  240. pConnObj->pDeviceList,
  241. pConnObj->cDeviceListSize
  242. * sizeof( PDEVICE_OBJECT ) );
  243. if ( pConnObj->pDeviceList == (PDEVICE_OBJECT *)NULL )
  244. {
  245. return( ERROR_NOT_ENOUGH_MEMORY );
  246. }
  247. pConnObj->pDeviceList[pConnObj->cDeviceListSize-5] = pDeviceObj;
  248. }
  249. pConnObj->cActiveDevices++;
  250. return( NO_ERROR );
  251. }
  252. //**
  253. //
  254. // Call: ConnObjRemoveLink
  255. //
  256. // Returns: None
  257. //
  258. // Description: Will remove a link from the connection object.
  259. //
  260. VOID
  261. ConnObjRemoveLink(
  262. IN HCONN hConnection,
  263. IN DEVICE_OBJECT * pDeviceObj
  264. )
  265. {
  266. CONNECTION_OBJECT * pConnObj;
  267. DWORD dwIndex;
  268. //
  269. // If there is no such connection object
  270. //
  271. if ( ( pConnObj = ConnObjGetPointer( hConnection ) ) == NULL )
  272. {
  273. return;
  274. }
  275. //
  276. // A connection object for this handle exists, try to find and remove
  277. // the link
  278. //
  279. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  280. {
  281. if ( pConnObj->pDeviceList[dwIndex] == pDeviceObj )
  282. {
  283. pConnObj->pDeviceList[dwIndex] = (DEVICE_OBJECT *)NULL;
  284. pConnObj->cActiveDevices--;
  285. return;
  286. }
  287. }
  288. return;
  289. }
  290. //**
  291. //
  292. // Call: ConnObjDisconnect
  293. //
  294. // Returns: None
  295. //
  296. // Description: Will initiate a disconnect for all the devices or links in this
  297. // connection.
  298. //
  299. VOID
  300. ConnObjDisconnect(
  301. IN CONNECTION_OBJECT * pConnObj
  302. )
  303. {
  304. DWORD dwIndex;
  305. DWORD cActiveDevices = pConnObj->cActiveDevices;
  306. RTASSERT( pConnObj != NULL );
  307. //
  308. // Bring down all the individual links
  309. //
  310. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  311. {
  312. DEVICE_OBJECT * pDeviceObj = pConnObj->pDeviceList[dwIndex];
  313. if ( pDeviceObj != (DEVICE_OBJECT *)NULL )
  314. {
  315. if ( pDeviceObj->fFlags & DEV_OBJ_OPENED_FOR_DIALOUT )
  316. {
  317. RasApiCleanUpPort( pDeviceObj );
  318. }
  319. else
  320. {
  321. if ( pDeviceObj->fFlags & DEV_OBJ_PPP_IS_ACTIVE )
  322. {
  323. PppDdmStop( (HPORT)pDeviceObj->hPort, NO_ERROR );
  324. }
  325. else
  326. {
  327. DevStartClosing( pDeviceObj );
  328. }
  329. }
  330. if ( --cActiveDevices == 0 )
  331. {
  332. break;
  333. }
  334. }
  335. }
  336. return;
  337. }