[NETAPI32]
authorEric Kohl <eric.kohl@reactos.org>
Mon, 5 Nov 2012 22:51:08 +0000 (22:51 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 5 Nov 2012 22:51:08 +0000 (22:51 +0000)
Start the implementation of NetpNtStatusToApiStatus and NetLocalGroupEnum.

svn path=/trunk/; revision=57678

reactos/dll/win32/netapi32/CMakeLists.txt
reactos/dll/win32/netapi32/local_group.c
reactos/dll/win32/netapi32/netapi32.c
reactos/dll/win32/netapi32/netapi32.h [new file with mode: 0644]
reactos/dll/win32/netapi32/netapi32.spec

index 219f4f9..50ae272 100644 (file)
@@ -28,5 +28,7 @@ target_link_libraries(netapi32 wine)
 
 add_importlibs(netapi32 iphlpapi ws2_32 advapi32 msvcrt kernel32 ntdll)
 
+add_delay_importlibs(netapi32 samlib)
+
 add_cd_file(TARGET netapi32 DESTINATION reactos/system32 FOR all)
 
index e125de5..ab37ee2 100644 (file)
 #include "wine/debug.h"
 #include "wine/unicode.h"
 
+#define NTOS_MODE_USER
+#include <ndk/rtlfuncs.h>
+#include "ntsam.h"
+#include "netapi32.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
 
+
+typedef struct _ENUM_CONTEXT
+{
+    SAM_HANDLE ServerHandle;
+    SAM_HANDLE BuiltinDomainHandle;
+    SAM_HANDLE AccountDomainHandle;
+
+    SAM_ENUMERATE_HANDLE EnumerationContext;
+    PSAM_RID_ENUMERATION EnumBuffer;
+    ULONG EnumReturned;
+
+} ENUM_CONTEXT, *PENUM_CONTEXT;
+
+static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+
+
+static
+NTSTATUS
+GetAccountDomainSid(PSID *AccountDomainSid)
+{
+    PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    LSA_HANDLE PolicyHandle = NULL;
+    ULONG Length = 0;
+    NTSTATUS Status;
+
+    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+
+    Status = LsaOpenPolicy(NULL,
+                           &ObjectAttributes,
+                           POLICY_VIEW_LOCAL_INFORMATION,
+                           &PolicyHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
+        return Status;
+    }
+
+    Status = LsaQueryInformationPolicy(PolicyHandle,
+                                       PolicyAccountDomainInformation,
+                                       (PVOID *)&AccountDomainInfo);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
+        goto done;
+    }
+
+    Length = RtlLengthSid(AccountDomainInfo->DomainSid);
+
+    *AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
+    if (*AccountDomainSid == NULL)
+    {
+        ERR("Failed to allocate SID\n");
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
+
+done:
+    if (AccountDomainInfo != NULL)
+        LsaFreeMemory(AccountDomainInfo);
+
+    LsaClose(PolicyHandle);
+
+    return Status;
+}
+
+
+static
+NTSTATUS
+GetBuiltinDomainSid(PSID *BuiltinDomainSid)
+{
+    PSID Sid = NULL;
+    PULONG Ptr;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    *BuiltinDomainSid = NULL;
+
+    Sid = RtlAllocateHeap(RtlGetProcessHeap(),
+                          0,
+                          RtlLengthRequiredSid(1));
+    if (Sid == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Status = RtlInitializeSid(Sid,
+                              &NtAuthority,
+                              1);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Ptr = RtlSubAuthoritySid(Sid, 0);
+    *Ptr = SECURITY_BUILTIN_DOMAIN_RID;
+
+    *BuiltinDomainSid = Sid;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (Sid != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
+    }
+
+    return Status;
+}
+
+
 /************************************************************
  *                NetLocalGroupAdd  (NETAPI32.@)
  */
@@ -129,11 +241,162 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
     LPDWORD totalentries,
     PDWORD_PTR resumehandle)
 {
+    PENUM_CONTEXT EnumContext = NULL;
+    PSID DomainSid = NULL;
+    ULONG i;
+
+    NET_API_STATUS ApiStatus = NERR_Success;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+
     FIXME("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername),
           level, bufptr, prefmaxlen, entriesread, totalentries, resumehandle);
+
     *entriesread = 0;
     *totalentries = 0;
-    return NERR_Success;
+    *bufptr = NULL;
+
+    if (resumehandle != NULL && *resumehandle != 0)
+    {
+        EnumContext = (PENUM_CONTEXT)resumehandle;
+    }
+    else
+    {
+        ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
+        if (ApiStatus != NERR_Success)
+            goto done;
+
+        EnumContext->EnumerationContext = 0;
+        EnumContext->EnumBuffer = NULL;
+        EnumContext->EnumReturned = 0;
+
+        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,
+                               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,
+                               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)
+    {
+        Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
+                                             &EnumContext->EnumerationContext,
+                                             (PVOID *)&EnumContext->EnumBuffer,
+                                             prefmaxlen,
+                                             &EnumContext->EnumReturned);
+
+        TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status);
+
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        TRACE("EnumContext: %lu\n", EnumContext);
+        TRACE("EnumReturned: %lu\n", EnumContext->EnumReturned);
+        TRACE("EnumBuffer: %p\n", EnumContext->EnumBuffer);
+
+        for (i = 0; i < EnumContext->EnumReturned; i++)
+        {
+            TRACE("RID: %lu\n", EnumContext->EnumBuffer[i].RelativeId);
+            TRACE("Name: %p\n", EnumContext->EnumBuffer[i].Name.Buffer);
+            TRACE("Name: %S\n", EnumContext->EnumBuffer[i].Name.Buffer);
+            if (EnumContext->EnumBuffer[i].Name.Buffer != NULL)
+            {
+                TRACE("Name: %hx\n", EnumContext->EnumBuffer[i].Name.Buffer[0]);
+            }
+        }
+
+        if (Status != STATUS_MORE_ENTRIES)
+            break;
+    }
+
+
+done:
+    if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
+    {
+        if (EnumContext != NULL)
+        {
+            if (EnumContext->BuiltinDomainHandle != NULL)
+                SamCloseHandle(EnumContext->BuiltinDomainHandle);
+
+            if (EnumContext->AccountDomainHandle != NULL)
+                SamCloseHandle(EnumContext->AccountDomainHandle);
+
+            if (EnumContext->ServerHandle != NULL)
+                SamCloseHandle(EnumContext->ServerHandle);
+
+            if (EnumContext->EnumBuffer != NULL)
+            {
+                for (i = 0; i < EnumContext->EnumReturned; i++)
+                {
+                    SamFreeMemory(EnumContext->EnumBuffer[i].Name.Buffer);
+                }
+
+                SamFreeMemory(EnumContext->EnumBuffer);
+            }
+
+            NetApiBufferFree(EnumContext);
+            EnumContext = NULL;
+        }
+    }
+
+
+    if (resumehandle != NULL)
+        *resumehandle = (DWORD_PTR)EnumContext;
+
+    return ApiStatus;
 }
 
 /************************************************************
index fb4468f..a0a8347 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_NO_STATUS
 #include "config.h"
 
 #include "wine/debug.h"
 #include "lm.h"
 #include "netbios.h"
 
+#define NTOS_MODE_USER
+#include <ndk/rtlfuncs.h>
+#include "netapi32.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
 
 static HMODULE NETAPI32_hModule;
@@ -211,6 +216,13 @@ DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc)
     return ret;
 }
 
+NET_API_STATUS
+WINAPI
+NetpNtStatusToApiStatus(NTSTATUS Status)
+{
+    return RtlNtStatusToDosError(Status);
+}
+
 NET_API_STATUS WINAPI NetUseEnum(LMSTR server, DWORD level, LPBYTE* bufptr, DWORD prefmaxsize,
                           LPDWORD entriesread, LPDWORD totalentries, LPDWORD resumehandle)
 {
diff --git a/reactos/dll/win32/netapi32/netapi32.h b/reactos/dll/win32/netapi32/netapi32.h
new file mode 100644 (file)
index 0000000..f7a0a7a
--- /dev/null
@@ -0,0 +1,10 @@
+
+#ifndef __WINE_NETAPI32_H__
+#define __WINE_NETAPI32_H__
+
+NET_API_STATUS
+WINAPI
+NetpNtStatusToApiStatus(NTSTATUS Status);
+
+
+#endif
\ No newline at end of file
index 6470280..1fb5ccf 100644 (file)
 @ stub NetpNetBiosReset
 @ stub NetpNetBiosSend
 @ stdcall NetpNetBiosStatusToApiStatus(long)
-@ stub NetpNtStatusToApiStatus
+@ stdcall NetpNtStatusToApiStatus(long)
 @ stub NetpOpenConfigData
 @ stub NetpPackString
 @ stub NetpReleasePrivilege