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;
+}