https://git.reactos.org/?p=reactos.git;a=commitdiff;h=23a90aab5a5b4eb323a9ca0b0a267dc156528422

commit 23a90aab5a5b4eb323a9ca0b0a267dc156528422
Author:     Eric Kohl <[email protected]>
AuthorDate: Sat Sep 8 14:14:13 2018 +0200
Commit:     Eric Kohl <[email protected]>
CommitDate: Sat Sep 8 14:18:36 2018 +0200

    [NET] Implement the group command
---
 base/applications/network/net/CMakeLists.txt |   1 +
 base/applications/network/net/cmdGroup.c     | 366 +++++++++++++++++++++++++++
 base/applications/network/net/lang/en-US.rc  |   5 +
 base/applications/network/net/lang/es-ES.rc  |   5 +
 base/applications/network/net/lang/ro-RO.rc  |   5 +
 base/applications/network/net/lang/ru-RU.rc  |   5 +
 base/applications/network/net/lang/tr-TR.rc  |   5 +
 base/applications/network/net/lang/zh-CN.rc  |   5 +
 base/applications/network/net/lang/zh-TW.rc  |   5 +
 base/applications/network/net/main.c         |   2 +-
 base/applications/network/net/net.h          |   1 +
 base/applications/network/net/resource.h     |   4 +
 12 files changed, 408 insertions(+), 1 deletion(-)

diff --git a/base/applications/network/net/CMakeLists.txt 
b/base/applications/network/net/CMakeLists.txt
index 3555509fa9..03f772bc09 100644
--- a/base/applications/network/net/CMakeLists.txt
+++ b/base/applications/network/net/CMakeLists.txt
@@ -8,6 +8,7 @@ list(APPEND SOURCE
     cmdAccounts.c
     cmdConfig.c
     cmdContinue.c
+    cmdGroup.c
     cmdHelpMsg.c
     cmdLocalGroup.c
     cmdPause.c
diff --git a/base/applications/network/net/cmdGroup.c 
b/base/applications/network/net/cmdGroup.c
new file mode 100644
index 0000000000..ccb5c6cb04
--- /dev/null
+++ b/base/applications/network/net/cmdGroup.c
@@ -0,0 +1,366 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS net command
+ * FILE:            base/applications/network/net/cmdGroup.c
+ * PROGRAMMERS:     Eric Kohl <[email protected]>
+ */
+
+#include "net.h"
+
+
+static
+int
+CompareInfo(const void *a,
+            const void *b)
+{
+    return _wcsicmp(((PGROUP_INFO_0)a)->grpi0_name,
+                    ((PGROUP_INFO_0)b)->grpi0_name);
+}
+
+
+static
+NET_API_STATUS
+EnumerateGroups(VOID)
+{
+    PGROUP_INFO_0 pBuffer = NULL;
+    PSERVER_INFO_100 pServer = NULL;
+    DWORD dwRead = 0, dwTotal = 0;
+    DWORD i;
+    DWORD_PTR ResumeHandle = 0;
+    NET_API_STATUS Status;
+
+    Status = NetServerGetInfo(NULL,
+                              100,
+                              (LPBYTE*)&pServer);
+    if (Status != NERR_Success)
+        return Status;
+
+    ConPuts(StdOut, L"\n");
+    ConResPrintf(StdOut, IDS_GROUP_GROUPS, pServer->sv100_name);
+    ConPuts(StdOut, L"\n\n");
+    PrintPadding(L'-', 79);
+    ConPuts(StdOut, L"\n");
+
+    NetApiBufferFree(pServer);
+
+    Status = NetGroupEnum(NULL,
+                          0,
+                          (LPBYTE*)&pBuffer,
+                          MAX_PREFERRED_LENGTH,
+                          &dwRead,
+                          &dwTotal,
+                          &ResumeHandle);
+    if (Status != NERR_Success)
+        return Status;
+
+    qsort(pBuffer,
+          dwRead,
+          sizeof(PGROUP_INFO_0),
+          CompareInfo);
+
+    for (i = 0; i < dwRead; i++)
+    {
+        if (pBuffer[i].grpi0_name)
+            ConPrintf(StdOut, L"*%s\n", pBuffer[i].grpi0_name);
+    }
+
+    NetApiBufferFree(pBuffer);
+
+    return NERR_Success;
+}
+
+
+static
+NET_API_STATUS
+DisplayGroup(LPWSTR lpGroupName)
+{
+    PGROUP_INFO_1 pGroupInfo = NULL;
+    PGROUP_USERS_INFO_0 pUsers = NULL;
+    LPWSTR *pNames = NULL;
+    DWORD dwRead = 0;
+    DWORD dwTotal = 0;
+    DWORD_PTR ResumeHandle = 0;
+    DWORD i;
+    INT nPaddedLength = 15;
+    NET_API_STATUS Status;
+
+    Status = NetGroupGetInfo(NULL,
+                             lpGroupName,
+                             1,
+                             (LPBYTE*)&pGroupInfo);
+    if (Status != NERR_Success)
+        return Status;
+
+    Status = NetGroupGetUsers(NULL,
+                              lpGroupName,
+                              0,
+                              (LPBYTE*)&pUsers,
+                              MAX_PREFERRED_LENGTH,
+                              &dwRead,
+                              &dwTotal,
+                              &ResumeHandle);
+    if (Status != NERR_Success)
+        goto done;
+
+    pNames = RtlAllocateHeap(RtlGetProcessHeap(),
+                             HEAP_ZERO_MEMORY,
+                             dwRead * sizeof(LPWSTR));
+    if (pNames == NULL)
+    {
+        Status = ERROR_OUTOFMEMORY;
+        goto done;
+    }
+
+    for (i = 0; i < dwRead; i++)
+    {
+        pNames[i] = pUsers[i].grui0_name;
+    }
+
+    PrintPaddedResourceString(IDS_GROUP_NAME, nPaddedLength);
+    ConPrintf(StdOut, L"%s\n", pGroupInfo->grpi1_name);
+
+    PrintPaddedResourceString(IDS_GROUP_COMMENT, nPaddedLength);
+    ConPrintf(StdOut, L"%s\n", pGroupInfo->grpi1_comment);
+
+    ConPuts(StdOut, L"\n");
+
+    ConResPuts(StdOut, IDS_GROUP_MEMBERS);
+    ConPuts(StdOut, L"\n\n");
+
+    PrintPadding(L'-', 79);
+    ConPuts(StdOut, L"\n");
+
+    for (i = 0; i < dwRead; i++)
+    {
+        if (pNames[i])
+            ConPrintf(StdOut, L"%s\n", pNames[i]);
+    }
+
+done:
+    if (pNames != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, pNames);
+
+    if (pUsers != NULL)
+        NetApiBufferFree(pUsers);
+
+    if (pGroupInfo != NULL)
+        NetApiBufferFree(pGroupInfo);
+
+    return Status;
+}
+
+
+INT
+cmdGroup(
+    INT argc,
+    WCHAR **argv)
+{
+    INT i, j;
+    INT result = 0;
+    ULONG dwUserCount = 0;
+    BOOL bAdd = FALSE;
+    BOOL bDelete = FALSE;
+#if 0
+    BOOL bDomain = FALSE;
+#endif
+    PWSTR pGroupName = NULL;
+    PWSTR pComment = NULL;
+    PWSTR *pUsers = NULL;
+    GROUP_INFO_0 Info0;
+    GROUP_INFO_1 Info1;
+    GROUP_INFO_1002 Info1002;
+    NET_API_STATUS Status;
+
+    if (argc == 2)
+    {
+        Status = EnumerateGroups();
+        ConPrintf(StdOut, L"Status: %lu\n", Status);
+        return 0;
+    }
+    else if (argc == 3)
+    {
+        Status = DisplayGroup(argv[2]);
+        ConPrintf(StdOut, L"Status: %lu\n", Status);
+        return 0;
+    }
+
+    i = 2;
+    if (argv[i][0] != L'/')
+    {
+        pGroupName = argv[i];
+        i++;
+    }
+
+    for (j = i; j < argc; j++)
+    {
+        if (argv[j][0] == L'/')
+            break;
+
+        dwUserCount++;
+    }
+
+    if (dwUserCount > 0)
+    {
+        pUsers = RtlAllocateHeap(RtlGetProcessHeap(),
+                                 HEAP_ZERO_MEMORY,
+                                 dwUserCount * sizeof(PGROUP_USERS_INFO_0));
+        if (pUsers == NULL)
+            return 0;
+    }
+
+    j = 0;
+    for (; i < argc; i++)
+    {
+        if (argv[i][0] == L'/')
+            break;
+
+        pUsers[j] = argv[i];
+        j++;
+    }
+
+    for (; i < argc; i++)
+    {
+        if (_wcsicmp(argv[i], L"/help") == 0)
+        {
+            ConResPuts(StdOut, IDS_GENERIC_SYNTAX);
+            ConResPuts(StdOut, IDS_GROUP_SYNTAX);
+            ConResPuts(StdOut, IDS_GROUP_HELP_1);
+            ConResPuts(StdOut, IDS_GROUP_HELP_2);
+            ConResPuts(StdOut, IDS_GROUP_HELP_3);
+            ConResPuts(StdOut, IDS_GROUP_HELP_4);
+            ConResPuts(StdOut, IDS_GROUP_HELP_5);
+            ConResPuts(StdOut, IDS_GROUP_HELP_6);
+            ConResPuts(StdOut, IDS_GROUP_HELP_7);
+            ConResPuts(StdOut, IDS_GENERIC_PAGE);
+            return 0;
+        }
+        else if (_wcsicmp(argv[i], L"/add") == 0)
+        {
+            bAdd = TRUE;
+        }
+        else if (_wcsicmp(argv[i], L"/delete") == 0)
+        {
+            bDelete = TRUE;
+        }
+        else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0)
+        {
+            pComment = &argv[i][9];
+        }
+        else if (_wcsicmp(argv[i], L"/domain") == 0)
+        {
+            ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/DOMAIN");
+#if 0
+            bDomain = TRUE;
+#endif
+        }
+        else
+        {
+            result = 1;
+            goto done;
+        }
+    }
+
+    if (pGroupName == NULL)
+    {
+        result = 1;
+        goto done;
+    }
+
+    if (bAdd && bDelete)
+    {
+        result = 1;
+        goto done;
+    }
+
+    if (pUsers == NULL)
+    {
+        if (!bAdd && !bDelete && pComment != NULL)
+        {
+            /* Set group comment */
+            Info1002.grpi1002_comment = pComment;
+            Status = NetGroupSetInfo(NULL,
+                                     pGroupName,
+                                     1002,
+                                     (LPBYTE)&Info1002,
+                                     NULL);
+            ConPrintf(StdOut, L"Status: %lu\n", Status);
+        }
+        else if (bAdd && !bDelete)
+        {
+            /* Add the group */
+            if (pComment == NULL)
+            {
+                Info0.grpi0_name = pGroupName;
+            }
+            else
+            {
+                Info1.grpi1_name = pGroupName;
+                Info1.grpi1_comment = pComment;
+            }
+
+            Status = NetGroupAdd(NULL,
+                                 (pComment == NULL) ? 0 : 1,
+                                 (pComment == NULL) ? (LPBYTE)&Info0 : 
(LPBYTE)&Info1,
+                                 NULL);
+            ConPrintf(StdOut, L"Status: %lu\n", Status);
+        }
+        else if (!bAdd && bDelete && pComment == NULL)
+        {
+            /* Delete the group */
+            Status = NetGroupDel(NULL,
+                                 pGroupName);
+            ConPrintf(StdOut, L"Status: %lu\n", Status);
+        }
+        else
+        {
+            result = 1;
+        }
+    }
+    else
+    {
+        if (bAdd && !bDelete && pComment == NULL)
+        {
+            /* Add group user */
+            for (i = 0; i < dwUserCount; i++)
+            {
+                Status = NetGroupAddUser(NULL,
+                                         pGroupName,
+                                         pUsers[i]);
+                if (Status != NERR_Success)
+                    break;
+            }
+            ConPrintf(StdOut, L"Status: %lu\n", Status);
+        }
+        else if (!bAdd && bDelete && pComment == NULL)
+        {
+            /* Delete group members */
+            for (i = 0; i < dwUserCount; i++)
+            {
+                Status = NetGroupDelUser(NULL,
+                                         pGroupName,
+                                         pUsers[i]);
+                if (Status != NERR_Success)
+                    break;
+            }
+            ConPrintf(StdOut, L"Status: %lu\n", Status);
+        }
+        else
+        {
+            result = 1;
+        }
+    }
+
+done:
+    if (pUsers != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, pUsers);
+
+    if (result != 0)
+    {
+        ConResPuts(StdOut, IDS_GENERIC_SYNTAX);
+        ConResPuts(StdOut, IDS_GROUP_SYNTAX);
+    }
+
+    return result;
+}
+
+/* EOF */
diff --git a/base/applications/network/net/lang/en-US.rc 
b/base/applications/network/net/lang/en-US.rc
index 793344d10f..c8c3b6e4b2 100644
--- a/base/applications/network/net/lang/en-US.rc
+++ b/base/applications/network/net/lang/en-US.rc
@@ -221,6 +221,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "Aliases for \\\\%s"
     IDS_LOCALGROUP_ALIAS_NAME "Alias name"
     IDS_LOCALGROUP_COMMENT "Comment"
diff --git a/base/applications/network/net/lang/es-ES.rc 
b/base/applications/network/net/lang/es-ES.rc
index b86e48a05a..45619ea332 100644
--- a/base/applications/network/net/lang/es-ES.rc
+++ b/base/applications/network/net/lang/es-ES.rc
@@ -221,6 +221,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "Alias de \\\\%s"
     IDS_LOCALGROUP_ALIAS_NAME "Nombre del alias"
     IDS_LOCALGROUP_COMMENT "Comentario"
diff --git a/base/applications/network/net/lang/ro-RO.rc 
b/base/applications/network/net/lang/ro-RO.rc
index a2c9963a2e..647e51d53c 100644
--- a/base/applications/network/net/lang/ro-RO.rc
+++ b/base/applications/network/net/lang/ro-RO.rc
@@ -224,6 +224,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "Alias pentru \\\\%s"
     IDS_LOCALGROUP_ALIAS_NAME "Nume alias"
     IDS_LOCALGROUP_COMMENT "Comentariu"
diff --git a/base/applications/network/net/lang/ru-RU.rc 
b/base/applications/network/net/lang/ru-RU.rc
index 7d91bd56b1..69b275a275 100644
--- a/base/applications/network/net/lang/ru-RU.rc
+++ b/base/applications/network/net/lang/ru-RU.rc
@@ -220,6 +220,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "Псевдонимы для \\\\%s"
     IDS_LOCALGROUP_ALIAS_NAME "Имя псевдонима"
     IDS_LOCALGROUP_COMMENT "Комментарий"
diff --git a/base/applications/network/net/lang/tr-TR.rc 
b/base/applications/network/net/lang/tr-TR.rc
index 203f82be88..3fb24e39c2 100644
--- a/base/applications/network/net/lang/tr-TR.rc
+++ b/base/applications/network/net/lang/tr-TR.rc
@@ -220,6 +220,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "\\\\%s için başka adlar"
     IDS_LOCALGROUP_ALIAS_NAME "Başka ad"
     IDS_LOCALGROUP_COMMENT "Açıklama"
diff --git a/base/applications/network/net/lang/zh-CN.rc 
b/base/applications/network/net/lang/zh-CN.rc
index 14de45cdfb..b643c14d1a 100644
--- a/base/applications/network/net/lang/zh-CN.rc
+++ b/base/applications/network/net/lang/zh-CN.rc
@@ -220,6 +220,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "\\\\%s 的别名"
     IDS_LOCALGROUP_ALIAS_NAME "别名名称"
     IDS_LOCALGROUP_COMMENT "注释"
diff --git a/base/applications/network/net/lang/zh-TW.rc 
b/base/applications/network/net/lang/zh-TW.rc
index 08a0f88380..1673f953ae 100644
--- a/base/applications/network/net/lang/zh-TW.rc
+++ b/base/applications/network/net/lang/zh-TW.rc
@@ -220,6 +220,11 @@ service can stop others. Some services cannot be 
stopped.\n\n"
     IDS_CONFIG_WORKSTATION_DOMAIN "Workstation domain"
     IDS_CONFIG_WORKSTATION_LOGON "Logon domain"
 
+    IDS_GROUP_GROUPS "Group Accounts for \\\\%s"
+    IDS_GROUP_NAME "Group name"
+    IDS_GROUP_COMMENT "Comment"
+    IDS_GROUP_MEMBERS "Members"
+
     IDS_LOCALGROUP_ALIASES "別名 \\\\%s"
     IDS_LOCALGROUP_ALIAS_NAME "別名名稱"
     IDS_LOCALGROUP_COMMENT "評論"
diff --git a/base/applications/network/net/main.c 
b/base/applications/network/net/main.c
index 5b2ad60b78..298b875caf 100644
--- a/base/applications/network/net/main.c
+++ b/base/applications/network/net/main.c
@@ -25,7 +25,7 @@ COMMAND cmds[] =
     {L"config",     cmdConfig},
     {L"continue",   cmdContinue},
     {L"file",       unimplemented},
-    {L"group",      unimplemented},
+    {L"group",      cmdGroup},
     {L"help",       cmdHelp},
     {L"helpmsg",    cmdHelpMsg},
     {L"localgroup", cmdLocalGroup},
diff --git a/base/applications/network/net/net.h 
b/base/applications/network/net/net.h
index a595166af5..3f04b18502 100644
--- a/base/applications/network/net/net.h
+++ b/base/applications/network/net/net.h
@@ -48,6 +48,7 @@ INT unimplemented(INT argc, WCHAR **argv);
 INT cmdAccounts(INT argc, WCHAR **argv);
 INT cmdConfig(INT argc, WCHAR **argv);
 INT cmdContinue(INT argc, WCHAR **argv);
+INT cmdGroup(INT argc, WCHAR **argv);
 INT cmdHelp(INT argc, WCHAR **argv);
 INT cmdHelpMsg(INT argc, WCHAR **argv);
 INT cmdLocalGroup(INT argc, WCHAR **argv);
diff --git a/base/applications/network/net/resource.h 
b/base/applications/network/net/resource.h
index beff7b0f3c..84d5f878a7 100644
--- a/base/applications/network/net/resource.h
+++ b/base/applications/network/net/resource.h
@@ -116,6 +116,10 @@
 #define IDS_CONFIG_WORKSTATION_DOMAIN   244
 #define IDS_CONFIG_WORKSTATION_LOGON    245
 
+#define IDS_GROUP_GROUPS                260
+#define IDS_GROUP_NAME                  261
+#define IDS_GROUP_COMMENT               262
+#define IDS_GROUP_MEMBERS               263
 
 #define IDS_LOCALGROUP_ALIASES          300
 #define IDS_LOCALGROUP_ALIAS_NAME       301

Reply via email to