mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[NETAPI32][WKSSVC][IDL] Implement NetrWkstaUserEnum
- TODO: Take PreferredMaximumLength and ResumeHandle into account
This commit is contained in:
parent
4cdcbbd1a9
commit
faf6297972
3 changed files with 267 additions and 17 deletions
|
@ -447,12 +447,243 @@ NetrWkstaUserEnum(
|
|||
unsigned long *TotalEntries,
|
||||
unsigned long *ResumeHandle)
|
||||
{
|
||||
ERR("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n",
|
||||
ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle);
|
||||
MSV1_0_ENUMUSERS_REQUEST EnumRequest;
|
||||
PMSV1_0_ENUMUSERS_RESPONSE EnumResponseBuffer = NULL;
|
||||
MSV1_0_GETUSERINFO_REQUEST UserInfoRequest;
|
||||
PMSV1_0_GETUSERINFO_RESPONSE UserInfoResponseBuffer = NULL;
|
||||
PMSV1_0_GETUSERINFO_RESPONSE *UserInfoArray = NULL;
|
||||
DWORD EnumResponseBufferSize = 0;
|
||||
DWORD UserInfoResponseBufferSize = 0;
|
||||
NTSTATUS Status, ProtocolStatus;
|
||||
ULONG i, start, count;
|
||||
PLUID pLogonId;
|
||||
PULONG pEnumHandle;
|
||||
DWORD dwResult = NERR_Success;
|
||||
|
||||
PWKSTA_USER_INFO_0 pUserInfo0 = NULL;
|
||||
PWKSTA_USER_INFO_1 pUserInfo1 = NULL;
|
||||
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
TRACE("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n",
|
||||
ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle);
|
||||
|
||||
if (UserInfo->Level > 1)
|
||||
{
|
||||
ERR("Invalid Level %lu\n", UserInfo->Level);
|
||||
return ERROR_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
/* Enumerate all currently logged-on users */
|
||||
EnumRequest.MessageType = MsV1_0EnumerateUsers;
|
||||
Status = LsaCallAuthenticationPackage(LsaHandle,
|
||||
LsaAuthenticationPackage,
|
||||
&EnumRequest,
|
||||
sizeof(EnumRequest),
|
||||
(PVOID*)&EnumResponseBuffer,
|
||||
&EnumResponseBufferSize,
|
||||
&ProtocolStatus);
|
||||
|
||||
TRACE("LsaCallAuthenticationPackage Status 0x%08lx ResponseBufferSize %lu\n", Status, EnumResponseBufferSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
dwResult = RtlNtStatusToDosError(Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
TRACE("LoggedOnUsers: %lu\n", EnumResponseBuffer->NumberOfLoggedOnUsers);
|
||||
TRACE("ResponseBuffer: 0x%p\n", EnumResponseBuffer);
|
||||
TRACE("LogonIds: 0x%p\n", EnumResponseBuffer->LogonIds);
|
||||
TRACE("EnumHandles: 0x%p\n", EnumResponseBuffer->EnumHandles);
|
||||
if (EnumResponseBuffer->NumberOfLoggedOnUsers > 0)
|
||||
{
|
||||
pLogonId = EnumResponseBuffer->LogonIds;
|
||||
pEnumHandle = EnumResponseBuffer->EnumHandles;
|
||||
TRACE("pLogonId: 0x%p\n", pLogonId);
|
||||
TRACE("pEnumHandle: 0x%p\n", pEnumHandle);
|
||||
|
||||
UserInfoArray = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
EnumResponseBuffer->NumberOfLoggedOnUsers * sizeof(PMSV1_0_GETUSERINFO_RESPONSE));
|
||||
if (UserInfoArray == NULL)
|
||||
{
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < EnumResponseBuffer->NumberOfLoggedOnUsers; i++)
|
||||
{
|
||||
TRACE("Logon %lu: 0x%08lx %lu\n", i, pLogonId->LowPart, *pEnumHandle);
|
||||
|
||||
UserInfoRequest.MessageType = MsV1_0GetUserInfo;
|
||||
UserInfoRequest.LogonId = *pLogonId;
|
||||
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))
|
||||
{
|
||||
dwResult = RtlNtStatusToDosError(Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
UserInfoArray[i] = UserInfoResponseBuffer;
|
||||
|
||||
TRACE("UserName: %wZ\n", &UserInfoArray[i]->UserName);
|
||||
TRACE("LogonDomain: %wZ\n", &UserInfoArray[i]->LogonDomainName);
|
||||
TRACE("LogonServer: %wZ\n", &UserInfoArray[i]->LogonServer);
|
||||
|
||||
pLogonId++;
|
||||
pEnumHandle++;
|
||||
}
|
||||
|
||||
if (PreferredMaximumLength == MAX_PREFERRED_LENGTH)
|
||||
{
|
||||
start = 0;
|
||||
count = EnumResponseBuffer->NumberOfLoggedOnUsers;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Calculate the start index and the number of matching array entries!");
|
||||
dwResult = ERROR_CALL_NOT_IMPLEMENTED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (UserInfo->Level)
|
||||
{
|
||||
case 0:
|
||||
pUserInfo0 = midl_user_allocate(count * sizeof(WKSTA_USER_INFO_0));
|
||||
if (pUserInfo0 == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo0, count * sizeof(WKSTA_USER_INFO_0));
|
||||
|
||||
for (i = 0; i < 0 + count; i++)
|
||||
{
|
||||
pUserInfo0[i].wkui0_username = midl_user_allocate(UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR));
|
||||
if (pUserInfo0[i].wkui0_username == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo0[i].wkui0_username, UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR));
|
||||
CopyMemory(pUserInfo0[i].wkui0_username, UserInfoArray[start + i]->UserName.Buffer, UserInfoArray[start + i]->UserName.Length);
|
||||
}
|
||||
|
||||
UserInfo->WkstaUserInfo.Level0.EntriesRead = count;
|
||||
UserInfo->WkstaUserInfo.Level0.Buffer = pUserInfo0;
|
||||
*TotalEntries = EnumResponseBuffer->NumberOfLoggedOnUsers;
|
||||
*ResumeHandle = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pUserInfo1 = midl_user_allocate(count * sizeof(WKSTA_USER_INFO_1));
|
||||
if (pUserInfo1 == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo1, count * sizeof(WKSTA_USER_INFO_1));
|
||||
|
||||
for (i = 0; i < 0 + count; i++)
|
||||
{
|
||||
pUserInfo1[i].wkui1_username = midl_user_allocate(UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR));
|
||||
if (pUserInfo1[i].wkui1_username == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo1[i].wkui1_username, UserInfoArray[start + i]->UserName.Length + sizeof(WCHAR));
|
||||
CopyMemory(pUserInfo1[i].wkui1_username, UserInfoArray[start + i]->UserName.Buffer, UserInfoArray[start + i]->UserName.Length);
|
||||
|
||||
pUserInfo1[i].wkui1_logon_domain = midl_user_allocate(UserInfoArray[start + i]->LogonDomainName.Length + sizeof(WCHAR));
|
||||
if (pUserInfo1[i].wkui1_logon_domain == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo1[i].wkui1_logon_domain, UserInfoArray[start + i]->LogonDomainName.Length + sizeof(WCHAR));
|
||||
CopyMemory(pUserInfo1[i].wkui1_logon_domain, UserInfoArray[start + i]->LogonDomainName.Buffer, UserInfoArray[start + i]->LogonDomainName.Length);
|
||||
|
||||
// FIXME: wkui1_oth_domains
|
||||
|
||||
pUserInfo1[i].wkui1_logon_server = midl_user_allocate(UserInfoArray[start + i]->LogonServer.Length + sizeof(WCHAR));
|
||||
if (pUserInfo1[i].wkui1_logon_server == NULL)
|
||||
{
|
||||
ERR("\n");
|
||||
dwResult = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ZeroMemory(pUserInfo1[i].wkui1_logon_server, UserInfoArray[start + i]->LogonServer.Length + sizeof(WCHAR));
|
||||
CopyMemory(pUserInfo1[i].wkui1_logon_server, UserInfoArray[start + i]->LogonServer.Buffer, UserInfoArray[start + i]->LogonServer.Length);
|
||||
}
|
||||
|
||||
UserInfo->WkstaUserInfo.Level1.EntriesRead = count;
|
||||
UserInfo->WkstaUserInfo.Level1.Buffer = pUserInfo1;
|
||||
*TotalEntries = EnumResponseBuffer->NumberOfLoggedOnUsers;
|
||||
*ResumeHandle = 0;
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UserInfo->Level == 0)
|
||||
{
|
||||
UserInfo->WkstaUserInfo.Level0.Buffer = NULL;
|
||||
UserInfo->WkstaUserInfo.Level0.EntriesRead = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserInfo->WkstaUserInfo.Level1.Buffer = NULL;
|
||||
UserInfo->WkstaUserInfo.Level1.EntriesRead = 0;
|
||||
}
|
||||
|
||||
*TotalEntries = 0;
|
||||
dwResult = NERR_Success;
|
||||
}
|
||||
|
||||
done:
|
||||
if (UserInfoArray !=NULL)
|
||||
{
|
||||
|
||||
for (i = 0; i < EnumResponseBuffer->NumberOfLoggedOnUsers; i++)
|
||||
{
|
||||
if (UserInfoArray[i]->UserName.Buffer != NULL)
|
||||
LsaFreeReturnBuffer(UserInfoArray[i]->UserName.Buffer);
|
||||
|
||||
if (UserInfoArray[i]->LogonDomainName.Buffer != NULL)
|
||||
LsaFreeReturnBuffer(UserInfoArray[i]->LogonDomainName.Buffer);
|
||||
|
||||
if (UserInfoArray[i]->LogonServer.Buffer != NULL)
|
||||
LsaFreeReturnBuffer(UserInfoArray[i]->LogonServer.Buffer);
|
||||
|
||||
LsaFreeReturnBuffer(UserInfoArray[i]);
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, UserInfoArray);
|
||||
}
|
||||
|
||||
if (EnumResponseBuffer != NULL)
|
||||
LsaFreeReturnBuffer(EnumResponseBuffer);
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1057,8 +1057,8 @@ NetWkstaUserEnum(
|
|||
_Inout_ LPDWORD resumehandle)
|
||||
{
|
||||
WKSTA_USER_ENUM_STRUCT UserEnumInfo;
|
||||
WKSTA_USER_INFO_0_CONTAINER Container0;
|
||||
WKSTA_USER_INFO_1_CONTAINER Container1;
|
||||
// WKSTA_USER_INFO_0_CONTAINER Container0;
|
||||
// WKSTA_USER_INFO_1_CONTAINER Container1;
|
||||
NET_API_STATUS status;
|
||||
|
||||
TRACE("NetWkstaUserEnum(%s, %d, %p, %d, %p, %p, %p)\n", debugstr_w(servername),
|
||||
|
@ -1068,15 +1068,19 @@ NetWkstaUserEnum(
|
|||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
UserEnumInfo.WkstaUserInfo.Level0 = &Container0;
|
||||
Container0.EntriesRead = 0;
|
||||
Container0.Buffer = NULL;
|
||||
// UserEnumInfo.WkstaUserInfo.Level0 = &Container0;
|
||||
// Container0.EntriesRead = 0;
|
||||
// Container0.Buffer = NULL;
|
||||
UserEnumInfo.WkstaUserInfo.Level0.EntriesRead = 0;
|
||||
UserEnumInfo.WkstaUserInfo.Level0.Buffer = NULL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
UserEnumInfo.WkstaUserInfo.Level1 = &Container1;
|
||||
Container1.EntriesRead = 0;
|
||||
Container1.Buffer = NULL;
|
||||
// UserEnumInfo.WkstaUserInfo.Level1 = &Container1;
|
||||
// Container1.EntriesRead = 0;
|
||||
// Container1.Buffer = NULL;
|
||||
UserEnumInfo.WkstaUserInfo.Level1.EntriesRead = 0;
|
||||
UserEnumInfo.WkstaUserInfo.Level1.Buffer = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1095,13 +1099,17 @@ NetWkstaUserEnum(
|
|||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
*bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0->Buffer;
|
||||
*entriesread = UserEnumInfo.WkstaUserInfo.Level0->EntriesRead;
|
||||
// *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0->Buffer;
|
||||
// *entriesread = UserEnumInfo.WkstaUserInfo.Level0->EntriesRead;
|
||||
*bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level0.Buffer;
|
||||
*entriesread = UserEnumInfo.WkstaUserInfo.Level0.EntriesRead;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1->Buffer;
|
||||
*entriesread = UserEnumInfo.WkstaUserInfo.Level1->EntriesRead;
|
||||
// *bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1->Buffer;
|
||||
// *entriesread = UserEnumInfo.WkstaUserInfo.Level1->EntriesRead;
|
||||
*bufptr = (LPBYTE)UserEnumInfo.WkstaUserInfo.Level1.Buffer;
|
||||
*entriesread = UserEnumInfo.WkstaUserInfo.Level1.EntriesRead;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ typedef struct _WKSTA_USER_INFO_1_CONTAINER
|
|||
unsigned long EntriesRead;
|
||||
[size_is(EntriesRead)] LPWKSTA_USER_INFO_1 Buffer;
|
||||
} WKSTA_USER_INFO_1_CONTAINER, *PWKSTA_USER_INFO_1_CONTAINER, *LPWKSTA_USER_INFO_1_CONTAINER;
|
||||
|
||||
/*
|
||||
typedef struct _WKSTA_USER_ENUM_STRUCT
|
||||
{
|
||||
unsigned long Level;
|
||||
|
@ -322,6 +322,17 @@ typedef struct _WKSTA_USER_ENUM_STRUCT
|
|||
[default] ;
|
||||
} WkstaUserInfo;
|
||||
} WKSTA_USER_ENUM_STRUCT, *PWKSTA_USER_ENUM_STRUCT, *LPWKSTA_USER_ENUM_STRUCT;
|
||||
*/
|
||||
typedef struct _WKSTA_USER_ENUM_STRUCT
|
||||
{
|
||||
unsigned long Level;
|
||||
[switch_is(Level)] union _WKSTA_USER_ENUM_UNION
|
||||
{
|
||||
[case(0)] WKSTA_USER_INFO_0_CONTAINER Level0;
|
||||
[case(1)] WKSTA_USER_INFO_1_CONTAINER Level1;
|
||||
[default] ;
|
||||
} WkstaUserInfo;
|
||||
} WKSTA_USER_ENUM_STRUCT, *PWKSTA_USER_ENUM_STRUCT, *LPWKSTA_USER_ENUM_STRUCT;
|
||||
|
||||
typedef struct _WKSTA_TRANSPORT_INFO_0_CONTAINER
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue