ReactOS  0.4.15-dev-2771-g6d441f7
notify.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Winlogon
4  * FILE: base/system/winlogon/notify.c
5  * PURPOSE: Logon notifications
6  * PROGRAMMERS: Eric Kohl
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "winlogon.h"
12 
13 /* GLOBALS ******************************************************************/
14 
15 
16 // void Event_Handler_Function_Name(PWLX_NOTIFICATION_INFO pInfo);
18 
20 {
21  "Logon",
22  "Logoff",
23  "Lock",
24  "Unlock",
25  "Startup",
26  "Shutdown",
27  "StartScreenSaver",
28  "StopScreenSaver",
29  "Disconnect",
30  "Reconnect",
31  "StartShell",
32  "PostShell"
33 };
34 
35 typedef struct _NOTIFICATION_ITEM
36 {
48 
49 
51 
52 
53 /* FUNCTIONS *****************************************************************/
54 
55 static
56 VOID
58 {
59  WCHAR szSfcFileName[MAX_PATH];
60  PNOTIFICATION_ITEM NotificationDll;
61  DWORD dwError = ERROR_SUCCESS;
62 
63  ExpandEnvironmentStringsW(L"%windir%\\system32\\sfc.dll",
64  szSfcFileName,
65  ARRAYSIZE(szSfcFileName));
66 
67  NotificationDll = RtlAllocateHeap(RtlGetProcessHeap(),
69  sizeof(NOTIFICATION_ITEM));
70  if (NotificationDll == NULL)
71  {
72  dwError = ERROR_OUTOFMEMORY;
73  goto done;
74  }
75 
76  NotificationDll->pszDllName = RtlAllocateHeap(RtlGetProcessHeap(),
78  (wcslen(szSfcFileName) + 1) * sizeof(WCHAR));
79  if (NotificationDll->pszDllName == NULL)
80  {
81  dwError = ERROR_OUTOFMEMORY;
82  goto done;
83  }
84 
85  wcscpy(NotificationDll->pszDllName, szSfcFileName);
86 
87  NotificationDll->bEnabled = TRUE;
88  NotificationDll->dwMaxWait = 30; /* FIXME: ??? */
89  NotificationDll->bSfcNotification = TRUE;
90 
92  &NotificationDll->ListEntry);
93 
94 done:
95  if (dwError != ERROR_SUCCESS)
96  {
97  if (NotificationDll != NULL)
98  {
99  if (NotificationDll->pszDllName != NULL)
100  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll->pszDllName);
101 
102  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll);
103  }
104  }
105 }
106 
107 static
108 VOID
110  HKEY hNotifyKey,
111  PWSTR pszKeyName)
112 {
113  HKEY hDllKey = NULL;
114  PNOTIFICATION_ITEM NotificationDll = NULL;
115  DWORD dwSize, dwType;
116  DWORD dwError;
117 
118  TRACE("AddNotificationDll(%p %S)\n", hNotifyKey, pszKeyName);
119 
120  dwError = RegOpenKeyExW(hNotifyKey,
121  pszKeyName,
122  0,
123  KEY_READ,
124  &hDllKey);
125  if (dwError != ERROR_SUCCESS)
126  return;
127 
128  NotificationDll = RtlAllocateHeap(RtlGetProcessHeap(),
130  sizeof(NOTIFICATION_ITEM));
131  if (NotificationDll == NULL)
132  {
133  dwError = ERROR_OUTOFMEMORY;
134  goto done;
135  }
136 
137  NotificationDll->pszKeyName = RtlAllocateHeap(RtlGetProcessHeap(),
139  (wcslen(pszKeyName) + 1) * sizeof(WCHAR));
140  if (NotificationDll->pszKeyName == NULL)
141  {
142  dwError = ERROR_OUTOFMEMORY;
143  goto done;
144  }
145 
146  wcscpy(NotificationDll->pszKeyName, pszKeyName);
147 
148  dwSize = 0;
149  RegQueryValueExW(hDllKey,
150  L"DllName",
151  NULL,
152  &dwType,
153  NULL,
154  &dwSize);
155  if (dwSize == 0)
156  {
157  dwError = ERROR_FILE_NOT_FOUND;
158  goto done;
159  }
160 
161  NotificationDll->pszDllName = RtlAllocateHeap(RtlGetProcessHeap(),
163  dwSize);
164  if (NotificationDll->pszDllName == NULL)
165  {
166  dwError = ERROR_OUTOFMEMORY;
167  goto done;
168  }
169 
170  dwError = RegQueryValueExW(hDllKey,
171  L"DllName",
172  NULL,
173  &dwType,
174  (PBYTE)NotificationDll->pszDllName,
175  &dwSize);
176  if (dwError != ERROR_SUCCESS)
177  goto done;
178 
179  NotificationDll->bEnabled = TRUE;
180  NotificationDll->dwMaxWait = 30; /* FIXME: ??? */
181 
182  dwSize = sizeof(BOOL);
183  RegQueryValueExW(hDllKey,
184  L"Asynchronous",
185  NULL,
186  &dwType,
187  (PBYTE)&NotificationDll->bAsynchronous,
188  &dwSize);
189 
190  dwSize = sizeof(BOOL);
191  RegQueryValueExW(hDllKey,
192  L"Enabled",
193  NULL,
194  &dwType,
195  (PBYTE)&NotificationDll->bEnabled,
196  &dwSize);
197 
198  dwSize = sizeof(BOOL);
199  RegQueryValueExW(hDllKey,
200  L"Impersonate",
201  NULL,
202  &dwType,
203  (PBYTE)&NotificationDll->bImpersonate,
204  &dwSize);
205 
206  dwSize = sizeof(BOOL);
207  RegQueryValueExW(hDllKey,
208  L"Safe",
209  NULL,
210  &dwType,
211  (PBYTE)&NotificationDll->bSafe,
212  &dwSize);
213 
214  dwSize = sizeof(BOOL);
215  RegQueryValueExW(hDllKey,
216  L"SmartCardLogonNotify",
217  NULL,
218  &dwType,
219  (PBYTE)&NotificationDll->bSmartCardLogon,
220  &dwSize);
221 
222  dwSize = sizeof(DWORD);
223  RegQueryValueExW(hDllKey,
224  L"MaxWait",
225  NULL,
226  &dwType,
227  (PBYTE)&NotificationDll->dwMaxWait,
228  &dwSize);
229 
231  &NotificationDll->ListEntry);
232 
233 done:
234  if (dwError != ERROR_SUCCESS)
235  {
236  if (NotificationDll != NULL)
237  {
238  if (NotificationDll->pszKeyName != NULL)
239  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll->pszKeyName);
240 
241  if (NotificationDll->pszDllName != NULL)
242  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll->pszDllName);
243 
244  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll);
245  }
246  }
247 
248  RegCloseKey(hDllKey);
249 }
250 
251 
252 BOOL
254 {
255  HKEY hNotifyKey = NULL;
256  LONG lError;
257  DWORD dwIndex;
258  WCHAR szKeyName[80];
259  DWORD dwKeyName;
260 
261  TRACE("InitNotifications()\n");
262 
264 
266 
268  L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify",
269  0,
271  &hNotifyKey);
272  if (lError != ERROR_SUCCESS)
273  {
274  TRACE("RegOpenKeyExW()\n");
275  return TRUE;
276  }
277 
278  dwIndex = 0;
279  for(;;)
280  {
281  dwKeyName = 80 * sizeof(WCHAR);
282  lError = RegEnumKeyExW(hNotifyKey,
283  dwIndex,
284  szKeyName,
285  &dwKeyName,
286  NULL,
287  NULL,
288  NULL,
289  NULL);
290  if (lError != ERROR_SUCCESS)
291  break;
292 
293  TRACE("Notification DLL: %S\n", szKeyName);
294  AddNotificationDll(hNotifyKey, szKeyName);
295 
296  dwIndex++;
297  }
298 
299  RegCloseKey(hNotifyKey);
300 
301  TRACE("InitNotifications() done\n");
302 
303  return TRUE;
304 }
305 
306 
307 static
308 VOID
310  HKEY hNotifyKey,
311  PNOTIFICATION_ITEM NotificationDll,
314 {
315  HKEY hDllKey = NULL;
316  HMODULE hModule = NULL;
317  CHAR szFuncBuffer[128];
318  DWORD dwSize;
319  DWORD dwType;
320  DWORD dwError = ERROR_SUCCESS;
321  PWLX_NOTIFY_HANDLER pNotifyHandler;
322 
323  if (NotificationDll->bSfcNotification)
324  {
325  switch (Type)
326  {
327  case LogonHandler:
328  strcpy(szFuncBuffer, "SfcWLEventLogon");
329  break;
330 
331  case LogoffHandler:
332  strcpy(szFuncBuffer, "SfcWLEventLogoff");
333  break;
334 
335  default:
336  return;
337  }
338  }
339  else
340  {
341  dwError = RegOpenKeyExW(hNotifyKey,
342  NotificationDll->pszKeyName,
343  0,
344  KEY_READ,
345  &hDllKey);
346  if (dwError != ERROR_SUCCESS)
347  {
348  TRACE("RegOpenKeyExW()\n");
349  return;
350  }
351 
352  dwSize = sizeof(szFuncBuffer);
353  dwError = RegQueryValueExA(hDllKey,
354  FuncNames[Type],
355  NULL,
356  &dwType,
357  (PBYTE)szFuncBuffer,
358  &dwSize);
359  }
360 
361  if (dwError == ERROR_SUCCESS)
362  {
363  hModule = LoadLibraryW(NotificationDll->pszDllName);
364  if (hModule != NULL)
365  {
366  pNotifyHandler = (PWLX_NOTIFY_HANDLER)GetProcAddress(hModule, szFuncBuffer);
367  if (pNotifyHandler != NULL)
368  pNotifyHandler(pInfo);
369 
371  }
372  }
373 
374  if (hDllKey != NULL)
375  RegCloseKey(hDllKey);
376 }
377 
378 
379 VOID
381  PWLSESSION pSession,
383 {
384  PLIST_ENTRY ListEntry;
385  PNOTIFICATION_ITEM NotificationDll;
387  HKEY hNotifyKey = NULL;
388  DWORD dwError;
389 
390  TRACE("CallNotificationDlls()\n");
391 
393  L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify",
394  0,
396  &hNotifyKey);
397  if (dwError != ERROR_SUCCESS)
398  {
399  TRACE("RegOpenKeyExW()\n");
400  return;
401  }
402 
403  Info.Size = sizeof(WLX_NOTIFICATION_INFO);
404 
405  switch (Type)
406  {
407  case LogoffHandler:
408  case ShutdownHandler:
409  Info.Flags = 3;
410  break;
411 
412  default:
413  Info.Flags = 0;
414  break;
415  }
416 
417  Info.UserName = NULL; //UserName;
418  Info.Domain = NULL; //Domain;
419  Info.WindowStation = pSession->InteractiveWindowStationName;
420  Info.hToken = pSession->UserToken;
421 
422  switch (Type)
423  {
424  case LogonHandler:
425  case StartShellHandler:
426  Info.hDesktop = pSession->ApplicationDesktop;
427  break;
428 
430  Info.hDesktop = pSession->ApplicationDesktop;
431  break;
432 
433  default:
434  Info.hDesktop = pSession->WinlogonDesktop;
435  break;
436  }
437 
438  Info.pStatusCallback = NULL;
439 
440  ListEntry = NotificationDllListHead.Flink;
441  while (ListEntry != &NotificationDllListHead)
442  {
443 TRACE("ListEntry %p\n", ListEntry);
444 
445  NotificationDll = CONTAINING_RECORD(ListEntry,
447  ListEntry);
448 TRACE("NotificationDll: %p\n", NotificationDll);
449  if (NotificationDll != NULL && NotificationDll->bEnabled)
450  CallNotificationDll(hNotifyKey, NotificationDll, Type, &Info);
451 
452  ListEntry = ListEntry->Flink;
453  }
454 
455  RegCloseKey(hNotifyKey);
456 }
457 
458 
459 VOID
461 {
462  PLIST_ENTRY ListEntry;
463  PNOTIFICATION_ITEM NotificationDll;
464 
465  ListEntry = NotificationDllListHead.Flink;
466  while (ListEntry != &NotificationDllListHead)
467  {
468  NotificationDll = CONTAINING_RECORD(ListEntry,
470  ListEntry);
471  if (NotificationDll != NULL)
472  {
473  if (NotificationDll->pszKeyName != NULL)
474  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll->pszKeyName);
475 
476  if (NotificationDll->pszDllName != NULL)
477  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll->pszDllName);
478  }
479 
480  ListEntry = ListEntry->Flink;
481 
482  RemoveEntryList(&NotificationDll->ListEntry);
483 
484  RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll);
485  }
486 }
487 
488 /* EOF */
static VOID AddSfcNotification(VOID)
Definition: notify.c:57
struct _NOTIFICATION_ITEM NOTIFICATION_ITEM
enum _NOTIFICATION_TYPE NOTIFICATION_TYPE
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
#define ERROR_SUCCESS
Definition: deptool.c:10
HDESK WinlogonDesktop
Definition: winlogon.h:224
PWSTR pszKeyName
Definition: notify.c:38
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
PWSTR pszDllName
Definition: notify.c:39
uint16_t * PWSTR
Definition: typedefs.h:56
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
char CHAR
Definition: xmlstorage.h:175
HANDLE UserToken
Definition: winlogon.h:227
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static LIST_ENTRY NotificationDllListHead
Definition: notify.c:50
BOOL bAsynchronous
Definition: notify.c:41
#define BOOL
Definition: nt_native.h:43
LIST_ENTRY ListEntry
Definition: notify.c:37
#define DWORD
Definition: nt_native.h:44
HDESK ApplicationDesktop
Definition: winlogon.h:223
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOL InitNotifications(VOID)
Definition: notify.c:253
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define LoadLibraryW(x)
Definition: compat.h:606
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOL bImpersonate
Definition: notify.c:43
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:607
struct _NOTIFICATION_ITEM * PNOTIFICATION_ITEM
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
Type
Definition: Type.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL bSmartCardLogon
Definition: notify.c:44
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
LPWSTR InteractiveWindowStationName
Definition: winlogon.h:222
static VOID AddNotificationDll(HKEY hNotifyKey, PWSTR pszKeyName)
Definition: notify.c:109
#define VOID
Definition: acefi.h:82
VOID CleanupNotifications(VOID)
Definition: notify.c:460
Definition: typedefs.h:119
static PSTR FuncNames[LastHandler]
Definition: notify.c:19
VOID(WINAPI * PWLX_NOTIFY_HANDLER)(PWLX_NOTIFICATION_INFO pInfo)
Definition: notify.c:17
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:380
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DWORD dwMaxWait
Definition: notify.c:45
signed char * PSTR
Definition: retypes.h:7
#define NULL
Definition: types.h:112
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static VOID CallNotificationDll(HKEY hNotifyKey, PNOTIFICATION_ITEM NotificationDll, NOTIFICATION_TYPE Type, PWLX_NOTIFICATION_INFO pInfo)
Definition: notify.c:309
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define GetProcAddress(x, y)
Definition: compat.h:612
BOOL bSfcNotification
Definition: notify.c:46
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
struct _WLX_NOTIFICATION_INFO WLX_NOTIFICATION_INFO
BYTE * PBYTE
Definition: pedump.c:66
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
HMODULE hModule
Definition: animate.c:44
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019