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.

319 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. sessmgr.cpp
  5. Abstract:
  6. Keeps track of the collection of session objects for the RDP
  7. device redirector
  8. Revision History:
  9. --*/
  10. #include "precomp.hxx"
  11. #define TRC_FILE "sessmgr"
  12. #include "trc.h"
  13. DrSessionManager::DrSessionManager()
  14. {
  15. BEGIN_FN("DrSessionManager::DrSessionManager");
  16. SetClassName("DrSessionManager");
  17. }
  18. DrSessionManager::~DrSessionManager()
  19. {
  20. BEGIN_FN("DrSessionManager::~DrSessionManager");
  21. }
  22. BOOL DrSessionManager::AddSession(SmartPtr<DrSession> &Session)
  23. {
  24. DrSession *SessionT;
  25. SmartPtr<DrSession> SessionFound;
  26. BOOL rc = FALSE;
  27. BEGIN_FN("DrSessionManager::AddSession");
  28. //
  29. // Create a new SmartPtr to track in the list
  30. //
  31. ASSERT(Session != NULL);
  32. _SessionList.LockExclusive();
  33. if (FindSessionById(Session->GetSessionId(), SessionFound)) {
  34. rc = FALSE;
  35. goto EXIT;
  36. }
  37. SessionT = Session;
  38. SessionT->AddRef();
  39. //
  40. // Add it to the list
  41. //
  42. if (_SessionList.CreateEntry((PVOID)SessionT)) {
  43. //
  44. // successfully added this entry
  45. //
  46. rc = TRUE;
  47. } else {
  48. //
  49. // Unable to add it to the list, clean up
  50. //
  51. SessionT->Release();
  52. rc = FALSE;
  53. }
  54. EXIT:
  55. _SessionList.Unlock();
  56. return rc;
  57. }
  58. BOOL DrSessionManager::OnConnect(PCHANNEL_CONNECT_IN ConnectIn,
  59. PCHANNEL_CONNECT_OUT ConnectOut)
  60. {
  61. SmartPtr<DrSession> ConnectingSession;
  62. BOOL Reconnect = FALSE;
  63. BOOL Connected = FALSE;
  64. BOOL Added = FALSE;
  65. BEGIN_FN("DrSessionManager::OnConnect");
  66. ASSERT(ConnectIn != NULL);
  67. ASSERT(ConnectOut != NULL);
  68. // Clear out the output buffer by default
  69. ConnectOut->hdr.contextData = (UINT_PTR)0;
  70. Reconnect = FindSessionById(ConnectIn->hdr.sessionID,
  71. ConnectingSession);
  72. if (Reconnect) {
  73. TRC_DBG((TB, "Reconnecting session %d",
  74. ConnectIn->hdr.sessionID));
  75. } else {
  76. TRC_DBG((TB, "Connecting session %d",
  77. ConnectIn->hdr.sessionID));
  78. ConnectingSession = new(NonPagedPool) DrSession;
  79. if (ConnectingSession != NULL) {
  80. TRC_DBG((TB, "Created new session"));
  81. if (!ConnectingSession->Initialize()) {
  82. TRC_DBG((TB, "Session couldn't initialize"));
  83. ConnectingSession = NULL;
  84. }
  85. } else {
  86. TRC_ERR((TB, "Failed to allocate new session"));
  87. }
  88. }
  89. if (ConnectingSession != NULL) {
  90. Connected = ConnectingSession->Connect(ConnectIn, ConnectOut);
  91. }
  92. if (Connected) {
  93. TRC_DBG((TB, "Session connected, adding"));
  94. if (!Reconnect) {
  95. Added = AddSession(ConnectingSession);
  96. if (!Added) {
  97. if (FindSessionById(ConnectIn->hdr.sessionID, ConnectingSession)) {
  98. Added = TRUE;
  99. }
  100. }
  101. } else {
  102. // Don't add what we found there anyway
  103. Added = TRUE;
  104. }
  105. }
  106. if (Added) {
  107. // Stash this here for the disconnect notification
  108. TRC_DBG((TB, "Added session"));
  109. ConnectingSession->AddRef();
  110. ConnectOut->hdr.contextData = (UINT_PTR)-1;
  111. }
  112. return Added;
  113. }
  114. VOID DrSessionManager::OnDisconnect(PCHANNEL_DISCONNECT_IN DisconnectIn,
  115. PCHANNEL_DISCONNECT_OUT DisconnectOut)
  116. {
  117. SmartPtr<DrSession> DisconnectingSession;
  118. BEGIN_FN("DrSessionManager::OnDisconnect");
  119. ASSERT(DisconnectIn != NULL);
  120. ASSERT(DisconnectOut != NULL);
  121. if (DisconnectIn->hdr.contextData == (UINT_PTR)-1 &&
  122. FindSessionById(DisconnectIn->hdr.sessionID, DisconnectingSession)) {
  123. TRC_NRM((TB, "Closing session for doctored client."));
  124. ASSERT(DisconnectingSession->IsValid());
  125. DisconnectingSession->Disconnect(DisconnectIn, DisconnectOut);
  126. DisconnectingSession->Release();
  127. } else {
  128. //
  129. // Must not have been a "doctored" client
  130. //
  131. TRC_NRM((TB, "Undoctored session ending"));
  132. }
  133. //
  134. // make sure the output context is blank
  135. //
  136. DisconnectOut->hdr.contextData = (UINT_PTR)0;
  137. }
  138. BOOL DrSessionManager::FindSessionById(ULONG SessionId,
  139. SmartPtr<DrSession> &SessionFound)
  140. {
  141. DrSession *SessionEnum;
  142. ListEntry *ListEnum;
  143. BOOL Found = FALSE;
  144. BEGIN_FN("DrSessionManager::FindSessionById");
  145. _SessionList.LockShared();
  146. ListEnum = _SessionList.First();
  147. while (ListEnum != NULL) {
  148. SessionEnum = (DrSession *)ListEnum->Node();
  149. if (SessionEnum->GetSessionId() == SessionId) {
  150. SessionFound = SessionEnum;
  151. //
  152. // These aren't guaranteed valid once the resource is released
  153. //
  154. SessionEnum = NULL;
  155. ListEnum = NULL;
  156. break;
  157. }
  158. ListEnum = _SessionList.Next(ListEnum);
  159. }
  160. _SessionList.Unlock();
  161. return SessionFound != NULL;
  162. }
  163. BOOL DrSessionManager::FindSessionByIdAndClient(ULONG SessionId, ULONG ClientId,
  164. SmartPtr<DrSession> &SessionFound)
  165. {
  166. DrSession *SessionEnum;
  167. ListEntry *ListEnum;
  168. BOOL Found = FALSE;
  169. BEGIN_FN("DrSessionManager::FindSessionByIdAndClient");
  170. _SessionList.LockShared();
  171. ListEnum = _SessionList.First();
  172. while (ListEnum != NULL) {
  173. SessionEnum = (DrSession *)ListEnum->Node();
  174. ASSERT(SessionEnum->IsValid());
  175. if ((SessionEnum->GetSessionId() == SessionId) &&
  176. (SessionEnum->GetClientId() == ClientId)) {
  177. SessionFound = SessionEnum;
  178. Found = TRUE;
  179. //
  180. // These aren't guaranteed valid past EndEnumeration() anyway
  181. //
  182. SessionEnum = NULL;
  183. ListEnum = NULL;
  184. break;
  185. }
  186. ListEnum = _SessionList.Next(ListEnum);
  187. }
  188. _SessionList.Unlock();
  189. return Found;
  190. }
  191. BOOL DrSessionManager::FindSessionByClientName(PWCHAR ClientName,
  192. SmartPtr<DrSession> &SessionFound)
  193. {
  194. DrSession *SessionEnum;
  195. ListEntry *ListEnum;
  196. BOOL Found = FALSE;
  197. BEGIN_FN("DrSessionManager::FindSessionByClientName");
  198. _SessionList.LockShared();
  199. ListEnum = _SessionList.First();
  200. while (ListEnum != NULL) {
  201. SessionEnum = (DrSession *)ListEnum->Node();
  202. if (_wcsicmp(SessionEnum->GetClientName(), ClientName) == 0) {
  203. SessionFound = SessionEnum;
  204. //
  205. // These aren't guaranteed valid once the resource is released
  206. //
  207. SessionEnum = NULL;
  208. ListEnum = NULL;
  209. break;
  210. }
  211. ListEnum = _SessionList.Next(ListEnum);
  212. }
  213. _SessionList.Unlock();
  214. return SessionFound != NULL;
  215. }
  216. VOID DrSessionManager::Remove(DrSession *Session)
  217. {
  218. DrSession *SessionEnum;
  219. ListEntry *ListEnum;
  220. BOOL Found = FALSE;
  221. BEGIN_FN("DrSessionManager::Remove");
  222. _SessionList.LockExclusive();
  223. ListEnum = _SessionList.First();
  224. while (ListEnum != NULL) {
  225. SessionEnum = (DrSession *)ListEnum->Node();
  226. ASSERT(SessionEnum->IsValid());
  227. if (SessionEnum == Session) {
  228. Found = TRUE;
  229. _SessionList.RemoveEntry(ListEnum);
  230. //
  231. // These aren't guaranteed valid past EndEnumeration() anyway
  232. //
  233. SessionEnum = NULL;
  234. ListEnum = NULL;
  235. break;
  236. }
  237. ListEnum = _SessionList.Next(ListEnum);
  238. }
  239. _SessionList.Unlock();
  240. }