On 2016-09-21 01:43, hbelusca(a)svn.reactos.org wrote:
> @@ -300,25 +268,53 @@
> * @implemented
> */
> NTSTATUS
> -WINAPI
> -LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
> - PHANDLE Handle,
> - PLSA_OPERATIONAL_MODE OperationalMode)
> -{
> +NTAPI
> +LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName,
> + OUT PHANDLE LsaHandle,
> + OUT PLSA_OPERATIONAL_MODE OperationalMode)
> +{
> + NTSTATUS Status;
> + HANDLE EventHandle;
> UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
> + OBJECT_ATTRIBUTES ObjectAttributes;
> SECURITY_QUALITY_OF_SERVICE SecurityQos;
> LSA_CONNECTION_INFO ConnectInfo;
> ULONG ConnectInfoLength = sizeof(ConnectInfo);
> - NTSTATUS Status;
>
> DPRINT("LsaRegisterLogonProcess()\n");
>
> /* Check the logon process name length */
> - if (LsaLogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
> + if (LogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
> return STATUS_NAME_TOO_LONG;
>
> - RtlInitUnicodeString(&PortName,
> - L"\\LsaAuthenticationPort");
> + /*
> + * First check whether the LSA server is ready:
> + * open the LSA event and wait on it.
> + */
> + // Note that we just reuse the 'PortName' variable here.
Please don't? This is not the 80s.
> + RtlInitUnicodeString(&PortName, L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
> + InitializeObjectAttributes(&ObjectAttributes,
> + &PortName,
> + OBJ_CASE_INSENSITIVE,
> + NULL,
> + NULL);
> + Status = NtOpenEvent(&EventHandle, SYNCHRONIZE, &ObjectAttributes);
> + if (!NT_SUCCESS(Status))
> + {
> + DPRINT1("NtOpenEvent failed (Status 0x%08lx)\n", Status);
> + return Status;
> + }
> +
> + Status = NtWaitForSingleObject(EventHandle, TRUE, NULL);
> + NtClose(EventHandle);
If you want to use this in kernel mode, you also have to program for
kernel mode. These should be Zw calls and you need OBJ_KERNEL_HANDLE.
> + if (!NT_SUCCESS(Status))
> + {
> + DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status);
> + return Status;
> + }
> +
> + /* Now attempt the connection */
> + RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort");
>
> SecurityQos.Length = sizeof(SecurityQos);
> SecurityQos.ImpersonationLevel = SecurityIdentification;
> @@ -326,13 +322,13 @@
> SecurityQos.EffectiveOnly = TRUE;
>
> strncpy(ConnectInfo.LogonProcessNameBuffer,
> - LsaLogonProcessName->Buffer,
> - LsaLogonProcessName->Length);
> - ConnectInfo.Length = LsaLogonProcessName->Length;
> - ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = '\0';
> + LogonProcessName->Buffer,
> + LogonProcessName->Length);
> + ConnectInfo.Length = LogonProcessName->Length;
> + ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL;
> ConnectInfo.CreateContext = TRUE;
>
> - Status = ZwConnectPort(Handle,
> + Status = ZwConnectPort(LsaHandle,
> &PortName,
> &SecurityQos,
> NULL,
> @@ -357,3 +353,42 @@
> return ConnectInfo.Status;
> }
>
> +
> +/*
> + * @implemented
> + */
> +NTSTATUS
> +NTAPI
> +LsaDeregisterLogonProcess(IN HANDLE LsaHandle)
> +{
> + NTSTATUS Status;
> + LSA_API_MSG ApiMessage;
> +
> + DPRINT("LsaDeregisterLogonProcess()\n");
> +
> + ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
> + ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess);
> + ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
> + ApiMessage.h.u2.ZeroInit = 0;
> +
> + Status = ZwRequestWaitReplyPort(LsaHandle,
> + (PPORT_MESSAGE)&ApiMessage,
> + (PPORT_MESSAGE)&ApiMessage);
> + if (!NT_SUCCESS(Status))
> + {
> + DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
> + return Status;
> + }
> +
> + if (!NT_SUCCESS(ApiMessage.Status))
> + {
> + DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
> + return ApiMessage.Status;
> + }
> +
> + NtClose(LsaHandle);
A handle opened with ZwXxx shouldn't be closed with NtClose.
> +
> + DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
> +
> + return Status;
> +}