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 <ntsecapi.h>
|
||||||
#include <ntmsv1_0.h>
|
#include <ntmsv1_0.h>
|
||||||
//#include <ntstatus.h>
|
//#include <ntstatus.h>
|
||||||
|
#include <ndk/obfuncs.h>
|
||||||
|
#include <ndk/psfuncs.h>
|
||||||
#include <ndk/rtlfuncs.h>
|
#include <ndk/rtlfuncs.h>
|
||||||
|
#include <ndk/sefuncs.h>
|
||||||
|
|
||||||
#include <wkssvc_s.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 */
|
/* Function 0 */
|
||||||
unsigned long
|
unsigned long
|
||||||
__stdcall
|
__stdcall
|
||||||
|
@ -384,12 +433,149 @@ __stdcall
|
||||||
NetrWkstaUserGetInfo(
|
NetrWkstaUserGetInfo(
|
||||||
WKSSVC_IDENTIFY_HANDLE Unused,
|
WKSSVC_IDENTIFY_HANDLE Unused,
|
||||||
unsigned long Level,
|
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;
|
TRACE("NetrWkstaUserGetInfo(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo);
|
||||||
return 0;
|
|
||||||
|
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.@)
|
* NetpGetComputerName (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1116,20 +1116,19 @@ NetWkstaUserEnum(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
NetWkstaUserGetInfo(
|
NetWkstaUserGetInfo(
|
||||||
LPWSTR reserved,
|
_In_ LPWSTR reserved,
|
||||||
_In_ DWORD level,
|
_In_ DWORD level,
|
||||||
_Out_ PBYTE *bufptr)
|
_Out_ LPBYTE *bufptr)
|
||||||
{
|
{
|
||||||
NET_API_STATUS status;
|
NET_API_STATUS status;
|
||||||
|
|
||||||
TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n",
|
TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n",
|
||||||
debugstr_w(reserved), level, bufptr);
|
debugstr_w(reserved), level, bufptr);
|
||||||
|
|
||||||
if (reserved != NULL)
|
if (reserved != NULL || bufptr == NULL)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
*bufptr = NULL;
|
*bufptr = NULL;
|
||||||
|
@ -1138,7 +1137,7 @@ NetWkstaUserGetInfo(
|
||||||
{
|
{
|
||||||
status = NetrWkstaUserGetInfo(NULL,
|
status = NetrWkstaUserGetInfo(NULL,
|
||||||
level,
|
level,
|
||||||
(LPWKSTA_USER_INFO)bufptr);
|
(LPWKSTA_USER_INFO*)bufptr);
|
||||||
}
|
}
|
||||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
@ -1148,13 +1147,12 @@ NetWkstaUserGetInfo(
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
WINAPI
|
WINAPI
|
||||||
NetWkstaUserSetInfo(
|
NetWkstaUserSetInfo(
|
||||||
LPWSTR reserved,
|
_In_ LPWSTR reserved,
|
||||||
_In_ DWORD level,
|
_In_ DWORD level,
|
||||||
_In_ LPBYTE buf,
|
_In_ LPBYTE buf,
|
||||||
_Out_ LPDWORD parm_err)
|
_Out_ LPDWORD parm_err)
|
||||||
|
|
|
@ -180,7 +180,7 @@ typedef struct _WKSTA_USER_INFO_1101
|
||||||
{
|
{
|
||||||
[string] wchar_t *wkui1101_oth_domains;
|
[string] wchar_t *wkui1101_oth_domains;
|
||||||
} WKSTA_USER_INFO_1101, *PWKSTA_USER_INFO_1101, *LPWKSTA_USER_INFO_1101;
|
} WKSTA_USER_INFO_1101, *PWKSTA_USER_INFO_1101, *LPWKSTA_USER_INFO_1101;
|
||||||
|
/*
|
||||||
typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO
|
typedef [switch_type(unsigned long)] union _WKSTA_USER_INFO
|
||||||
{
|
{
|
||||||
[case(0)] LPWKSTA_USER_INFO_0 UserInfo0;
|
[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;
|
[case(1101)] LPWKSTA_USER_INFO_1101 UserInfo1101;
|
||||||
[default] ;
|
[default] ;
|
||||||
} WKSTA_USER_INFO, *PWKSTA_USER_INFO, *LPWKSTA_USER_INFO;
|
} 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
|
typedef struct _WKSTA_TRANSPORT_INFO_0
|
||||||
{
|
{
|
||||||
|
@ -407,7 +415,8 @@ interface wkssvc
|
||||||
NetrWkstaUserGetInfo(
|
NetrWkstaUserGetInfo(
|
||||||
[in, string, unique] WKSSVC_IDENTIFY_HANDLE Unused,
|
[in, string, unique] WKSSVC_IDENTIFY_HANDLE Unused,
|
||||||
[in] unsigned long Level,
|
[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 */
|
/* Function 4 */
|
||||||
unsigned long
|
unsigned long
|
||||||
|
|
Loading…
Reference in a new issue