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.

230 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name :
  4. rdpevlst.h
  5. Abstract:
  6. This manages kernel-mode pending events and event requests, organized
  7. around session ID's. All functions are reentrant. Events and requests
  8. are opaque to this module.
  9. Data stored in the list can come from paged or non-paged pool.
  10. Revision History:
  11. --*/
  12. #pragma once
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif // __cplusplus
  16. ////////////////////////////////////////////////////////////////////////
  17. //
  18. // Typedefs
  19. //
  20. //
  21. // A SESSIONLIST struct points to a list of SESSIONLISTNODE's.
  22. // Each SESSIONLISTNODE contains a list of REQUESTLISTNODE's and a list of
  23. // EVENTLISTNODE's. The requestListHead and
  24. // eventListHead fields point to the REQUESTLISTNODE lists and
  25. // the event record lists, respectively.
  26. typedef struct tagSESSIONLIST
  27. {
  28. #if DBG
  29. ULONG magicNo;
  30. #endif
  31. KSPIN_LOCK spinlock;
  32. LIST_ENTRY listHead;
  33. } SESSIONLIST, *PSESSIONLIST;
  34. typedef struct tagSESSIONLISTNODE
  35. {
  36. #if DBG
  37. ULONG magicNo;
  38. #endif
  39. ULONG sessionID;
  40. LIST_ENTRY requestListHead;
  41. LIST_ENTRY eventListHead;
  42. LIST_ENTRY listEntry;
  43. } SESSIONLISTNODE, *PSESSIONLISTNODE;
  44. typedef struct tagREQUESTLISTNODE
  45. {
  46. #if DBG
  47. ULONG magicNo;
  48. #endif
  49. PVOID request;
  50. LIST_ENTRY listEntry;
  51. } REQUESTLISTNODE, *PREQUESTLISTNODE;
  52. typedef struct tagEVENTLISTNODE
  53. {
  54. #if DBG
  55. ULONG magicNo;
  56. #endif
  57. void *event;
  58. SmartPtr<DrDevice> device;
  59. ULONG type;
  60. LIST_ENTRY listEntry;
  61. } EVENTLISTNODE, *PEVENTLISTNODE;
  62. //
  63. // External type for an event management list.
  64. //
  65. typedef PSESSIONLIST RDPEVNTLIST;
  66. typedef RDPEVNTLIST *PRDPEVNTLIST;
  67. #define RDPEVNTLIST_INVALID_LIST NULL
  68. ////////////////////////////////////////////////////////////////////////
  69. //
  70. // Lock Management Macros - Must define extern RDPEVNTLIST_LockCount
  71. // for debug builds.
  72. //
  73. #if DBG
  74. extern ULONG RDPEVNTLIST_LockCount;
  75. //
  76. // Lock the list from access via other threads.
  77. //
  78. #define RDPEVNTLIST_Lock(list, irql) \
  79. KeAcquireSpinLock(&(list)->spinlock, irql); \
  80. RDPEVNTLIST_LockCount++
  81. //
  82. // Unlock a list locked by RDPEVNTLIST_Lock
  83. //
  84. #define RDPEVNTLIST_Unlock(list, irql) \
  85. RDPEVNTLIST_LockCount--; \
  86. KeReleaseSpinLock(&(list)->spinlock, irql)
  87. #else
  88. //
  89. // Lock the list from access via other threads.
  90. //
  91. #define RDPEVNTLIST_Lock(list, irql) \
  92. KeAcquireSpinLock(&(list)->spinlock, irql)
  93. //
  94. // Unlock a list locked by RDPEVNTLIST_Lock
  95. //
  96. #define RDPEVNTLIST_Unlock(list, irql) \
  97. KeReleaseSpinLock(&(list)->spinlock, irql)
  98. #endif
  99. ////////////////////////////////////////////////////////////////////////
  100. //
  101. // Prototypes
  102. //
  103. // Create a new pending device list.
  104. RDPEVNTLIST RDPEVNTLIST_CreateNewList();
  105. // Release a pending device list.
  106. void RDPEVNTLIST_DestroyList(IN RDPEVNTLIST list);
  107. // Add a new pending event. Note that this function simply stores the void pointer.
  108. // It does not copy the data pointed to by the pointer.
  109. NTSTATUS RDPEVNTLIST_EnqueueEvent(
  110. IN RDPEVNTLIST list,
  111. IN ULONG sessionID,
  112. IN PVOID devMgmtEvent,
  113. IN ULONG type,
  114. OPTIONAL IN DrDevice *devDevice
  115. );
  116. // Requeue a pending event for the specified session at the tail of the queue,
  117. // as opposed to the head of the queue in standard FIFO fashion. Note that this
  118. // function simply stores the event pointer. It does not copy the data pointed to
  119. // by the pointer.
  120. NTSTATUS RDPEVNTLIST_RequeueEvent(
  121. IN RDPEVNTLIST list,
  122. IN ULONG sessionID,
  123. IN void *event,
  124. IN ULONG type,
  125. OPTIONAL IN DrDevice *devDevice
  126. );
  127. // Returns and removes the next pending device management event for the specified
  128. // session. The returned pointer can be cast using the returned type field.
  129. // NULL is returned if there are no more pending device mgmt events for the
  130. // specified session. Note that, if non-NULL is returned, the pointer returned is
  131. // the pointer that was passed in to RDPEVNTLIST_AddPendingDevMgmtEvent
  132. BOOL RDPEVNTLIST_DequeueEvent(
  133. IN RDPEVNTLIST list,
  134. IN ULONG sessionID,
  135. OPTIONAL IN OUT ULONG *type,
  136. PVOID *eventPtr,
  137. OPTIONAL IN OUT DrDevice **devicePtr
  138. );
  139. // Add a new pending request. Note that this function simply stores the request
  140. // pointer. It does not copy the data pointed to by the pointer.
  141. NTSTATUS RDPEVNTLIST_EnqueueRequest(
  142. IN RDPEVNTLIST list,
  143. IN ULONG sessionID,
  144. IN PVOID request
  145. );
  146. // Returns and removes the next pending request for the specified session.
  147. // NULL is returned if there are no more pending devices for the specified session.
  148. // Note that, if non-NULL is returned, the pointer returned is the pointer that was
  149. // passed in to RDPEVNTLIST_AddPendingRequest.
  150. PVOID RDPEVNTLIST_DequeueRequest(
  151. IN RDPEVNTLIST list,
  152. IN ULONG sessionID
  153. );
  154. // Get the first session ID in the set of currently managed sessions. A
  155. // session is managed if there are any pending requests or events. A session
  156. // is no longer managed when there are no longer any pending requests or events.
  157. //
  158. // This session is useful for cleaning up pending requests and pending events.
  159. BOOL RDPEVNTLLIST_GetFirstSessionID(
  160. IN RDPEVNTLIST list,
  161. IN ULONG *pSessionID
  162. );
  163. // Peek at the next pending event for the specified session, without dequeueing
  164. // it. NULL is returned if there are no more pending events for the specified
  165. // session. Note that, if non-NULL is returned, the pointer returned is the
  166. // pointer that was passed in to RDPEVNTLIST_EnqueueEvent.
  167. BOOL RDPEVNTLIST_PeekNextEvent(
  168. IN RDPEVNTLIST list,
  169. IN ULONG sessionID,
  170. PVOID *eventPtr,
  171. OPTIONAL IN OUT ULONG *type,
  172. OPTIONAL IN OUT DrDevice **devicePtr
  173. );
  174. // Dequeues a specific request from a session's request list. The dequeued request
  175. // is returned if it is found. Otherwise, NULL is returned.
  176. PVOID RDPEVNTLIST_DequeueSpecificRequest(
  177. IN RDPEVNTLIST list,
  178. IN ULONG sessionID,
  179. IN PVOID request
  180. );
  181. // Unit-Test function that can be called from a kernel-mode driver to cover all
  182. // functions implemented by this module.
  183. #ifdef DBG
  184. void RDPEVNTLIST_UnitTest();
  185. #endif
  186. #ifdef __cplusplus
  187. }
  188. #endif // __cplusplus