https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd1f0d02bc0ecf2bea0781af2915c419871fb493

commit dd1f0d02bc0ecf2bea0781af2915c419871fb493
Author:     Eric Kohl <[email protected]>
AuthorDate: Sun Feb 21 18:05:11 2021 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Sun Feb 21 18:05:11 2021 +0100

    [LSASRV] Improve the policy change registration code and notify registered 
events
---
 dll/win32/lsasrv/notify.c | 144 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 110 insertions(+), 34 deletions(-)

diff --git a/dll/win32/lsasrv/notify.c b/dll/win32/lsasrv/notify.c
index c5233ce0bc6..34c7de7a798 100644
--- a/dll/win32/lsasrv/notify.c
+++ b/dll/win32/lsasrv/notify.c
@@ -11,7 +11,9 @@ typedef struct _LSA_NOTIFICATION_ENTRY
 {
     LIST_ENTRY Entry;
     POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass;
+    CLIENT_ID ClientId;
     HANDLE EventHandle;
+    HANDLE MappedEventHandle;
 } LSA_NOTIFICATION_ENTRY, *PLSA_NOTIFICATION_ENTRY;
 
 /* GLOBALS *****************************************************************/
@@ -33,8 +35,7 @@ LsapInitNotificationList(VOID)
 static
 PLSA_NOTIFICATION_ENTRY
 LsapGetNotificationEntry(
-    HANDLE EventHandle,
-    POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass)
+    PLSA_API_MSG pRequestMsg)
 {
     PLIST_ENTRY NotificationEntry;
     PLSA_NOTIFICATION_ENTRY CurrentNotification;
@@ -44,8 +45,10 @@ LsapGetNotificationEntry(
     {
         CurrentNotification = CONTAINING_RECORD(NotificationEntry, 
LSA_NOTIFICATION_ENTRY, Entry);
 
-        if ((CurrentNotification->EventHandle == EventHandle) &&
-            (CurrentNotification->InformationClass == InformationClass))
+        if ((CurrentNotification->ClientId.UniqueProcess == 
pRequestMsg->h.ClientId.UniqueProcess) &&
+            (CurrentNotification->ClientId.UniqueThread == 
pRequestMsg->h.ClientId.UniqueThread) &&
+            (CurrentNotification->InformationClass == 
pRequestMsg->PolicyChangeNotify.Request.InformationClass) &&
+            (CurrentNotification->EventHandle == 
pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle))
             return CurrentNotification;
 
         NotificationEntry = NotificationEntry->Flink;
@@ -55,14 +58,110 @@ LsapGetNotificationEntry(
 }
 
 
+static
 NTSTATUS
-LsapRegisterNotification(
+LsapAddNotification(
     PLSA_API_MSG pRequestMsg)
 {
     PLSA_NOTIFICATION_ENTRY pEntry;
+    HANDLE hProcess = NULL;
     NTSTATUS Status = STATUS_SUCCESS;
 
-    FIXME("LsapRegisterNotification(%p)\n", pRequestMsg);
+    TRACE("LsapAddNotification(%p)\n", pRequestMsg);
+
+    /* Allocate a new notification list entry */
+    pEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+                             HEAP_ZERO_MEMORY,
+                             sizeof(LSA_NOTIFICATION_ENTRY));
+    if (pEntry == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    /* Copy the notification data */
+    pEntry->InformationClass = 
pRequestMsg->PolicyChangeNotify.Request.InformationClass;
+    pEntry->EventHandle = 
pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle;
+    pEntry->ClientId = pRequestMsg->h.ClientId;
+
+    /* Open the client process */
+    Status = NtOpenProcess(&hProcess,
+                           PROCESS_DUP_HANDLE,
+                           NULL,
+                           pEntry->ClientId.UniqueProcess);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtOpenProcess() failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Duplicate the event handle into the current process */
+    Status = NtDuplicateObject(hProcess,
+                               pEntry->EventHandle,
+                               NtCurrentProcess(),
+                               &pEntry->MappedEventHandle,
+                               0,
+                               0,
+                               DUPLICATE_SAME_ACCESS);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtDuplicateObject() failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Insert the new entry into the notification list */
+    InsertHeadList(&NotificationListHead,
+                   &pEntry->Entry);
+
+done:
+    if (hProcess != NULL)
+        NtClose(hProcess);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (pEntry != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
+    }
+
+    return Status;
+}
+
+
+static
+NTSTATUS
+LsapRemoveNotification(
+    PLSA_API_MSG pRequestMsg)
+{
+    PLSA_NOTIFICATION_ENTRY pEntry;
+
+    TRACE("LsapRemoveNotification(%p)\n", pRequestMsg);
+
+    pEntry = LsapGetNotificationEntry(pRequestMsg);
+    if (pEntry == NULL)
+    {
+        return STATUS_INVALID_HANDLE;
+    }
+
+    /* Remove the  notification entry from the notification list */
+    RemoveEntryList(&pEntry->Entry);
+
+    /* Close the mapped event handle */
+    NtClose(pEntry->MappedEventHandle);
+
+    /* Release the notification entry */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
+
+    return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+LsapRegisterNotification(
+    PLSA_API_MSG pRequestMsg)
+{
+    NTSTATUS Status;
+
+    TRACE("LsapRegisterNotification(%p)\n", pRequestMsg);
 
     /* Acquire the notification list lock exclusively */
     RtlAcquireResourceExclusive(&NotificationListLock, TRUE);
@@ -70,37 +169,14 @@ LsapRegisterNotification(
     if (pRequestMsg->PolicyChangeNotify.Request.Register)
     {
         /* Register the notification event */
-        pEntry = RtlAllocateHeap(RtlGetProcessHeap(),
-                                 HEAP_ZERO_MEMORY,
-                                 sizeof(LSA_NOTIFICATION_ENTRY));
-        if (pEntry == NULL)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto done;
-        }
-
-        pEntry->InformationClass = 
pRequestMsg->PolicyChangeNotify.Request.InformationClass;
-        pEntry->EventHandle = 
pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle;
-
-        InsertHeadList(&NotificationListHead,
-                       &pEntry->Entry);
+        Status = LsapAddNotification(pRequestMsg);
     }
     else
     {
         /* Unregister the notification event */
-        pEntry = 
LsapGetNotificationEntry(pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle,
-                                          
pRequestMsg->PolicyChangeNotify.Request.InformationClass);
-        if (pEntry == NULL)
-        {
-            Status = STATUS_INVALID_HANDLE;
-            goto done;
-        }
-
-        RemoveEntryList(&pEntry->Entry);
-        RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
+        Status = LsapRemoveNotification(pRequestMsg);
     }
 
-done:
     /* Release the notification list lock */
     RtlReleaseResource(&NotificationListLock);
 
@@ -115,7 +191,7 @@ LsapNotifyPolicyChange(
     PLIST_ENTRY NotificationEntry;
     PLSA_NOTIFICATION_ENTRY CurrentNotification;
 
-    FIXME("LsapNotifyPolicyChange(%lu)\n", InformationClass);
+    TRACE("LsapNotifyPolicyChange(%lu)\n", InformationClass);
 
     /* Acquire the notification list lock shared */
     RtlAcquireResourceShared(&NotificationListLock, TRUE);
@@ -127,8 +203,8 @@ LsapNotifyPolicyChange(
 
         if (CurrentNotification->InformationClass == InformationClass)
         {
-            FIXME("Notify event %p\n", CurrentNotification->EventHandle);
-
+            TRACE("Notify event %p\n", CurrentNotification->MappedEventHandle);
+            NtSetEvent(CurrentNotification->MappedEventHandle, NULL);
         }
 
         NotificationEntry = NotificationEntry->Flink;

Reply via email to