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.

417 lines
10 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. if(pConnObj->pQuarantineFilter != NULL)
  194. {
  195. MprInfoDelete(pConnObj->pQuarantineFilter);
  196. }
  197. if(pConnObj->pFilter != NULL)
  198. {
  199. MprInfoDelete(pConnObj->pFilter);
  200. }
  201. LOCAL_FREE( pConnObj );
  202. }
  203. }
  204. //**
  205. //
  206. // Call: ConnObjAddLink
  207. //
  208. // Returns: NO_ERROR - Success
  209. // ERROR_NOT_ENOUGH_MEMORY - Failure
  210. //
  211. // Description: Will add a link to the connection object
  212. //
  213. DWORD
  214. ConnObjAddLink(
  215. IN CONNECTION_OBJECT * pConnObj,
  216. IN DEVICE_OBJECT * pDeviceObj
  217. )
  218. {
  219. DWORD dwIndex;
  220. //
  221. // First check to see if the link is not already added
  222. //
  223. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  224. {
  225. if ( pConnObj->pDeviceList[dwIndex] == pDeviceObj )
  226. {
  227. return( NO_ERROR );
  228. }
  229. }
  230. //
  231. // A connection object for this handle exists, try to insert the link
  232. //
  233. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  234. {
  235. if ( pConnObj->pDeviceList[dwIndex] == (DEVICE_OBJECT *)NULL )
  236. {
  237. pConnObj->pDeviceList[dwIndex] = pDeviceObj;
  238. break;
  239. }
  240. }
  241. //
  242. // No space for the new link so allocate more memory.
  243. //
  244. if ( dwIndex == pConnObj->cDeviceListSize )
  245. {
  246. LPVOID Tmp = pConnObj->pDeviceList;
  247. pConnObj->cDeviceListSize += 5;
  248. Tmp = (PDEVICE_OBJECT *)LOCAL_REALLOC(
  249. pConnObj->pDeviceList,
  250. pConnObj->cDeviceListSize
  251. * sizeof( PDEVICE_OBJECT ) );
  252. if ( Tmp == (PDEVICE_OBJECT *)NULL )
  253. {
  254. if (pConnObj->pDeviceList)
  255. {
  256. LOCAL_FREE(pConnObj->pDeviceList);
  257. }
  258. return( ERROR_NOT_ENOUGH_MEMORY );
  259. }
  260. else
  261. {
  262. pConnObj->pDeviceList = Tmp;
  263. }
  264. pConnObj->pDeviceList[pConnObj->cDeviceListSize-5] = pDeviceObj;
  265. }
  266. pConnObj->cActiveDevices++;
  267. return( NO_ERROR );
  268. }
  269. //**
  270. //
  271. // Call: ConnObjRemoveLink
  272. //
  273. // Returns: None
  274. //
  275. // Description: Will remove a link from the connection object.
  276. //
  277. VOID
  278. ConnObjRemoveLink(
  279. IN HCONN hConnection,
  280. IN DEVICE_OBJECT * pDeviceObj
  281. )
  282. {
  283. CONNECTION_OBJECT * pConnObj;
  284. DWORD dwIndex;
  285. //
  286. // If there is no such connection object
  287. //
  288. if ( ( pConnObj = ConnObjGetPointer( hConnection ) ) == NULL )
  289. {
  290. return;
  291. }
  292. //
  293. // A connection object for this handle exists, try to find and remove
  294. // the link
  295. //
  296. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  297. {
  298. if ( pConnObj->pDeviceList[dwIndex] == pDeviceObj )
  299. {
  300. pConnObj->pDeviceList[dwIndex] = (DEVICE_OBJECT *)NULL;
  301. pConnObj->cActiveDevices--;
  302. return;
  303. }
  304. }
  305. return;
  306. }
  307. //**
  308. //
  309. // Call: ConnObjDisconnect
  310. //
  311. // Returns: None
  312. //
  313. // Description: Will initiate a disconnect for all the devices or links in this
  314. // connection.
  315. //
  316. VOID
  317. ConnObjDisconnect(
  318. IN CONNECTION_OBJECT * pConnObj
  319. )
  320. {
  321. DWORD dwIndex;
  322. DWORD cActiveDevices = pConnObj->cActiveDevices;
  323. RTASSERT( pConnObj != NULL );
  324. //
  325. // Bring down all the individual links
  326. //
  327. for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
  328. {
  329. DEVICE_OBJECT * pDeviceObj = pConnObj->pDeviceList[dwIndex];
  330. if ( pDeviceObj != (DEVICE_OBJECT *)NULL )
  331. {
  332. if ( pDeviceObj->fFlags & DEV_OBJ_OPENED_FOR_DIALOUT )
  333. {
  334. RasApiCleanUpPort( pDeviceObj );
  335. }
  336. else
  337. {
  338. if ( pDeviceObj->fFlags & DEV_OBJ_PPP_IS_ACTIVE )
  339. {
  340. PppDdmStop( (HPORT)pDeviceObj->hPort, NO_ERROR );
  341. }
  342. else
  343. {
  344. DevStartClosing( pDeviceObj );
  345. }
  346. }
  347. if ( --cActiveDevices == 0 )
  348. {
  349. break;
  350. }
  351. }
  352. }
  353. return;
  354. }