mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[WKSSVC][NETAPI32][IDL] Implement NetWkstaUserGetInfo using the workstation service
This commit is contained in:
parent
0bb830022c
commit
45b008dd23
5 changed files with 209 additions and 159 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
LPWKSTA_USER_INFO *UserInfo)
|
||||
{
|
||||
FIXME("(%s, %d, %p)\n", debugstr_w(Unused), Level, 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue