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?rev=56718&r1=56717&r2=56718&view=diff
==============================================================================
--- 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.spec?rev=56718&r1=56717&r2=56718&view=diff
==============================================================================
--- 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?rev=56718&r1=56717&r2=56718&view=diff
==============================================================================
--- 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=56718&r1=56717&r2=56718&view=diff
==============================================================================
--- 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,


Reply via email to