https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd1f0d02bc0ecf2bea0781...
commit dd1f0d02bc0ecf2bea0781af2915c419871fb493 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Sun Feb 21 18:05:11 2021 +0100 Commit: Eric Kohl eric.kohl@reactos.org 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;