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.

443 lines
10 KiB

  1. //
  2. // connlist.c
  3. //
  4. // Handles a linked list which will keep track of all the TCLIENT2 handles.
  5. //
  6. // Why is this needed?
  7. //
  8. // I am using SetTimer() callbacks to keep track of idled scripts.
  9. // The problem is, there is no way for me to tell exactly which
  10. // handle executed which timer. The only way to do this is to keep
  11. // a list of all the handles, and their associated timer id.
  12. //
  13. // Copyright (C) 2001 Microsoft Corporation
  14. //
  15. // Author: a-devjen (Devin Jenson)
  16. //
  17. // 03-08-2001 - Fixed bug regarding last node on list not being cleaned.
  18. #include "connlist.h"
  19. // Linked handle list
  20. typedef struct _ConnList
  21. {
  22. struct _ConnList *Next;
  23. struct _ConnList *Prev;
  24. HANDLE Handle;
  25. UINT_PTR TimerId;
  26. DWORD msStartTime;
  27. } ConnList;
  28. // This is the global variable, representing the head of the list
  29. ConnList *Head = NULL;
  30. // This queue is used to prevent two threads from messing
  31. // with the list at the same time
  32. CRITICAL_SECTION ListQueue;
  33. // Indicates the number of items in the list
  34. DWORD ItemCount;
  35. DWORD AccessCount;
  36. // Internal function prototypes
  37. void T2ConnList_EnterQueue(void);
  38. void T2ConnList_LeaveQueue(void);
  39. // T2ConnList_EnterQueue
  40. //
  41. // A "safe" critical section - no critical section needed.
  42. //
  43. // No return value.
  44. void T2ConnList_EnterQueue(void)
  45. {
  46. if (ItemCount == 0 && AccessCount == 0)
  47. InitializeCriticalSection(&ListQueue);
  48. ++AccessCount;
  49. EnterCriticalSection(&ListQueue);
  50. }
  51. // T2ConnList_LeaveQueue
  52. //
  53. // A "safe" critical section - critical section automatically
  54. // deletes itself when no longer needed.
  55. //
  56. // No return value.
  57. void T2ConnList_LeaveQueue(void)
  58. {
  59. LeaveCriticalSection(&ListQueue);
  60. --AccessCount;
  61. if (ItemCount == 0 && AccessCount == 0)
  62. DeleteCriticalSection(&ListQueue);
  63. }
  64. // T2ConnList_AddHandle
  65. //
  66. // Adds a new handle to the connection list. Additionally
  67. // this will also set the TimerId and msStartTime properties
  68. // for the new entry.
  69. //
  70. // Returns TRUE if the handle was successfully added.
  71. // FALSE otherwise.
  72. BOOL T2ConnList_AddHandle(HANDLE Handle, UINT_PTR TimerId, DWORD msStartTime)
  73. {
  74. ConnList *Node;
  75. // Sanity check
  76. if (Handle == NULL || Handle == INVALID_HANDLE_VALUE)
  77. return FALSE;
  78. // Get access to the list
  79. T2ConnList_EnterQueue();
  80. Node = Head;
  81. // Loop through each item, ensuring the item does not already exist
  82. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  83. // If we didn't reach the end of the list, it already exists
  84. if (Node != NULL) {
  85. // Simply modify the parameters instead of adding it
  86. Node->TimerId = TimerId;
  87. Node->msStartTime = msStartTime;
  88. // Release access from the list
  89. T2ConnList_LeaveQueue();
  90. return TRUE;
  91. }
  92. // It doesn't exist, allocate a new node for the handle
  93. Node = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (ConnList));
  94. if (Node == NULL) {
  95. // Allocation failed, release access from the list
  96. T2ConnList_LeaveQueue();
  97. return FALSE;
  98. }
  99. // Begin adding it to the list by setting the new node at the head
  100. if (Head != NULL)
  101. Head->Prev = Node;
  102. Node->Next = Head;
  103. Head = Node;
  104. // Record the parameters
  105. Node->Handle = Handle;
  106. Node->TimerId = TimerId;
  107. Node->msStartTime = msStartTime;
  108. // Increment the number of handles in the list
  109. ++ItemCount;
  110. // Release access from the list and return
  111. T2ConnList_LeaveQueue();
  112. return TRUE;
  113. }
  114. // T2ConnList_RemoveHandle
  115. //
  116. // Removes a handle from the list if it exists.
  117. //
  118. // No return value.
  119. void T2ConnList_RemoveHandle(HANDLE Handle)
  120. {
  121. ConnList *Node;
  122. // Sanity check
  123. if (Handle == NULL || Handle == INVALID_HANDLE_VALUE)
  124. return;
  125. // Gain access to the list
  126. T2ConnList_EnterQueue();
  127. Node = Head;
  128. // First find the handle in the list
  129. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  130. // If the Node pointer is NULL, then the handle didn't exist
  131. if (Node == NULL) {
  132. // Just release access from the list, and return
  133. T2ConnList_LeaveQueue();
  134. return;
  135. }
  136. // Handle found, now unlink it from the list
  137. if (Node->Next != NULL)
  138. Node->Next->Prev = Node->Prev;
  139. if (Node->Prev != NULL)
  140. Node->Prev->Next = Node->Next;
  141. // Costin and Hammad's Fix!! Yay!!
  142. if (Node == Head)
  143. Head = Node->Next;
  144. // Free the handle itself
  145. HeapFree(GetProcessHeap(), 0, Node);
  146. // Decrement the handle count in the list
  147. --ItemCount;
  148. // Release access from the list
  149. T2ConnList_LeaveQueue();
  150. }
  151. // T2ConnList_GetData
  152. //
  153. // Gets any non-null pointer parameters for the specified
  154. // handle from the list.
  155. //
  156. // Returns TRUE if the handle was found, FALSE otherwise.
  157. BOOL T2ConnList_GetData(HANDLE Handle, UINT_PTR *TimerId, DWORD *msStartTime)
  158. {
  159. ConnList *Node;
  160. // Gain access to the list
  161. T2ConnList_EnterQueue();
  162. Node = Head;
  163. // First find the handle in the list
  164. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  165. // If the Node pointer is NULL, then the handle didn't exist
  166. if (Node == NULL) {
  167. // Just release access from the list, and return an error
  168. T2ConnList_LeaveQueue();
  169. return FALSE;
  170. }
  171. // Simply enter in the parameters
  172. if (TimerId != NULL)
  173. *TimerId = Node->TimerId;
  174. if (msStartTime != NULL)
  175. *msStartTime = Node->msStartTime;
  176. // Release access from the list, and return success
  177. T2ConnList_LeaveQueue();
  178. return TRUE;
  179. }
  180. // T2ConnList_SetData
  181. //
  182. // Sets/changes all of the handle's parameters.
  183. //
  184. // Returns TRUE if the handle was found, FALSE otherwise.
  185. BOOL T2ConnList_SetData(HANDLE Handle, UINT_PTR TimerId, DWORD msStartTime)
  186. {
  187. ConnList *Node;
  188. // Gain access to the list
  189. T2ConnList_EnterQueue();
  190. Node = Head;
  191. // First find the handle in the list
  192. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  193. // If the Node pointer is NULL, then the handle didn't exist
  194. if (Node == NULL) {
  195. // Just release access from the list, and return an error
  196. T2ConnList_LeaveQueue();
  197. return FALSE;
  198. }
  199. // Change the parameters
  200. Node->TimerId = TimerId;
  201. Node->msStartTime = msStartTime;
  202. // Release access from the list, and return success
  203. T2ConnList_LeaveQueue();
  204. return TRUE;
  205. }
  206. // T2ConnList_SetTimerId
  207. //
  208. // Sets the timer id parameter of the specified handle.
  209. //
  210. // Returns TRUE on success and FALSE on failure.
  211. BOOL T2ConnList_SetTimerId(HANDLE Handle, UINT_PTR TimerId)
  212. {
  213. ConnList *Node;
  214. // Gain access to the list
  215. T2ConnList_EnterQueue();
  216. Node = Head;
  217. // First find the handle in the list
  218. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  219. // If the Node pointer is NULL, then the handle didn't exist
  220. if (Node == NULL) {
  221. // Just release access from the list, and return an error
  222. T2ConnList_LeaveQueue();
  223. return FALSE;
  224. }
  225. // Change it
  226. Node->TimerId = TimerId;
  227. // Release access from the list, and return success
  228. T2ConnList_LeaveQueue();
  229. return TRUE;
  230. }
  231. // T2ConnList_SetStartTime
  232. //
  233. // Sets the start time parameter of the specified handle.
  234. //
  235. // Returns TRUE on success and FALSE on failure.
  236. BOOL T2ConnList_SetStartTime(HANDLE Handle, DWORD msStartTime)
  237. {
  238. ConnList *Node;
  239. // Gain access to the list
  240. T2ConnList_EnterQueue();
  241. Node = Head;
  242. // First find the handle in the list
  243. for (; Node != NULL && Node->Handle != Handle; Node = Node->Next);
  244. // If the Node pointer is NULL, then the handle didn't exist
  245. if (Node == NULL) {
  246. // Just release access from the list, and return an error
  247. T2ConnList_LeaveQueue();
  248. return FALSE;
  249. }
  250. // Change it
  251. Node->msStartTime = msStartTime;
  252. // Release access from the list, and return success
  253. T2ConnList_LeaveQueue();
  254. return TRUE;
  255. }
  256. // T2ConnList_FindHandleByTimerId
  257. //
  258. // Finds the first handle with the specified matching timer id.
  259. //
  260. // Returns the handle on success, or NULL if a handle
  261. // with the specified timer id did not existed.
  262. HANDLE T2ConnList_FindHandleByTimerId(UINT_PTR TimerId)
  263. {
  264. HANDLE Handle;
  265. ConnList *Node;
  266. // Gain access to the list
  267. T2ConnList_EnterQueue();
  268. Node = Head;
  269. // Find the first matching timer in the list
  270. for (; Node != NULL && Node->TimerId != TimerId; Node = Node->Next);
  271. // If the Node pointer is NULL, then a handle didn't exist
  272. if (Node == NULL) {
  273. // Just release access from the list, and return an error
  274. T2ConnList_LeaveQueue();
  275. return NULL;
  276. }
  277. // Found a handle, record it
  278. Handle = Node->Handle;
  279. // Release access from the list and return our found handle
  280. T2ConnList_LeaveQueue();
  281. return Handle;
  282. }
  283. // T2ConnList_FindHandleByStartTime
  284. //
  285. // Finds the first handle with the specified matching start time.
  286. //
  287. // Returns the handle on success, or NULL if a handle
  288. // with the specified start time did not exist.
  289. HANDLE T2ConnList_FindHandleByStartTime(DWORD msStartTime)
  290. {
  291. HANDLE Handle;
  292. ConnList *Node;
  293. // Gain access to the list
  294. T2ConnList_EnterQueue();
  295. Node = Head;
  296. // Find the first matching start time in the list
  297. for (; Node != NULL && Node->msStartTime != msStartTime;
  298. Node = Node->Next);
  299. // If the Node pointer is NULL, then a handle didn't exist
  300. if (Node == NULL) {
  301. // Just release access from the list, and return an error
  302. T2ConnList_LeaveQueue();
  303. return NULL;
  304. }
  305. // Found a handle, record it
  306. Handle = Node->Handle;
  307. // Release access from the list and return our found handle
  308. T2ConnList_LeaveQueue();
  309. return Handle;
  310. }