xref: /reactos/base/services/shsvcs/thmserver.c (revision 9393fc32)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:        See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:          ReactOS kernel
4c2c66affSColin Finck  * FILE:             base/services/thmsvc/thmserver.c
5c2c66affSColin Finck  * PURPOSE:          Themes server
6c2c66affSColin Finck  * PROGRAMMER:       Giannis Adamopoulos
7c2c66affSColin Finck  */
8c2c66affSColin Finck 
9c2c66affSColin Finck /*
10c2c66affSColin Finck  * NOTE:
11c2c66affSColin Finck  * ThemeWaitForServiceReady and ThemeWatchForStart are called from msgina
12c2c66affSColin Finck  * so all the functions in this file run in the context of winlogon
13c2c66affSColin Finck  */
14c2c66affSColin Finck 
15c2c66affSColin Finck /* INCLUDES *****************************************************************/
16c2c66affSColin Finck 
17c2c66affSColin Finck #include <windows.h>
18c2c66affSColin Finck #include <uxtheme.h>
19c2c66affSColin Finck #include <uxundoc.h>
20c2c66affSColin Finck #include <wine/debug.h>
21c2c66affSColin Finck 
22c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(shsvcs);
23c2c66affSColin Finck 
24c2c66affSColin Finck /* GLOBALS ******************************************************************/
25c2c66affSColin Finck 
26c2c66affSColin Finck static WCHAR ServiceName[] = L"Themes";
27c2c66affSColin Finck 
28c2c66affSColin Finck HANDLE hThemeStartWaitObject, hThemeStopWaitObject, hThemeServiceWaitObject;
29c2c66affSColin Finck HANDLE hStartEvent, hStopEvent, hServiceProcess;
30c2c66affSColin Finck 
31511ad21fSAmine Khaldi BOOL WINAPI ThemeWatchForStart(VOID);
32c2c66affSColin Finck 
33c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
34c2c66affSColin Finck 
35c2c66affSColin Finck static
36c2c66affSColin Finck HANDLE
GetThemeServiceProcessHandle(VOID)37511ad21fSAmine Khaldi GetThemeServiceProcessHandle(VOID)
38c2c66affSColin Finck {
39c2c66affSColin Finck     SC_HANDLE scm, service;
40c2c66affSColin Finck     SERVICE_STATUS_PROCESS status;
41c2c66affSColin Finck     DWORD dummy;
42c2c66affSColin Finck     HANDLE ret;
43c2c66affSColin Finck 
44c2c66affSColin Finck     if (!(scm = OpenSCManagerW( NULL, NULL, 0 )))
45c2c66affSColin Finck     {
46c2c66affSColin Finck         ERR( "failed to open service manager\n" );
47c2c66affSColin Finck         return NULL;
48c2c66affSColin Finck     }
49c2c66affSColin Finck     if (!(service = OpenServiceW( scm, ServiceName, SERVICE_QUERY_STATUS )))
50c2c66affSColin Finck     {
51c2c66affSColin Finck         ERR( "failed to open themes service\n" );
52c2c66affSColin Finck         CloseServiceHandle( scm );
53c2c66affSColin Finck         return NULL;
54c2c66affSColin Finck     }
55c2c66affSColin Finck 
56c2c66affSColin Finck     if (!QueryServiceStatusEx( service, SC_STATUS_PROCESS_INFO,
57c2c66affSColin Finck                                   (BYTE *)&status, sizeof(status), &dummy ))
58c2c66affSColin Finck     {
59c2c66affSColin Finck         ERR("QueryServiceStatusEx failed\n");
60c2c66affSColin Finck         CloseServiceHandle( service );
61c2c66affSColin Finck         CloseServiceHandle( scm );
62c2c66affSColin Finck         return NULL;
63c2c66affSColin Finck     }
64c2c66affSColin Finck 
65c2c66affSColin Finck     ret = OpenProcess(SYNCHRONIZE, FALSE, status.dwProcessId);
66c2c66affSColin Finck 
67c2c66affSColin Finck     CloseServiceHandle( service );
68c2c66affSColin Finck     CloseServiceHandle( scm );
69c2c66affSColin Finck 
70c2c66affSColin Finck     return ret;
71c2c66affSColin Finck }
72c2c66affSColin Finck 
73c2c66affSColin Finck static
74c2c66affSColin Finck VOID
75c2c66affSColin Finck CALLBACK
ThemeStopCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired)76c2c66affSColin Finck ThemeStopCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
77c2c66affSColin Finck {
78c2c66affSColin Finck     CloseHandle(hServiceProcess);
79c2c66affSColin Finck     UnregisterWait(hThemeServiceWaitObject);
80c2c66affSColin Finck 
81c2c66affSColin Finck     ThemeWatchForStart();
82c2c66affSColin Finck     ThemeHooksRemove();
83c2c66affSColin Finck }
84c2c66affSColin Finck 
85c2c66affSColin Finck static
86c2c66affSColin Finck VOID
87c2c66affSColin Finck CALLBACK
ThemeServiceDiedCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired)88c2c66affSColin Finck ThemeServiceDiedCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
89c2c66affSColin Finck {
90c2c66affSColin Finck     /* The theme service died and we don't know if it could set its events properly */
91c2c66affSColin Finck     ResetEvent(hStartEvent);
92c2c66affSColin Finck     ResetEvent(hStopEvent);
93c2c66affSColin Finck 
94*5a5ba1adSThomas Faber     CloseHandle(hServiceProcess);
95*5a5ba1adSThomas Faber     UnregisterWait(hThemeStopWaitObject);
96*5a5ba1adSThomas Faber     ThemeWatchForStart();
97*5a5ba1adSThomas Faber     ThemeHooksRemove();
98c2c66affSColin Finck }
99c2c66affSColin Finck 
100c2c66affSColin Finck static
101c2c66affSColin Finck VOID
102c2c66affSColin Finck CALLBACK
ThemeStartCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired)103c2c66affSColin Finck ThemeStartCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
104c2c66affSColin Finck {
105c2c66affSColin Finck     hServiceProcess = GetThemeServiceProcessHandle();
106c2c66affSColin Finck 
107*5a5ba1adSThomas Faber     RegisterWaitForSingleObject(&hThemeStopWaitObject, hStopEvent, ThemeStopCallback, NULL, INFINITE, WT_EXECUTEONLYONCE);
108*5a5ba1adSThomas Faber     RegisterWaitForSingleObject(&hThemeServiceWaitObject, hServiceProcess, ThemeServiceDiedCallback, NULL, INFINITE, WT_EXECUTEONLYONCE);
109c2c66affSColin Finck 
110c2c66affSColin Finck     ThemeHooksInstall();
111c2c66affSColin Finck }
112c2c66affSColin Finck 
113c2c66affSColin Finck BOOL
114c2c66affSColin Finck WINAPI
ThemeWatchForStart(VOID)115511ad21fSAmine Khaldi ThemeWatchForStart(VOID)
116c2c66affSColin Finck {
117c2c66affSColin Finck     hStartEvent = CreateEventW(NULL, TRUE, FALSE, L"Global\\ThemeStartEvent");
118c2c66affSColin Finck     hStopEvent = CreateEventW(NULL, TRUE, FALSE, L"Global\\ThemeStopEvent");
119c2c66affSColin Finck 
120*5a5ba1adSThomas Faber     RegisterWaitForSingleObject(&hThemeStartWaitObject, hStartEvent, ThemeStartCallback, NULL, INFINITE, WT_EXECUTEONLYONCE);
121c2c66affSColin Finck 
122c2c66affSColin Finck     return TRUE;
123c2c66affSColin Finck }
124c2c66affSColin Finck 
125c2c66affSColin Finck DWORD
126c2c66affSColin Finck WINAPI
ThemeWaitForServiceReady(DWORD dwTimeout)127c2c66affSColin Finck ThemeWaitForServiceReady(DWORD dwTimeout)
128c2c66affSColin Finck {
129c2c66affSColin Finck     SC_HANDLE scm, service;
130c2c66affSColin Finck     SERVICE_STATUS_PROCESS status;
131c2c66affSColin Finck     BOOL ret = FALSE;
132c2c66affSColin Finck     DWORD start_time = GetTickCount();
133c2c66affSColin Finck 
134c2c66affSColin Finck     TRACE("\n");
135c2c66affSColin Finck 
136c2c66affSColin Finck     if (!(scm = OpenSCManagerW( NULL, NULL, 0 )))
137c2c66affSColin Finck     {
138c2c66affSColin Finck         ERR( "failed to open service manager\n" );
139c2c66affSColin Finck         return FALSE;
140c2c66affSColin Finck     }
141c2c66affSColin Finck     if (!(service = OpenServiceW( scm, ServiceName, SERVICE_QUERY_STATUS )))
142c2c66affSColin Finck     {
143c2c66affSColin Finck         ERR( "failed to open themes service\n" );
144c2c66affSColin Finck         CloseServiceHandle( scm );
145c2c66affSColin Finck         return FALSE;
146c2c66affSColin Finck     }
147c2c66affSColin Finck 
148c2c66affSColin Finck     while(TRUE)
149c2c66affSColin Finck     {
150c2c66affSColin Finck         DWORD dummy;
151c2c66affSColin Finck 
152c2c66affSColin Finck         if (!QueryServiceStatusEx( service, SC_STATUS_PROCESS_INFO,
153c2c66affSColin Finck                                   (BYTE *)&status, sizeof(status), &dummy ))
154c2c66affSColin Finck             break;
155c2c66affSColin Finck         if (status.dwCurrentState == SERVICE_RUNNING)
156c2c66affSColin Finck         {
157c2c66affSColin Finck             ret = TRUE;
158c2c66affSColin Finck             break;
159c2c66affSColin Finck         }
160c2c66affSColin Finck         if (status.dwCurrentState != SERVICE_START_PENDING)
161c2c66affSColin Finck         {
162c2c66affSColin Finck             break;
163c2c66affSColin Finck         }
164c2c66affSColin Finck 
165c2c66affSColin Finck         if (GetTickCount() - start_time > dwTimeout)
166c2c66affSColin Finck         {
167c2c66affSColin Finck             break;
168c2c66affSColin Finck         }
169c2c66affSColin Finck         Sleep( 100 );
170c2c66affSColin Finck     };
171c2c66affSColin Finck 
172c2c66affSColin Finck     CloseServiceHandle( service );
173c2c66affSColin Finck     CloseServiceHandle( scm );
174c2c66affSColin Finck     return ret;
175c2c66affSColin Finck }
176c2c66affSColin Finck 
177c2c66affSColin Finck /* EOF */
178