xref: /reactos/dll/win32/lsasrv/notify.c (revision d5399189)
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 */
142