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.

193 lines
5.7 KiB

  1. // ts.cpp : Server side code for terminal server event stuff
  2. //
  3. // Created by FrankYe on 7/3/2000
  4. //
  5. #include <windows.h>
  6. #include <wtsapi32.h>
  7. #include "debug.h"
  8. #include "list.h"
  9. #include "service.h"
  10. #include "audiosrv.h"
  11. #include "agfxs.h"
  12. #include "ts.h"
  13. //=============================================================================
  14. //=== Global data ===
  15. //=============================================================================
  16. CListSessionNotifications *gplistSessionNotifications;
  17. //=============================================================================
  18. //=== debug helpers ===
  19. //=============================================================================
  20. #ifdef DBG
  21. PTSTR astrWtsEvent[] = {
  22. NULL,
  23. TEXT("WTS_CONSOLE_CONNECT"),
  24. TEXT("WTS_CONSOLE_DISCONNECT"),
  25. TEXT("WTS_REMOTE_CONNECT"),
  26. TEXT("WTS_REMOTE_DISCONNECT"),
  27. TEXT("WTS_SESSION_LOGON"),
  28. TEXT("WTS_SESSION_LOGOFF")
  29. };
  30. #endif
  31. //=============================================================================
  32. //=== xxx ===
  33. //=============================================================================
  34. DWORD ServiceSessionChange(DWORD EventType, LPVOID EventData)
  35. {
  36. PWTSSESSION_NOTIFICATION pWtsNotification = (PWTSSESSION_NOTIFICATION)EventData;
  37. POSITION pos;
  38. // dprintf(TEXT("ServiceSessionChange: %s on session %d\n"), astrWtsEvent[EventType], pWtsNotification->dwSessionId);
  39. GFX_SessionChange(EventType, EventData);
  40. gplistSessionNotifications->Lock();
  41. pos = gplistSessionNotifications->GetHeadPosition();
  42. while (pos) {
  43. PSESSIONNOTIFICATION pNotification;
  44. pNotification = gplistSessionNotifications->GetNext(pos);
  45. if (pWtsNotification->dwSessionId == pNotification->SessionId) {
  46. SetEvent(pNotification->Event);
  47. }
  48. }
  49. gplistSessionNotifications->Unlock();
  50. return NO_ERROR;
  51. }
  52. long s_winmmRegisterSessionNotificationEvent(IN unsigned long dwProcessId,
  53. IN RHANDLE inhEvent,
  54. OUT PHANDLE_SESSIONNOTIFICATION phNotification)
  55. {
  56. PSESSIONNOTIFICATION pNotification;
  57. HANDLE hEvent;
  58. LONG lresult;
  59. ASSERT(gplistSessionNotifications);
  60. hEvent = (HANDLE)inhEvent;
  61. pNotification = new SESSIONNOTIFICATION;
  62. if (pNotification) {
  63. if (ProcessIdToSessionId(dwProcessId, &pNotification->SessionId))
  64. {
  65. HANDLE hClientProcess;
  66. hClientProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
  67. if (hClientProcess) {
  68. if (DuplicateHandle(hClientProcess, hEvent,
  69. GetCurrentProcess(), &pNotification->Event,
  70. EVENT_MODIFY_STATE, FALSE, 0))
  71. {
  72. POSITION posNotification;
  73. posNotification = gplistSessionNotifications->AddTail(pNotification);
  74. if (posNotification)
  75. {
  76. *phNotification = posNotification;
  77. lresult = NO_ERROR;
  78. } else {
  79. lresult = ERROR_OUTOFMEMORY;
  80. }
  81. if (lresult) {
  82. CloseHandle(pNotification->Event);
  83. }
  84. } else {
  85. lresult = GetLastError();
  86. }
  87. CloseHandle(hClientProcess);
  88. } else {
  89. lresult = GetLastError();
  90. }
  91. } else {
  92. lresult = GetLastError();
  93. }
  94. if (lresult) {
  95. delete pNotification;
  96. }
  97. } else {
  98. lresult = ERROR_OUTOFMEMORY;
  99. }
  100. return lresult;
  101. }
  102. long s_winmmUnregisterSessionNotification(IN OUT PHANDLE_SESSIONNOTIFICATION phNotification)
  103. {
  104. POSITION posNotification;
  105. LONG lresult;
  106. posNotification = (POSITION)*phNotification;
  107. if (posNotification) {
  108. PSESSIONNOTIFICATION pNotification;
  109. pNotification = gplistSessionNotifications->GetAt(posNotification);
  110. gplistSessionNotifications->RemoveAt(posNotification);
  111. CloseHandle(pNotification->Event);
  112. delete pNotification;
  113. *phNotification = NULL;
  114. lresult = NO_ERROR;
  115. } else {
  116. lresult = ERROR_INVALID_PARAMETER;
  117. }
  118. return lresult;
  119. }
  120. long s_winmmSessionConnectState(IN unsigned long dwProcessId, OUT int *outConnectState)
  121. {
  122. DWORD dwSessionId;
  123. LONG lresult;
  124. if (ProcessIdToSessionId(dwProcessId, &dwSessionId)) {
  125. INT *pConnectState;
  126. DWORD BytesReturned;
  127. BOOL fresult;
  128. fresult = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
  129. dwSessionId,
  130. WTSConnectState,
  131. (LPTSTR*)&pConnectState,
  132. &BytesReturned);
  133. if (fresult) {
  134. ASSERT(BytesReturned == sizeof(*pConnectState));
  135. *outConnectState = *pConnectState;
  136. WTSFreeMemory(pConnectState);
  137. lresult = NO_ERROR;
  138. } else {
  139. lresult = GetLastError();
  140. }
  141. } else {
  142. lresult = GetLastError();
  143. }
  144. return lresult;
  145. }
  146. void __RPC_USER HANDLE_SESSIONNOTIFICATION_rundown(HANDLE_SESSIONNOTIFICATION hNotification)
  147. {
  148. ASSERT(SERVICE_STOPPED != ssStatus.dwCurrentState);
  149. if (SERVICE_STOPPED == ssStatus.dwCurrentState) return;
  150. s_winmmUnregisterSessionNotification(&hNotification);
  151. }