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

commit 45b008dd2318b1d3d5b8dfbe3be35a5c0425fbd6
Author:     Eric Kohl <[email protected]>
AuthorDate: Sat Dec 28 21:14:38 2024 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Sat Dec 28 21:14:38 2024 +0100

    [WKSSVC][NETAPI32][IDL] Implement NetWkstaUserGetInfo using the workstation 
service
---
 base/services/wkssvc/precomp.h     |   3 +
 base/services/wkssvc/rpcserver.c   | 196 ++++++++++++++++++++++++++++++++++++-
 dll/win32/netapi32/wksta.c         | 146 ---------------------------
 dll/win32/netapi32/wksta_new.c     |  12 +--
 sdk/include/reactos/idl/wkssvc.idl |  13 ++-
 5 files changed, 210 insertions(+), 160 deletions(-)

diff --git a/base/services/wkssvc/precomp.h b/base/services/wkssvc/precomp.h
index f2fbde4e433..71a60f4ea50 100644
--- a/base/services/wkssvc/precomp.h
+++ b/base/services/wkssvc/precomp.h
@@ -17,7 +17,10 @@
 #include <ntsecapi.h>
 #include <ntmsv1_0.h>
 //#include <ntstatus.h>
+#include <ndk/obfuncs.h>
+#include <ndk/psfuncs.h>
 #include <ndk/rtlfuncs.h>
+#include <ndk/sefuncs.h>
 
 #include <wkssvc_s.h>
 
diff --git a/base/services/wkssvc/rpcserver.c b/base/services/wkssvc/rpcserver.c
index 5088b48f6e9..0c50e494f33 100644
--- a/base/services/wkssvc/rpcserver.c
+++ b/base/services/wkssvc/rpcserver.c
@@ -77,6 +77,55 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
 }
 
 
+static
+NET_API_STATUS
+NetpGetClientLogonId(
+    _Out_ PLUID LogonId)
+{
+    HANDLE ThreadToken = NULL;
+    TOKEN_STATISTICS Statistics;
+    ULONG Length;
+    NTSTATUS NtStatus;
+    NET_API_STATUS ApiStatus = NERR_Success;
+
+    ApiStatus = RpcImpersonateClient(NULL);
+    if (ApiStatus != NERR_Success)
+        return ApiStatus;
+
+    NtStatus = NtOpenThreadToken(NtCurrentThread(),
+                                 TOKEN_QUERY,
+                                 TRUE,
+                                 &ThreadToken);
+    if (!NT_SUCCESS(NtStatus))
+    {
+        ApiStatus = RtlNtStatusToDosError(NtStatus);
+        goto done;
+    }
+
+    NtStatus = NtQueryInformationToken(ThreadToken,
+                                       TokenStatistics,
+                                       (PVOID)&Statistics,
+                                       sizeof(Statistics),
+                                       &Length);
+    if (!NT_SUCCESS(NtStatus))
+    {
+        ApiStatus = RtlNtStatusToDosError(NtStatus);
+        goto done;
+    }
+
+    FIXME("Client LUID: %lx\n", Statistics.AuthenticationId.LowPart);
+    RtlCopyLuid(LogonId, &Statistics.AuthenticationId);
+
+done:
+    if (ThreadToken != NULL)
+        NtClose(ThreadToken);
+
+    RpcRevertToSelf();
+
+    return ApiStatus;
+}
+
+
 /* Function 0 */
 unsigned long
 __stdcall
@@ -384,12 +433,149 @@ __stdcall
 NetrWkstaUserGetInfo(
     WKSSVC_IDENTIFY_HANDLE Unused,
     unsigned long Level,
-    LPWKSTA_USER_INFO UserInfo)
-{
-    FIXME("(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo);
+    LPWKSTA_USER_INFO *UserInfo)
+{
+    MSV1_0_GETUSERINFO_REQUEST UserInfoRequest;
+    PMSV1_0_GETUSERINFO_RESPONSE UserInfoResponseBuffer = NULL;
+    DWORD UserInfoResponseBufferSize = 0;
+    NTSTATUS Status, ProtocolStatus;
+    LUID LogonId;
+    PWKSTA_USER_INFO pUserInfo;
+    DWORD dwResult = NERR_Success;
 
-    UNIMPLEMENTED;
-    return 0;
+    TRACE("NetrWkstaUserGetInfo(%s, %d, %p)\n", debugstr_w(Unused), Level, 
UserInfo);
+
+    if (Unused != NULL)
+        return ERROR_INVALID_PARAMETER;
+
+    if (Level > 1 && Level != 1101)
+        return ERROR_INVALID_LEVEL;
+
+    if (Level != 1101)
+    {
+        dwResult = NetpGetClientLogonId(&LogonId);
+        if (dwResult != NERR_Success)
+        {
+            ERR("NetpGetClientLogonId() failed (%u)\n", dwResult);
+            return dwResult;
+        }
+
+        TRACE("LogonId: 0x%08lx\n", LogonId.LowPart);
+
+        UserInfoRequest.MessageType = MsV1_0GetUserInfo;
+        UserInfoRequest.LogonId = LogonId;
+        Status = LsaCallAuthenticationPackage(LsaHandle,
+                                              LsaAuthenticationPackage,
+                                              &UserInfoRequest,
+                                              sizeof(UserInfoRequest),
+                                              (PVOID*)&UserInfoResponseBuffer,
+                                              &UserInfoResponseBufferSize,
+                                              &ProtocolStatus);
+        TRACE("LsaCallAuthenticationPackage:MsV1_0GetUserInfo Status 0x%08lx 
ResponseBufferSize %lu\n", Status, UserInfoResponseBufferSize);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("\n");
+            return RtlNtStatusToDosError(Status);
+        }
+
+        TRACE("UserName: %wZ\n", &UserInfoResponseBuffer->UserName);
+        TRACE("LogonDomain: %wZ\n", &UserInfoResponseBuffer->LogonDomainName);
+        TRACE("LogonServer: %wZ\n", &UserInfoResponseBuffer->LogonServer);
+    }
+
+    switch (Level)
+    {
+        case 0:
+            pUserInfo = midl_user_allocate(sizeof(WKSTA_USER_INFO_0));
+            if (pUserInfo == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo, sizeof(WKSTA_USER_INFO_0));
+
+            /* User Name */
+            pUserInfo->UserInfo0.wkui0_username = 
midl_user_allocate(UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR));
+            if (pUserInfo->UserInfo0.wkui0_username == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo->UserInfo0.wkui0_username, 
UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR));
+            CopyMemory(pUserInfo->UserInfo0.wkui0_username, 
UserInfoResponseBuffer->UserName.Buffer, 
UserInfoResponseBuffer->UserName.Length);
+
+            *UserInfo = pUserInfo;
+            break;
+
+        case 1:
+            pUserInfo = midl_user_allocate(sizeof(WKSTA_USER_INFO_1));
+            if (pUserInfo == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo, sizeof(WKSTA_USER_INFO_1));
+
+            /* User Name */
+            pUserInfo->UserInfo1.wkui1_username = 
midl_user_allocate(UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR));
+            if (pUserInfo->UserInfo1.wkui1_username == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo->UserInfo1.wkui1_username, 
UserInfoResponseBuffer->UserName.Length + sizeof(WCHAR));
+            CopyMemory(pUserInfo->UserInfo1.wkui1_username, 
UserInfoResponseBuffer->UserName.Buffer, 
UserInfoResponseBuffer->UserName.Length);
+
+            /* Logon Domain Name */
+            pUserInfo->UserInfo1.wkui1_logon_domain = 
midl_user_allocate(UserInfoResponseBuffer->LogonDomainName.Length + 
sizeof(WCHAR));
+            if (pUserInfo->UserInfo1.wkui1_logon_domain == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo->UserInfo1.wkui1_logon_domain, 
UserInfoResponseBuffer->LogonDomainName.Length + sizeof(WCHAR));
+            CopyMemory(pUserInfo->UserInfo1.wkui1_logon_domain, 
UserInfoResponseBuffer->LogonDomainName.Buffer, 
UserInfoResponseBuffer->LogonDomainName.Length);
+
+            /* FIXME: wkui1_oth_domains */
+
+            /* Logon Server */
+            pUserInfo->UserInfo1.wkui1_logon_server = 
midl_user_allocate(UserInfoResponseBuffer->LogonServer.Length + sizeof(WCHAR));
+            if (pUserInfo->UserInfo1.wkui1_logon_server == NULL)
+            {
+                ERR("\n");
+                dwResult = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            ZeroMemory(pUserInfo->UserInfo1.wkui1_logon_server, 
UserInfoResponseBuffer->LogonServer.Length + sizeof(WCHAR));
+            CopyMemory(pUserInfo->UserInfo1.wkui1_logon_server, 
UserInfoResponseBuffer->LogonServer.Buffer, 
UserInfoResponseBuffer->LogonServer.Length);
+
+            *UserInfo = pUserInfo;
+            break;
+
+        case 1101:
+            /* FIXME: wkui1101_oth_domains */
+            break;
+
+        default:
+            ERR("\n");
+            break;
+    }
+
+    if (UserInfoResponseBuffer)
+        LsaFreeReturnBuffer(UserInfoResponseBuffer);
+
+    return dwResult;
 }
 
 
diff --git a/dll/win32/netapi32/wksta.c b/dll/win32/netapi32/wksta.c
index 8890d7ce7e5..d09c5cb201c 100644
--- a/dll/win32/netapi32/wksta.c
+++ b/dll/win32/netapi32/wksta.c
@@ -273,152 +273,6 @@ NetWkstaTransportEnum(LMSTR ServerName, DWORD level, 
PBYTE* pbuf,
 }
 
 
-/************************************************************
- *                NetWkstaUserGetInfo  (NETAPI32.@)
- */
-NET_API_STATUS WINAPI NetWkstaUserGetInfo(LMSTR reserved, DWORD level,
-                                          PBYTE* bufptr)
-{
-    NET_API_STATUS nastatus;
-
-    TRACE("(%s, %d, %p)\n", debugstr_w(reserved), level, bufptr);
-    switch (level)
-    {
-    case 0:
-    {
-        PWKSTA_USER_INFO_0 ui;
-        DWORD dwSize = UNLEN + 1;
-
-        /* set up buffer */
-        nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * 
sizeof(WCHAR),
-                             (LPVOID *) bufptr);
-        if (nastatus != NERR_Success)
-            return ERROR_NOT_ENOUGH_MEMORY;
-
-        ui = (PWKSTA_USER_INFO_0) *bufptr;
-        ui->wkui0_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
-
-        /* get data */
-        if (!GetUserNameW(ui->wkui0_username, &dwSize))
-        {
-            NetApiBufferFree(ui);
-            return ERROR_NOT_ENOUGH_MEMORY;
-        }
-        else {
-            nastatus = NetApiBufferReallocate(
-                *bufptr, sizeof(WKSTA_USER_INFO_0) +
-                (lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR),
-                (LPVOID *) bufptr);
-            if (nastatus != NERR_Success)
-            {
-                NetApiBufferFree(ui);
-                return nastatus;
-            }
-            ui = (PWKSTA_USER_INFO_0) *bufptr;
-            ui->wkui0_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
-        }
-        break;
-    }
-
-    case 1:
-    {
-        PWKSTA_USER_INFO_1 ui;
-        PWKSTA_USER_INFO_0 ui0;
-        LSA_OBJECT_ATTRIBUTES ObjectAttributes;
-        LSA_HANDLE PolicyHandle;
-        PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
-        NTSTATUS NtStatus;
-
-        /* sizes of the field buffers in WCHARS */
-        int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz;
-
-        FIXME("Level 1 processing is partially implemented\n");
-        oth_domains_sz = 1;
-        logon_server_sz = 1;
-
-        /* get some information first to estimate size of the buffer */
-        ui0 = NULL;
-        nastatus = NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0);
-        if (nastatus != NERR_Success)
-            return nastatus;
-        username_sz = lstrlenW(ui0->wkui0_username) + 1;
-
-        ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
-        NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
-                                 POLICY_VIEW_LOCAL_INFORMATION,
-                                 &PolicyHandle);
-        if (NtStatus != STATUS_SUCCESS)
-        {
-            TRACE("LsaOpenPolicyFailed with NT status %x\n",
-                LsaNtStatusToWinError(NtStatus));
-            NetApiBufferFree(ui0);
-            return ERROR_NOT_ENOUGH_MEMORY;
-        }
-        LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation,
-                                  (PVOID*) &DomainInfo);
-        logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
-        LsaClose(PolicyHandle);
-
-        /* set up buffer */
-        nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) +
-                             (username_sz + logon_domain_sz +
-                              oth_domains_sz + logon_server_sz) * 
sizeof(WCHAR),
-                             (LPVOID *) bufptr);
-        if (nastatus != NERR_Success) {
-            NetApiBufferFree(ui0);
-            return nastatus;
-        }
-        ui = (WKSTA_USER_INFO_1 *) *bufptr;
-        ui->wkui1_username = (LMSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1));
-        ui->wkui1_logon_domain = (LMSTR) (
-            ((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR));
-        ui->wkui1_oth_domains = (LMSTR) (
-            ((PBYTE) ui->wkui1_logon_domain) +
-            logon_domain_sz * sizeof(WCHAR));
-        ui->wkui1_logon_server = (LMSTR) (
-            ((PBYTE) ui->wkui1_oth_domains) +
-            oth_domains_sz * sizeof(WCHAR));
-
-        /* get data */
-        lstrcpyW(ui->wkui1_username, ui0->wkui0_username);
-        NetApiBufferFree(ui0);
-
-        lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer,
-                logon_domain_sz);
-        LsaFreeMemory(DomainInfo);
-
-        /* FIXME. Not implemented. Populated with empty strings */
-        ui->wkui1_oth_domains[0] = 0;
-        ui->wkui1_logon_server[0] = 0;
-        break;
-    }
-    case 1101:
-    {
-        PWKSTA_USER_INFO_1101 ui;
-        DWORD dwSize = 1;
-
-        FIXME("Stub. Level 1101 processing is not implemented\n");
-        /* FIXME see also wkui1_oth_domains for level 1 */
-
-        /* set up buffer */
-        nastatus = NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize 
* sizeof(WCHAR),
-                             (LPVOID *) bufptr);
-        if (nastatus != NERR_Success)
-            return nastatus;
-        ui = (PWKSTA_USER_INFO_1101) *bufptr;
-        ui->wkui1101_oth_domains = (LMSTR)(ui + 1);
-
-        /* get data */
-        ui->wkui1101_oth_domains[0] = 0;
-        break;
-    }
-    default:
-        TRACE("Invalid level %d is specified\n", level);
-        return ERROR_INVALID_LEVEL;
-    }
-    return NERR_Success;
-}
-
 /************************************************************
  *                NetpGetComputerName  (NETAPI32.@)
  */
diff --git a/dll/win32/netapi32/wksta_new.c b/dll/win32/netapi32/wksta_new.c
index 2739a6c86e0..f427f3cd35f 100644
--- a/dll/win32/netapi32/wksta_new.c
+++ b/dll/win32/netapi32/wksta_new.c
@@ -1116,20 +1116,19 @@ NetWkstaUserEnum(
 }
 
 
-#if 0
 NET_API_STATUS
 WINAPI
 NetWkstaUserGetInfo(
-    LPWSTR reserved,
+    _In_ LPWSTR reserved,
     _In_ DWORD level,
-    _Out_ PBYTE *bufptr)
+    _Out_ LPBYTE *bufptr)
 {
     NET_API_STATUS status;
 
     TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n",
           debugstr_w(reserved), level, bufptr);
 
-    if (reserved != NULL)
+    if (reserved != NULL || bufptr == NULL)
         return ERROR_INVALID_PARAMETER;
 
     *bufptr = NULL;
@@ -1138,7 +1137,7 @@ NetWkstaUserGetInfo(
     {
         status = NetrWkstaUserGetInfo(NULL,
                                       level,
-                                      (LPWKSTA_USER_INFO)bufptr);
+                                      (LPWKSTA_USER_INFO*)bufptr);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -1148,13 +1147,12 @@ NetWkstaUserGetInfo(
 
     return status;
 }
-#endif
 
 
 NET_API_STATUS
 WINAPI
 NetWkstaUserSetInfo(
-    LPWSTR reserved,
+    _In_ LPWSTR reserved,
     _In_ DWORD level,
     _In_ LPBYTE buf,
     _Out_ LPDWORD parm_err)
diff --git a/sdk/include/reactos/idl/wkssvc.idl 
b/sdk/include/reactos/idl/wkssvc.idl
index b4cac96edd3..88cf97f6057 100644
--- a/sdk/include/reactos/idl/wkssvc.idl
+++ b/sdk/include/reactos/idl/wkssvc.idl
@@ -180,7 +180,7 @@ typedef struct _WKSTA_USER_INFO_1101
 {
     [string] wchar_t *wkui1101_oth_domains;
 } WKSTA_USER_INFO_1101, *PWKSTA_USER_INFO_1101, *LPWKSTA_USER_INFO_1101;
-
+/*
 typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO
 {
     [case(0)] LPWKSTA_USER_INFO_0 UserInfo0;
@@ -188,6 +188,14 @@ typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO
     [case(1101)] LPWKSTA_USER_INFO_1101 UserInfo1101;
     [default] ;
 } WKSTA_USER_INFO, *PWKSTA_USER_INFO, *LPWKSTA_USER_INFO;
+*/
+typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO
+{
+    [case(0)] WKSTA_USER_INFO_0 UserInfo0;
+    [case(1)] WKSTA_USER_INFO_1 UserInfo1;
+    [case(1101)] WKSTA_USER_INFO_1101 UserInfo1101;
+    [default] ;
+} WKSTA_USER_INFO, *PWKSTA_USER_INFO, *LPWKSTA_USER_INFO;
 
 typedef struct _WKSTA_TRANSPORT_INFO_0
 {
@@ -407,7 +415,8 @@ interface wkssvc
     NetrWkstaUserGetInfo(
         [in, string, unique] WKSSVC_IDENTIFY_HANDLE Unused,
         [in] unsigned long Level,
-        [out, switch_is(Level)] LPWKSTA_USER_INFO UserInfo);
+        [out, switch_is(Level)] LPWKSTA_USER_INFO *UserInfo);
+//        [out, switch_is(Level)] LPWKSTA_USER_INFO UserInfo);
 
     /* Function 4 */
     unsigned long

Reply via email to