[LSASRV] Implement and call the policy change notification routine
[reactos.git] / dll / win32 / lsasrv / notify.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: LSA policy change notifications
5 * COPYRIGHT: Eric Kohl 2018
6 */
7
8 #include "lsasrv.h"
9
10 typedef struct _LSA_NOTIFICATION_ENTRY
11 {
12 LIST_ENTRY Entry;
13 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass;
14 HANDLE EventHandle;
15 } LSA_NOTIFICATION_ENTRY, *PLSA_NOTIFICATION_ENTRY;
16
17 /* GLOBALS *****************************************************************/
18
19 static LIST_ENTRY NotificationListHead;
20 static RTL_RESOURCE NotificationListLock;
21
22
23 /* FUNCTIONS ***************************************************************/
24
25 VOID
26 LsapInitNotificationList(VOID)
27 {
28 InitializeListHead(&NotificationListHead);
29 RtlInitializeResource(&NotificationListLock);
30 }
31
32
33 static
34 PLSA_NOTIFICATION_ENTRY
35 LsapGetNotificationEntry(
36 HANDLE EventHandle,
37 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass)
38 {
39 PLIST_ENTRY NotificationEntry;
40 PLSA_NOTIFICATION_ENTRY CurrentNotification;
41
42 NotificationEntry = NotificationListHead.Flink;
43 while (NotificationEntry != &NotificationListHead)
44 {
45 CurrentNotification = CONTAINING_RECORD(NotificationEntry, LSA_NOTIFICATION_ENTRY, Entry);
46
47 if ((CurrentNotification->EventHandle == EventHandle) &&
48 (CurrentNotification->InformationClass == InformationClass))
49 return CurrentNotification;
50
51 NotificationEntry = NotificationEntry->Flink;
52 }
53
54 return NULL;
55 }
56
57
58 NTSTATUS
59 LsapRegisterNotification(
60 PLSA_API_MSG pRequestMsg)
61 {
62 PLSA_NOTIFICATION_ENTRY pEntry;
63 NTSTATUS Status = STATUS_SUCCESS;
64
65 FIXME("LsapRegisterNotification(%p)\n", pRequestMsg);
66
67 /* Acquire the notification list lock exclusively */
68 RtlAcquireResourceExclusive(&NotificationListLock, TRUE);
69
70 if (pRequestMsg->PolicyChangeNotify.Request.Register)
71 {
72 /* Register the notification event */
73 pEntry = RtlAllocateHeap(RtlGetProcessHeap(),
74 HEAP_ZERO_MEMORY,
75 sizeof(LSA_NOTIFICATION_ENTRY));
76 if (pEntry == NULL)
77 {
78 Status = STATUS_INSUFFICIENT_RESOURCES;
79 goto done;
80 }
81
82 pEntry->InformationClass = pRequestMsg->PolicyChangeNotify.Request.InformationClass;
83 pEntry->EventHandle = pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle;
84
85 InsertHeadList(&NotificationListHead,
86 &pEntry->Entry);
87 }
88 else
89 {
90 /* Unregister the notification event */
91 pEntry = LsapGetNotificationEntry(pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle,
92 pRequestMsg->PolicyChangeNotify.Request.InformationClass);
93 if (pEntry == NULL)
94 {
95 Status = STATUS_INVALID_HANDLE;
96 goto done;
97 }
98
99 RemoveEntryList(&pEntry->Entry);
100 RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
101 }
102
103 done:
104 /* Release the notification list lock */
105 RtlReleaseResource(&NotificationListLock);
106
107 return Status;
108 }
109
110
111 VOID
112 LsapNotifyPolicyChange(
113 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass)
114 {
115 PLIST_ENTRY NotificationEntry;
116 PLSA_NOTIFICATION_ENTRY CurrentNotification;
117
118 FIXME("LsapNotifyPolicyChange(%lu)\n", InformationClass);
119
120 /* Acquire the notification list lock shared */
121 RtlAcquireResourceShared(&NotificationListLock, TRUE);
122
123 NotificationEntry = NotificationListHead.Flink;
124 while (NotificationEntry != &NotificationListHead)
125 {
126 CurrentNotification = CONTAINING_RECORD(NotificationEntry, LSA_NOTIFICATION_ENTRY, Entry);
127
128 if (CurrentNotification->InformationClass == InformationClass)
129 {
130 FIXME("Notify event %p\n", CurrentNotification->EventHandle);
131
132 }
133
134 NotificationEntry = NotificationEntry->Flink;
135 }
136
137 /* Release the notification list lock */
138 RtlReleaseResource(&NotificationListLock);
139 }
140
141 /* EOF */