https://git.reactos.org/?p=reactos.git;a=commitdiff;h=45b008dd2318b1d3d5b8d…
commit 45b008dd2318b1d3d5b8dfbe3be35a5c0425fbd6
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Dec 28 21:14:38 2024 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
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