mirror of
https://github.com/reactos/reactos.git
synced 2024-11-06 06:33:08 +00:00
342 lines
8.7 KiB
C
342 lines
8.7 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Winlogon
|
|
* FILE: base/system/winlogon/notify.c
|
|
* PURPOSE: Logon notifications
|
|
* PROGRAMMERS: Eric Kohl
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "winlogon.h"
|
|
|
|
/* GLOBALS ******************************************************************/
|
|
|
|
|
|
// void Event_Handler_Function_Name(PWLX_NOTIFICATION_INFO pInfo);
|
|
typedef VOID (WINAPI *PWLX_NOTIFY_HANDLER)(PWLX_NOTIFICATION_INFO pInfo);
|
|
|
|
static PSTR FuncNames[LastHandler] =
|
|
{
|
|
"Logon",
|
|
"Logoff",
|
|
"Lock",
|
|
"Unlock",
|
|
"Startup",
|
|
"Shutdown",
|
|
"StartScreenSaver",
|
|
"StopScreenSaver",
|
|
"Disconnect",
|
|
"Reconnect",
|
|
"StartShell",
|
|
"PostShell"
|
|
};
|
|
|
|
typedef struct _NOTIFICATION_ITEM
|
|
{
|
|
LIST_ENTRY ListEntry;
|
|
|
|
HINSTANCE hInstance;
|
|
BOOL bEnabled;
|
|
BOOL bAsynchronous;
|
|
BOOL bSafe;
|
|
BOOL bImpersonate;
|
|
BOOL bSmartCardLogon;
|
|
DWORD dwMaxWait;
|
|
PWLX_NOTIFY_HANDLER Handler[LastHandler];
|
|
} NOTIFICATION_ITEM, *PNOTIFICATION_ITEM;
|
|
|
|
|
|
static LIST_ENTRY NotificationDllListHead;
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
PWLX_NOTIFY_HANDLER
|
|
GetNotificationHandler(
|
|
HKEY hDllKey,
|
|
HINSTANCE hInstance,
|
|
PSTR pNotification)
|
|
{
|
|
CHAR szFuncBuffer[128];
|
|
DWORD dwSize;
|
|
DWORD dwType;
|
|
LONG lError;
|
|
|
|
dwSize = 128;
|
|
lError = RegQueryValueExA(hDllKey,
|
|
pNotification,
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)szFuncBuffer,
|
|
&dwSize);
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
return (PWLX_NOTIFY_HANDLER)GetProcAddress(hInstance, szFuncBuffer);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
LoadNotificationDll(
|
|
HKEY hNotifyKey,
|
|
PWSTR pKeyName)
|
|
{
|
|
HKEY hDllKey = NULL;
|
|
PNOTIFICATION_ITEM NotificationDll = NULL;
|
|
LONG lError;
|
|
WCHAR szBuffer[80];
|
|
DWORD dwSize;
|
|
DWORD dwType;
|
|
HINSTANCE hInstance;
|
|
NOTIFICATION_TYPE i;
|
|
|
|
TRACE("LoadNotificationDll(%p %S)\n", hNotifyKey, pKeyName);
|
|
|
|
lError = RegOpenKeyExW(hNotifyKey,
|
|
pKeyName,
|
|
0,
|
|
KEY_READ,
|
|
&hDllKey);
|
|
if (lError != ERROR_SUCCESS)
|
|
return;
|
|
|
|
dwSize = 80 * sizeof(WCHAR);
|
|
lError = RegQueryValueExW(hDllKey,
|
|
L"DllName",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)szBuffer,
|
|
&dwSize);
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
hInstance = LoadLibraryW(szBuffer);
|
|
if (hInstance == NULL)
|
|
return;
|
|
|
|
NotificationDll = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof(NOTIFICATION_ITEM));
|
|
if (NotificationDll == NULL)
|
|
{
|
|
FreeLibrary(hInstance);
|
|
return;
|
|
}
|
|
|
|
NotificationDll->bEnabled = TRUE;
|
|
NotificationDll->dwMaxWait = 30; /* FIXME: ??? */
|
|
NotificationDll->hInstance = hInstance;
|
|
|
|
dwSize = sizeof(BOOL);
|
|
RegQueryValueExW(hDllKey,
|
|
L"Asynchronous",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->bAsynchronous,
|
|
&dwSize);
|
|
|
|
dwSize = sizeof(BOOL);
|
|
RegQueryValueExW(hDllKey,
|
|
L"Enabled",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->bEnabled,
|
|
&dwSize);
|
|
|
|
dwSize = sizeof(BOOL);
|
|
RegQueryValueExW(hDllKey,
|
|
L"Impersonate",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->bImpersonate,
|
|
&dwSize);
|
|
|
|
dwSize = sizeof(BOOL);
|
|
RegQueryValueExW(hDllKey,
|
|
L"Safe",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->bSafe,
|
|
&dwSize);
|
|
|
|
dwSize = sizeof(BOOL);
|
|
RegQueryValueExW(hDllKey,
|
|
L"SmartCardLogonNotify",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->bSmartCardLogon,
|
|
&dwSize);
|
|
|
|
dwSize = sizeof(DWORD);
|
|
RegQueryValueExW(hDllKey,
|
|
L"MaxWait",
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE)&NotificationDll->dwMaxWait,
|
|
&dwSize);
|
|
|
|
for (i = LogonHandler; i < LastHandler; i++)
|
|
{
|
|
NotificationDll->Handler[i] = GetNotificationHandler(hDllKey, hInstance, FuncNames[i]);
|
|
TRACE("%s: %p\n", FuncNames[i], NotificationDll->Handler[i]);
|
|
}
|
|
|
|
InsertHeadList(&NotificationDllListHead,
|
|
&NotificationDll->ListEntry);
|
|
}
|
|
|
|
RegCloseKey(hDllKey);
|
|
}
|
|
|
|
|
|
BOOL
|
|
InitNotifications(VOID)
|
|
{
|
|
HKEY hNotifyKey = NULL;
|
|
LONG lError;
|
|
DWORD dwIndex;
|
|
WCHAR szKeyName[80];
|
|
DWORD dwKeyName;
|
|
|
|
TRACE("InitNotifications()\n");
|
|
|
|
InitializeListHead(&NotificationDllListHead);
|
|
|
|
lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify",
|
|
0,
|
|
KEY_READ | KEY_ENUMERATE_SUB_KEYS,
|
|
&hNotifyKey);
|
|
if (lError != ERROR_SUCCESS)
|
|
{
|
|
TRACE("RegOpenKeyExW()\n");
|
|
return TRUE;
|
|
}
|
|
|
|
dwIndex = 0;
|
|
for(;;)
|
|
{
|
|
dwKeyName = 80 * sizeof(WCHAR);
|
|
lError = RegEnumKeyExW(hNotifyKey,
|
|
dwIndex,
|
|
szKeyName,
|
|
&dwKeyName,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if (lError != ERROR_SUCCESS)
|
|
break;
|
|
|
|
TRACE("Notification DLL: %S\n", szKeyName);
|
|
LoadNotificationDll(hNotifyKey, szKeyName);
|
|
|
|
dwIndex++;
|
|
}
|
|
|
|
RegCloseKey(hNotifyKey);
|
|
|
|
TRACE("InitNotifications() done\n");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
CallNotificationDlls(
|
|
PWLSESSION pSession,
|
|
NOTIFICATION_TYPE Type)
|
|
{
|
|
PLIST_ENTRY ListEntry;
|
|
PNOTIFICATION_ITEM NotificationDll;
|
|
WLX_NOTIFICATION_INFO Info;
|
|
|
|
TRACE("CallNotificationDlls()\n");
|
|
|
|
Info.Size = sizeof(WLX_NOTIFICATION_INFO);
|
|
|
|
switch (Type)
|
|
{
|
|
case LogoffHandler:
|
|
case ShutdownHandler:
|
|
Info.Flags = 3;
|
|
break;
|
|
|
|
default:
|
|
Info.Flags = 0;
|
|
break;
|
|
}
|
|
|
|
Info.UserName = NULL; //UserName;
|
|
Info.Domain = NULL; //Domain;
|
|
Info.WindowStation = pSession->InteractiveWindowStationName;
|
|
Info.hToken = pSession->UserToken;
|
|
|
|
switch (Type)
|
|
{
|
|
case LogonHandler:
|
|
case StartShellHandler:
|
|
Info.hDesktop = pSession->ApplicationDesktop;
|
|
break;
|
|
|
|
case StartScreenSaverHandler:
|
|
Info.hDesktop = pSession->ApplicationDesktop;
|
|
break;
|
|
|
|
default:
|
|
Info.hDesktop = pSession->WinlogonDesktop;
|
|
break;
|
|
}
|
|
|
|
Info.pStatusCallback = NULL;
|
|
|
|
ListEntry = NotificationDllListHead.Flink;
|
|
while (ListEntry != &NotificationDllListHead)
|
|
{
|
|
TRACE("ListEntry %p\n", ListEntry);
|
|
|
|
NotificationDll = CONTAINING_RECORD(ListEntry,
|
|
NOTIFICATION_ITEM,
|
|
ListEntry);
|
|
TRACE("NotificationDll: %p\n", NotificationDll);
|
|
if (NotificationDll != NULL && NotificationDll->bEnabled)
|
|
{
|
|
TRACE("NotificationDll->Handler: %p\n", NotificationDll->Handler[Type]);
|
|
if (NotificationDll->Handler[Type] != NULL)
|
|
NotificationDll->Handler[Type](&Info);
|
|
}
|
|
|
|
ListEntry = ListEntry->Flink;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
CleanupNotifications(VOID)
|
|
{
|
|
PLIST_ENTRY ListEntry;
|
|
PNOTIFICATION_ITEM NotificationDll;
|
|
|
|
ListEntry = NotificationDllListHead.Flink;
|
|
while (ListEntry != &NotificationDllListHead)
|
|
{
|
|
NotificationDll = CONTAINING_RECORD(ListEntry,
|
|
NOTIFICATION_ITEM,
|
|
ListEntry);
|
|
if (NotificationDll != NULL)
|
|
{
|
|
FreeLibrary(NotificationDll->hInstance);
|
|
}
|
|
|
|
ListEntry = ListEntry->Flink;
|
|
|
|
RemoveEntryList(&NotificationDll->ListEntry);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NotificationDll);
|
|
}
|
|
}
|
|
|
|
/* EOF */
|