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.

285 lines
9.5 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: ThemeManagerService.cpp
  3. //
  4. // Copyright (c) 2000, Microsoft Corporation
  5. //
  6. // This file contains a class that implements the theme server service
  7. // specifics.
  8. //
  9. // History: 2000-11-29 vtan created
  10. // --------------------------------------------------------------------------
  11. #include "StandardHeader.h"
  12. #define STRSAFE_LIB
  13. #include <strsafe.h>
  14. #include "ThemeManagerService.h"
  15. #include <lpcthemes.h>
  16. #include <winsta.h>
  17. #include "Access.h"
  18. #include "StatusCode.h"
  19. const TCHAR CThemeManagerService::s_szName[] = TEXT("Themes");
  20. // --------------------------------------------------------------------------
  21. // CThemeManagerService::CThemeManagerService
  22. //
  23. // Arguments: pAPIConnection = CAPIConnection passed to base class.
  24. // pServerAPI = CServerAPI passed to base class.
  25. //
  26. // Returns: <none>
  27. //
  28. // Purpose: Constructor for CThemeManagerService.
  29. //
  30. // History: 2000-11-29 vtan created
  31. // --------------------------------------------------------------------------
  32. CThemeManagerService::CThemeManagerService (CAPIConnection *pAPIConnection, CServerAPI *pServerAPI) :
  33. CService(pAPIConnection, pServerAPI, GetName())
  34. {
  35. }
  36. // --------------------------------------------------------------------------
  37. // CThemeManagerService::~CThemeManagerService
  38. //
  39. // Arguments: <none>
  40. //
  41. // Returns: <none>
  42. //
  43. // Purpose: Destructor for CThemeManagerService.
  44. //
  45. // History: 2000-11-29 vtan created
  46. // --------------------------------------------------------------------------
  47. CThemeManagerService::~CThemeManagerService (void)
  48. {
  49. }
  50. // --------------------------------------------------------------------------
  51. // CThemeManagerService::SignalStartStop
  52. //
  53. // Arguments: BOOL fStart
  54. //
  55. // Returns: NTSTATUS
  56. //
  57. // Purpose: Used to signal that the service is starting or stopping.
  58. // In the case of serivce start, Winlogon (via
  59. // msgina) is listening for this event in its own session. This
  60. // function queues a request to execute the real work done on a
  61. // worker thread to prevent blocking the main service thread. If
  62. // this is not possible then execute the signal inline.
  63. //
  64. // History: 2000-11-29 vtan created
  65. // 2002-03-11 scotthan renamed to 'SignalStartStop' from 'Signal',
  66. // added boolean arg, add call to base class
  67. // implementation.
  68. // --------------------------------------------------------------------------
  69. NTSTATUS CThemeManagerService::SignalStartStop (BOOL fStart)
  70. {
  71. if( fStart )
  72. {
  73. if (QueueUserWorkItem(SignalSessionEvents, NULL, WT_EXECUTEDEFAULT) == FALSE)
  74. {
  75. (DWORD)SignalSessionEvents(NULL);
  76. }
  77. }
  78. return CService::SignalStartStop(fStart);
  79. }
  80. // --------------------------------------------------------------------------
  81. // CThemeManagerService::GetName
  82. //
  83. // Arguments: <none>
  84. //
  85. // Returns: const TCHAR*
  86. //
  87. // Purpose: Returns the name of the service (ThemeService).
  88. //
  89. // History: 2000-11-29 vtan created
  90. // --------------------------------------------------------------------------
  91. const TCHAR* CThemeManagerService::GetName (void)
  92. {
  93. return(s_szName);
  94. }
  95. // --------------------------------------------------------------------------
  96. // CThemeManagerService::OpenStartEvent
  97. //
  98. // Arguments: <none>
  99. //
  100. // Returns: HANDLE
  101. //
  102. // Purpose: Opens or creates the theme service recovery event. This allows
  103. // a process that has registered for the event to be signaled
  104. // when the theme server is demand started. Currently only
  105. // winlogon listens for this event and is required so that it can
  106. // reestablish a server connection and re-create the session data
  107. // which holds the hooks for theming.
  108. //
  109. // History: 2000-11-29 vtan created
  110. // --------------------------------------------------------------------------
  111. HANDLE CThemeManagerService::OpenStartEvent (DWORD dwSessionID, DWORD dwDesiredAccess)
  112. {
  113. HANDLE hEvent;
  114. NTSTATUS status;
  115. UNICODE_STRING eventName;
  116. OBJECT_ATTRIBUTES objectAttributes;
  117. WCHAR szEventName[64];
  118. if (dwSessionID == 0)
  119. {
  120. StringCchPrintfW(szEventName, ARRAYSIZE(szEventName), L"\\BaseNamedObjects\\%s", THEMES_START_EVENT_NAME);
  121. }
  122. else
  123. {
  124. StringCchPrintfW(szEventName, ARRAYSIZE(szEventName), L"\\Sessions\\%d\\BaseNamedObjects\\%s", dwSessionID, THEMES_START_EVENT_NAME);
  125. }
  126. RtlInitUnicodeString(&eventName, szEventName);
  127. InitializeObjectAttributes(&objectAttributes,
  128. &eventName,
  129. 0,
  130. NULL,
  131. NULL);
  132. status = NtOpenEvent(&hEvent, dwDesiredAccess, &objectAttributes);
  133. if (!NT_SUCCESS(status))
  134. {
  135. // Build a security descriptor for the event that allows:
  136. // S-1-5-18 NT AUTHORITY\SYSTEM EVENT_ALL_ACCESS
  137. // S-1-5-32-544 <local administrators> SYNCHRONIZE | READ_CONTROL
  138. // S-1-1-0 <everyone> SYNCHRONIZE
  139. static SID_IDENTIFIER_AUTHORITY s_SecurityNTAuthority = SECURITY_NT_AUTHORITY;
  140. static SID_IDENTIFIER_AUTHORITY s_SecurityWorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
  141. static const CSecurityDescriptor::ACCESS_CONTROL s_AccessControl[] =
  142. {
  143. {
  144. &s_SecurityNTAuthority,
  145. 1,
  146. SECURITY_LOCAL_SYSTEM_RID,
  147. 0, 0, 0, 0, 0, 0, 0,
  148. EVENT_ALL_ACCESS
  149. },
  150. {
  151. &s_SecurityNTAuthority,
  152. 2,
  153. SECURITY_BUILTIN_DOMAIN_RID,
  154. DOMAIN_ALIAS_RID_ADMINS,
  155. 0, 0, 0, 0, 0, 0,
  156. SYNCHRONIZE | READ_CONTROL
  157. },
  158. {
  159. // Review: Is synchronize for Everyone really necessary?
  160. &s_SecurityWorldAuthority,
  161. 1,
  162. SECURITY_WORLD_RID,
  163. 0, 0, 0, 0, 0, 0, 0,
  164. SYNCHRONIZE
  165. },
  166. };
  167. PSECURITY_DESCRIPTOR pSecurityDescriptor;
  168. // Build a security descriptor that allows the described access above.
  169. pSecurityDescriptor = CSecurityDescriptor::Create(ARRAYSIZE(s_AccessControl), s_AccessControl);
  170. InitializeObjectAttributes(&objectAttributes,
  171. &eventName,
  172. 0,
  173. NULL,
  174. pSecurityDescriptor);
  175. status = NtCreateEvent(&hEvent,
  176. EVENT_ALL_ACCESS,
  177. &objectAttributes,
  178. NotificationEvent,
  179. FALSE);
  180. ReleaseMemory(pSecurityDescriptor);
  181. if (!NT_SUCCESS(status))
  182. {
  183. hEvent = NULL;
  184. SetLastError(CStatusCode::ErrorCodeOfStatusCode(status));
  185. }
  186. }
  187. return(hEvent);
  188. }
  189. // --------------------------------------------------------------------------
  190. // CThemeManagerService::SignalSessionEvents
  191. //
  192. // Arguments: <none>
  193. //
  194. // Returns: HANDLE
  195. //
  196. // Purpose: Opens or creates the theme service recovery event. This allows
  197. // a process that has registered for the event to be signaled
  198. // when the theme server is demand started.
  199. //
  200. // History: 2000-11-29 vtan created
  201. // --------------------------------------------------------------------------
  202. DWORD WINAPI CThemeManagerService::SignalSessionEvents (void *pParameter)
  203. {
  204. UNREFERENCED_PARAMETER(pParameter);
  205. HANDLE hEvent;
  206. HANDLE hServer;
  207. // First try and use terminal server to enumerate the sessions available.
  208. hServer = WinStationOpenServerW(reinterpret_cast<WCHAR*>(SERVERNAME_CURRENT));
  209. if (hServer != NULL)
  210. {
  211. ULONG ulEntries;
  212. PLOGONID pLogonIDs;
  213. if (WinStationEnumerate(hServer, &pLogonIDs, &ulEntries))
  214. {
  215. ULONG ul;
  216. PLOGONID pLogonID;
  217. for (ul = 0, pLogonID = pLogonIDs; ul < ulEntries; ++ul, ++pLogonID)
  218. {
  219. if ((pLogonID->State == State_Active) || (pLogonID->State == State_Connected) || (pLogonID->State == State_Disconnected))
  220. {
  221. hEvent = OpenStartEvent(pLogonID->SessionId, EVENT_MODIFY_STATE);
  222. if (hEvent != NULL)
  223. {
  224. TBOOL(SetEvent(hEvent));
  225. TBOOL(CloseHandle(hEvent));
  226. }
  227. }
  228. }
  229. (BOOLEAN)WinStationFreeMemory(pLogonIDs);
  230. }
  231. (BOOLEAN)WinStationCloseServer(hServer);
  232. }
  233. else
  234. {
  235. // If terminal services is not available then assume session 0 only.
  236. hEvent = OpenStartEvent(0, EVENT_MODIFY_STATE);
  237. if (hEvent != NULL)
  238. {
  239. TBOOL(SetEvent(hEvent));
  240. TBOOL(CloseHandle(hEvent));
  241. }
  242. }
  243. return(0);
  244. }