Author: ekohl Date: Sat Jun 9 23:34:42 2012 New Revision: 56718
URL: http://svn.reactos.org/svn/reactos?rev=56718&view=rev Log: [SAMLIB][SAMSRV] Implement SamEnumerateAliasesInDomain and SamrEnumerateAliasesInDomain. SamEnumerateAliasesInDomain does not return the names of the enumerated aliases, most likely due to a bug in rpcrt4.dll.
Modified: trunk/reactos/dll/win32/samlib/samlib.c trunk/reactos/dll/win32/samlib/samlib.spec trunk/reactos/dll/win32/samsrv/samrpc.c trunk/reactos/include/ddk/ntsam.h
Modified: trunk/reactos/dll/win32/samlib/samlib.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?r... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Sat Jun 9 23:34:42 2012 @@ -242,6 +242,56 @@
NTSTATUS NTAPI +SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned) +{ + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + NTSTATUS Status; + + TRACE("SamEnumerateAliasesInDomain(%p,%p,%p,%lu,%p)\n", + DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength, + CountReturned); + + if ((EnumerationContext == NULL) || + (Buffer == NULL) || + (CountReturned == NULL)) + return STATUS_INVALID_PARAMETER; + + *Buffer = NULL; + + RpcTryExcept + { + Status = SamrEnumerateAliasesInDomain((SAMPR_HANDLE)DomainHandle, + EnumerationContext, + (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + PreferedMaximumLength, + CountReturned); + + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + { + *Buffer = EnumBuffer->Buffer; + } + + midl_user_free(EnumBuffer); + } + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; +} + + +NTSTATUS +NTAPI SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, OUT PVOID *Buffer,
Modified: trunk/reactos/dll/win32/samlib/samlib.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spe... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Sat Jun 9 23:34:42 2012 @@ -14,7 +14,7 @@ @ stub SamDeleteAlias @ stub SamDeleteGroup @ stub SamDeleteUser -@ stub SamEnumerateAliasesInDomain +@ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr) @ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr) @ stub SamEnumerateGroupsInDomain @ stub SamEnumerateUsersInDomain
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sat Jun 9 23:34:42 2012 @@ -929,7 +929,7 @@ return Status; }
- /* Set the name attribute */ + /* Set the Name attribute */ Status = SampSetObjectAttribute(AliasObject, L"Name", REG_SZ, @@ -972,8 +972,223 @@ IN unsigned long PreferedMaximumLength, OUT unsigned long *CountReturned) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; + PSAM_DB_OBJECT DomainObject; + HANDLE AliasesKeyHandle; + WCHAR AliasKeyName[64]; + HANDLE AliasKeyHandle; + ULONG EnumIndex; + ULONG EnumCount; + ULONG RequiredLength; + ULONG DataLength; + ULONG i; + BOOLEAN MoreEntries = FALSE; + NTSTATUS Status; + + TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n", + DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength, + CountReturned); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_LIST_ACCOUNTS, + &DomainObject); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Aliases", + KEY_READ, + &AliasesKeyHandle); + if (!NT_SUCCESS(Status)) + return Status; + + TRACE("Part 1\n"); + + EnumIndex = *EnumerationContext; + EnumCount = 0; + RequiredLength = 0; + + while (TRUE) + { + Status = SampRegEnumerateSubKey(AliasesKeyHandle, + EnumIndex, + 64 * sizeof(WCHAR), + AliasKeyName); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Alias key name: %S\n", AliasKeyName); + + Status = SampRegOpenKey(AliasesKeyHandle, + AliasKeyName, + KEY_READ, + &AliasKeyHandle); + TRACE("SampRegOpenKey returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(AliasKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + + NtClose(AliasKeyHandle); + + TRACE("SampRegQueryValue returned %08lX\n", Status); + + if (NT_SUCCESS(Status)) + { + TRACE("Data length: %lu\n", DataLength); + + if ((RequiredLength + DataLength + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength) + { + MoreEntries = TRUE; + break; + } + + RequiredLength += (DataLength + sizeof(SAMPR_RID_ENUMERATION)); + EnumCount++; + } + } + + EnumIndex++; + } + + TRACE("EnumCount: %lu\n", EnumCount); + TRACE("RequiredLength: %lu\n", RequiredLength); + + EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER)); + if (EnumBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + EnumBuffer->EntriesRead = EnumCount; + if (EnumCount == 0) + goto done; + + EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION)); + if (EnumBuffer->Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Part 2\n"); + + EnumIndex = *EnumerationContext; + for (i = 0; i < EnumCount; i++, EnumIndex++) + { + Status = SampRegEnumerateSubKey(AliasesKeyHandle, + EnumIndex, + 64 * sizeof(WCHAR), + AliasKeyName); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NO_MORE_ENTRIES) + Status = STATUS_SUCCESS; + break; + } + + TRACE("EnumIndex: %lu\n", EnumIndex); + TRACE("Alias key name: %S\n", AliasKeyName); + + Status = SampRegOpenKey(AliasesKeyHandle, + AliasKeyName, + KEY_READ, + &AliasKeyHandle); + TRACE("SampRegOpenKey returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(AliasKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + TRACE("SampRegQueryValue returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + EnumBuffer->Buffer[i].RelativeId = wcstoul(AliasKeyName, NULL, 16); + + EnumBuffer->Buffer[i].Name.Length = (USHORT)DataLength - sizeof(WCHAR); + EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)DataLength; + EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(DataLength); + if (EnumBuffer->Buffer[i].Name.Buffer == NULL) + { + NtClose(AliasKeyHandle); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampRegQueryValue(AliasKeyHandle, + L"Name", + NULL, + EnumBuffer->Buffer[i].Name.Buffer, + &DataLength); + TRACE("SampRegQueryValue returned %08lX\n", Status); + if (NT_SUCCESS(Status)) + { + TRACE("Alias name: %S\n", EnumBuffer->Buffer[i].Name.Buffer); + } + } + + NtClose(AliasKeyHandle); + + if (!NT_SUCCESS(Status)) + goto done; + } + } + +done: + if (NT_SUCCESS(Status)) + { + *EnumerationContext += EnumCount; + *Buffer = EnumBuffer; + *CountReturned = EnumCount; + } + + if (!NT_SUCCESS(Status)) + { + *EnumerationContext = 0; + *Buffer = NULL; + *CountReturned = 0; + + if (EnumBuffer != NULL) + { + if (EnumBuffer->Buffer != NULL) + { + if (EnumBuffer->EntriesRead != 0) + { + for (i = 0; i < EnumBuffer->EntriesRead; i++) + { + if (EnumBuffer->Buffer[i].Name.Buffer != NULL) + midl_user_free(EnumBuffer->Buffer[i].Name.Buffer); + } + } + + midl_user_free(EnumBuffer->Buffer); + } + + midl_user_free(EnumBuffer); + } + } + + NtClose(AliasesKeyHandle); + + if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE)) + Status = STATUS_MORE_ENTRIES; + + return Status; }
/* Function 16 */
Modified: trunk/reactos/include/ddk/ntsam.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=567... ============================================================================== --- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Sat Jun 9 23:34:42 2012 @@ -154,6 +154,14 @@
NTSTATUS NTAPI +SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, + IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, + OUT PVOID *Buffer, + IN ULONG PreferedMaximumLength, + OUT PULONG CountReturned); + +NTSTATUS +NTAPI SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, OUT PVOID *Buffer,