[NET] Implement the group command
authorEric Kohl <eric.kohl@reactos.org>
Sat, 8 Sep 2018 12:14:13 +0000 (14:14 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 8 Sep 2018 12:18:36 +0000 (14:18 +0200)
12 files changed:
base/applications/network/net/CMakeLists.txt
base/applications/network/net/cmdGroup.c [new file with mode: 0644]
base/applications/network/net/lang/en-US.rc
base/applications/network/net/lang/es-ES.rc
base/applications/network/net/lang/ro-RO.rc
base/applications/network/net/lang/ru-RU.rc
base/applications/network/net/lang/tr-TR.rc
base/applications/network/net/lang/zh-CN.rc
base/applications/network/net/lang/zh-TW.rc
base/applications/network/net/main.c
base/applications/network/net/net.h
base/applications/network/net/resource.h

index 3555509..03f772b 100644 (file)
@@ -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 (file)
index 0000000..ccb5c6c
--- /dev/null
@@ -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 <eric.kohl@reactos.org>
+ */
+
+#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 */
index 793344d..c8c3b6e 100644 (file)
@@ -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"
index b86e48a..45619ea 100644 (file)
@@ -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"
index a2c9963..647e51d 100644 (file)
@@ -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"
index 7d91bd5..69b275a 100644 (file)
@@ -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 "Комментарий"
index 203f82b..3fb24e3 100644 (file)
@@ -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"
index 14de45c..b643c14 100644 (file)
@@ -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 "注释"
index 08a0f88..1673f95 100644 (file)
@@ -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 "評論"
index 5b2ad60..298b875 100644 (file)
@@ -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},
index a595166..3f04b18 100644 (file)
@@ -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);
index beff7b0..84d5f87 100644 (file)
 #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