+ PSAM_RID_ENUMERATION CurrentUser;
+ PENUM_CONTEXT EnumContext = NULL;
+ LPVOID Buffer = NULL;
+ PSID DomainSid = NULL;
+ PUSER_INFO_0 UserInfo0;
+ PUSER_INFO_1 UserInfo1;
+ PUSER_INFO_20 UserInfo20;
+
+ LPWSTR Ptr;
+ ULONG i;
+ ULONG Size;
+
+ SAM_HANDLE UserHandle = NULL;
+ PUSER_ACCOUNT_INFORMATION UserInfo = NULL;
+
+ NET_API_STATUS ApiStatus = NERR_Success;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ FIXME("(%s %d 0x%d %p %d %p %p %p) stub!\n", debugstr_w(servername), level,
+ filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
+
+ *entriesread = 0;
+ *totalentries = 0;
+ *bufptr = NULL;
+
+ if (resume_handle != NULL && *resume_handle != 0)
+ {
+ EnumContext = (PENUM_CONTEXT)*resume_handle;
+ }
+ else
+ {
+ ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
+ if (ApiStatus != NERR_Success)
+ goto done;
+
+ EnumContext->EnumerationContext = 0;
+ EnumContext->Buffer = NULL;
+ EnumContext->Returned = 0;
+ EnumContext->Index = 0;
+ EnumContext->BuiltinDone = FALSE;
+
+ Status = SamConnect(NULL,
+ &EnumContext->ServerHandle,
+ SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamConnect failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = GetAccountDomainSid(&DomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = SamOpenDomain(EnumContext->ServerHandle,
+ DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+ DomainSid,
+ &EnumContext->AccountDomainHandle);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = GetBuiltinDomainSid(&DomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = SamOpenDomain(EnumContext->ServerHandle,
+ DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+ DomainSid,
+ &EnumContext->BuiltinDomainHandle);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+ }
+
+// while (TRUE)
+// {
+ TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
+ TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
+
+ if (EnumContext->Index >= EnumContext->Returned)
+ {
+// if (EnumContext->BuiltinDone == TRUE)
+// {
+// ApiStatus = NERR_Success;
+// goto done;
+// }
+
+ TRACE("Calling SamEnumerateUsersInDomain\n");
+ Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
+ &EnumContext->EnumerationContext,
+ 0,
+ (PVOID *)&EnumContext->Buffer,
+ prefmaxlen,
+ &EnumContext->Returned);
+
+ TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ if (Status == STATUS_MORE_ENTRIES)
+ {
+ ApiStatus = NERR_BufTooSmall;
+ goto done;
+ }
+ else
+ {
+ EnumContext->BuiltinDone = TRUE;
+ }
+ }
+
+ TRACE("EnumContext: %lu\n", EnumContext);
+ TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
+ TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
+
+ /* Get a pointer to the current user */
+ CurrentUser = &EnumContext->Buffer[EnumContext->Index];
+
+ TRACE("RID: %lu\n", CurrentUser->RelativeId);
+
+ Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
+ USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
+ CurrentUser->RelativeId,
+ &UserHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenUser failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = SamQueryInformationUser(UserHandle,
+ UserAccountInformation,
+ (PVOID *)&UserInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ SamCloseHandle(UserHandle);
+ UserHandle = NULL;
+
+ switch (level)
+ {
+ case 0:
+ Size = sizeof(USER_INFO_0) +
+ UserInfo->UserName.Length + sizeof(WCHAR);
+ break;
+
+ case 1:
+ Size = sizeof(USER_INFO_1) +
+ UserInfo->UserName.Length + sizeof(WCHAR);
+
+ if (UserInfo->HomeDirectory.Length > 0)
+ Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
+
+ if (UserInfo->AdminComment.Length > 0)
+ Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
+
+ if (UserInfo->ScriptPath.Length > 0)
+ Size = UserInfo->ScriptPath.Length + sizeof(WCHAR);
+ break;
+
+// case 2:
+// case 3:
+// case 10:
+// case 11:
+
+ case 20:
+ Size = sizeof(USER_INFO_20) +
+ UserInfo->UserName.Length + sizeof(WCHAR);
+
+ if (UserInfo->FullName.Length > 0)
+ Size += UserInfo->FullName.Length + sizeof(WCHAR);
+
+ if (UserInfo->AdminComment.Length > 0)
+ Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
+ break;
+
+// case 23:
+
+ default:
+ ApiStatus = ERROR_INVALID_LEVEL;
+ goto done;
+ }
+
+ ApiStatus = NetApiBufferAllocate(Size, &Buffer);
+ if (ApiStatus != NERR_Success)
+ goto done;
+
+ switch (level)
+ {
+ case 0:
+ UserInfo0 = (PUSER_INFO_0)Buffer;
+
+ Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
+ UserInfo0->usri0_name = Ptr;
+
+ memcpy(UserInfo0->usri0_name,
+ UserInfo->UserName.Buffer,
+ UserInfo->UserName.Length);
+ UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ break;
+
+ case 1:
+ UserInfo1 = (PUSER_INFO_1)Buffer;
+
+ Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));