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.

478 lines
10 KiB

  1. /*++
  2. Copyright (c) 1997 - 98, Microsoft Corporation
  3. Module Name:
  4. rtmlist.c
  5. Abstract:
  6. Contains routines for managing entity-specific
  7. list of routes in RTM.
  8. Author:
  9. Chaitanya Kodeboyina (chaitk) 10-Sep-1998
  10. Revision History:
  11. --*/
  12. #include "pchrtm.h"
  13. #pragma hdrstop
  14. DWORD
  15. WINAPI
  16. RtmCreateRouteList (
  17. IN RTM_ENTITY_HANDLE RtmRegHandle,
  18. OUT PRTM_ROUTE_LIST_HANDLE RouteListHandle
  19. )
  20. /*++
  21. Routine Description:
  22. Creates a list in which the caller can keep routes owned
  23. by it.
  24. Arguments:
  25. RtmRegHandle - RTM registration handle for calling entity
  26. RouteListHandle - Handle to the new route list is returned
  27. Return Value:
  28. Status of the operation
  29. --*/
  30. {
  31. PENTITY_INFO Entity;
  32. PROUTE_LIST RouteList;
  33. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  34. //
  35. // Create and initialize a new route list
  36. //
  37. RouteList = (PROUTE_LIST) AllocNZeroObject(sizeof(ROUTE_LIST));
  38. if (RouteList == NULL)
  39. {
  40. return ERROR_NOT_ENOUGH_MEMORY;
  41. }
  42. #if DBG_HDL
  43. RouteList->ListHeader.ObjectHeader.TypeSign = ROUTE_LIST_ALLOC;
  44. RouteList->ListHeader.HandleType = ROUTE_LIST_TYPE;
  45. #endif
  46. InitializeListHead(&RouteList->ListHead);
  47. #if DBG_HDL
  48. //
  49. // Insert into list of handles opened by entity
  50. //
  51. ACQUIRE_OPEN_HANDLES_LOCK(Entity);
  52. InsertTailList(&Entity->OpenHandles, &RouteList->ListHeader.HandlesLE);
  53. RELEASE_OPEN_HANDLES_LOCK(Entity);
  54. #endif
  55. REFERENCE_ENTITY(Entity, LIST_REF);
  56. //
  57. // Make a handle to the route list and return
  58. //
  59. *RouteListHandle = MAKE_HANDLE_FROM_POINTER(RouteList);
  60. return NO_ERROR;
  61. }
  62. DWORD
  63. WINAPI
  64. RtmInsertInRouteList (
  65. IN RTM_ENTITY_HANDLE RtmRegHandle,
  66. IN RTM_ROUTE_LIST_HANDLE RouteListHandle OPTIONAL,
  67. IN UINT NumRoutes,
  68. IN PRTM_ROUTE_HANDLE RouteHandles
  69. )
  70. /*++
  71. Routine Description:
  72. Inserts a set of routes into the route list. If any route
  73. is already in another route list, it is removed from this
  74. old list in the process.
  75. Arguments:
  76. RtmRegHandle - RTM registration handle for calling entity
  77. RouteListHandle - Handle to the route list into which we are
  78. moving the routes to; if this argument is
  79. NULL then we are just removing the routes
  80. from the route lists to which they belonged
  81. NumRoutes - Num. of route handles in the input buffer
  82. RouteHandles - Array of handles to insert into the new list
  83. Return Value:
  84. Status of the operation
  85. --*/
  86. {
  87. PENTITY_INFO Entity;
  88. PROUTE_LIST RouteList;
  89. PROUTE_INFO Route;
  90. UINT i;
  91. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  92. RouteList = NULL;
  93. if (ARGUMENT_PRESENT(RouteListHandle))
  94. {
  95. VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
  96. }
  97. ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
  98. for (i = 0; i < NumRoutes; i++)
  99. {
  100. Route = ROUTE_FROM_HANDLE(RouteHandles[i]);
  101. ASSERT(Route->RouteInfo.RouteOwner == RtmRegHandle);
  102. //
  103. // Remove from old list if it was present in one
  104. //
  105. if (!IsListEmpty(&Route->RouteListLE))
  106. {
  107. RemoveEntryList(&Route->RouteListLE);
  108. DEREFERENCE_ROUTE(Route, LIST_REF);
  109. }
  110. //
  111. // Insert in the new list if a new list is specified
  112. //
  113. if (RouteList)
  114. {
  115. InsertTailList(&RouteList->ListHead, &Route->RouteListLE);
  116. REFERENCE_ROUTE(Route, LIST_REF);
  117. }
  118. }
  119. RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
  120. return NO_ERROR;
  121. }
  122. DWORD
  123. WINAPI
  124. RtmCreateRouteListEnum (
  125. IN RTM_ENTITY_HANDLE RtmRegHandle,
  126. IN RTM_ROUTE_LIST_HANDLE RouteListHandle,
  127. OUT PRTM_ENUM_HANDLE RtmEnumHandle
  128. )
  129. /*++
  130. Routine Description:
  131. Creates a enumeration on routes in the specified route list.
  132. Arguments:
  133. RtmRegHandle - RTM registration handle for calling entity,
  134. RouteListHandle - Handle to route list whose routes we want,
  135. RtmEnumHandle - Handle to this enumeration, which is used
  136. in calls to get routes in the route list
  137. Return Value:
  138. Status of the operation
  139. --*/
  140. {
  141. PENTITY_INFO Entity;
  142. PROUTE_LIST RouteList;
  143. PLIST_ENUM Enum;
  144. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  145. VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
  146. //
  147. // Create and initialize an list enumeration block
  148. //
  149. Enum = (PLIST_ENUM) AllocNZeroObject(sizeof(LIST_ENUM));
  150. if (Enum == NULL)
  151. {
  152. return ERROR_NOT_ENOUGH_MEMORY;
  153. }
  154. #if DBG_HDL
  155. Enum->EnumHeader.ObjectHeader.TypeSign = LIST_ENUM_ALLOC;
  156. #endif
  157. Enum->EnumHeader.HandleType = LIST_ENUM_TYPE;
  158. Enum->RouteList = RouteList;
  159. //
  160. // Insert marker into the route list
  161. //
  162. ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
  163. InsertHeadList(&RouteList->ListHead, &Enum->MarkerRoute.RouteListLE);
  164. RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
  165. #if DBG_HDL
  166. //
  167. // Insert into the list of handles opened by entity
  168. //
  169. ACQUIRE_OPEN_HANDLES_LOCK(Entity);
  170. InsertTailList(&Entity->OpenHandles,&Enum->EnumHeader.HandlesLE);
  171. RELEASE_OPEN_HANDLES_LOCK(Entity);
  172. #endif
  173. REFERENCE_ENTITY(Entity, ENUM_REF);
  174. //
  175. // Make a handle to the enum block and return
  176. //
  177. *RtmEnumHandle = MAKE_HANDLE_FROM_POINTER(Enum);
  178. return NO_ERROR;
  179. }
  180. DWORD
  181. WINAPI
  182. RtmGetListEnumRoutes (
  183. IN RTM_ENTITY_HANDLE RtmRegHandle,
  184. IN RTM_ENUM_HANDLE EnumHandle,
  185. IN OUT PUINT NumRoutes,
  186. OUT PRTM_ROUTE_HANDLE RouteHandles
  187. )
  188. /*++
  189. Routine Description:
  190. Enumerates a set of routes in the route list starting from
  191. a specific route (if given) or the start of the route list.
  192. Arguments:
  193. RtmRegHandle - RTM registration handle for calling entity,
  194. EnumHandle - Handle to enumeration on the route list,
  195. NumRoutes - Max. number of routes to fill is passed in,
  196. Num. of routes actually copied is returned.
  197. RouteHandles - Output buffer where route handles are retd.
  198. Return Value:
  199. Status of the operation
  200. --*/
  201. {
  202. PENTITY_INFO Entity;
  203. PLIST_ENUM ListEnum;
  204. PROUTE_INFO Route;
  205. UINT RoutesInput;
  206. PLIST_ENTRY p;
  207. RoutesInput = *NumRoutes;
  208. *NumRoutes = 0;
  209. //
  210. // Do some validation checks on the input params
  211. //
  212. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  213. VALIDATE_LIST_ENUM_HANDLE(EnumHandle, &ListEnum);
  214. if (RoutesInput > Entity->OwningAddrFamily->MaxHandlesInEnum)
  215. {
  216. return ERROR_INVALID_PARAMETER;
  217. }
  218. //
  219. // List routes starting from the enum's marker route
  220. //
  221. ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
  222. for (p = ListEnum->MarkerRoute.RouteListLE.Flink;
  223. p != &ListEnum->RouteList->ListHead;
  224. p = p->Flink)
  225. {
  226. if (*NumRoutes >= RoutesInput)
  227. {
  228. break;
  229. }
  230. Route = CONTAINING_RECORD(p, ROUTE_INFO, RouteListLE);
  231. //
  232. // If this route is not a marker route, copy handle
  233. //
  234. if (Route->RouteInfo.DestHandle)
  235. {
  236. RouteHandles[(*NumRoutes)++] = MAKE_HANDLE_FROM_POINTER(Route);
  237. REFERENCE_ROUTE(Route, HANDLE_REF);
  238. }
  239. }
  240. //
  241. // Re-adjust the marker to reflect its new posn
  242. //
  243. RemoveEntryList(&ListEnum->MarkerRoute.RouteListLE);
  244. InsertTailList(p, &ListEnum->MarkerRoute.RouteListLE);
  245. RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
  246. return NO_ERROR;
  247. }
  248. DWORD
  249. WINAPI
  250. RtmDeleteRouteList (
  251. IN RTM_ENTITY_HANDLE RtmRegHandle,
  252. IN RTM_ROUTE_LIST_HANDLE RouteListHandle
  253. )
  254. /*++
  255. Routine Description:
  256. Removes all routes on an entity specific list and frees
  257. resources allocated to it.
  258. Arguments:
  259. RtmRegHandle - RTM registration handle for calling entity,
  260. RouteListHandle - Handle to the route list to delete.
  261. Return Value:
  262. Status of the operation
  263. --*/
  264. {
  265. PENTITY_INFO Entity;
  266. PROUTE_LIST RouteList;
  267. PLIST_ENUM Enum;
  268. PROUTE_INFO Route;
  269. PLIST_ENTRY p;
  270. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  271. VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
  272. ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
  273. //
  274. // Remove each route from the route list
  275. //
  276. while (!IsListEmpty(&RouteList->ListHead))
  277. {
  278. p = RemoveHeadList(&RouteList->ListHead);
  279. Route = CONTAINING_RECORD(p, ROUTE_INFO, RouteListLE);
  280. if (Route->RouteInfo.DestHandle)
  281. {
  282. // This is an actual route in the list
  283. DEREFERENCE_ROUTE(Route, LIST_REF);
  284. }
  285. else
  286. {
  287. // This is a marker route for an enum
  288. Enum = CONTAINING_RECORD(Route, LIST_ENUM, MarkerRoute);
  289. #if DBG_HDL
  290. //
  291. // Remove from the list of handles opened by entity
  292. //
  293. ACQUIRE_OPEN_HANDLES_LOCK(Entity);
  294. RemoveEntryList(&Enum->EnumHeader.HandlesLE);
  295. RELEASE_OPEN_HANDLES_LOCK(Entity);
  296. #endif
  297. DEREFERENCE_ENTITY(Entity, ENUM_REF);
  298. // Free the memory allocated for the enum and continue
  299. #if DBG_HDL
  300. Enum->EnumHeader.ObjectHeader.TypeSign = LIST_ENUM_FREED;
  301. #endif
  302. FreeObject(Enum);
  303. }
  304. }
  305. RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
  306. #if DBG_HDL
  307. //
  308. // Remove from the list of handles opened by entity
  309. //
  310. ACQUIRE_OPEN_HANDLES_LOCK(Entity);
  311. RemoveEntryList(&RouteList->ListHeader.HandlesLE);
  312. RELEASE_OPEN_HANDLES_LOCK(Entity);
  313. #endif
  314. DEREFERENCE_ENTITY(Entity, LIST_REF);
  315. // Free the memory allocated for the list and return
  316. #if DBG_HDL
  317. RouteList->ListHeader.ObjectHeader.TypeSign = ROUTE_LIST_FREED;
  318. #endif
  319. FreeObject(RouteList);
  320. return NO_ERROR;
  321. }