1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS net command 4 * FILE: base/applications/network/net/cmdGroup.c 5 * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org> 6 */ 7 8 #include "net.h" 9 10 11 static 12 int 13 CompareInfo(const void *a, 14 const void *b) 15 { 16 return _wcsicmp(((PGROUP_INFO_0)a)->grpi0_name, 17 ((PGROUP_INFO_0)b)->grpi0_name); 18 } 19 20 21 static 22 NET_API_STATUS 23 EnumerateGroups(VOID) 24 { 25 PGROUP_INFO_0 pBuffer = NULL; 26 PSERVER_INFO_100 pServer = NULL; 27 DWORD dwRead = 0, dwTotal = 0; 28 DWORD i; 29 DWORD_PTR ResumeHandle = 0; 30 NET_API_STATUS Status; 31 32 Status = NetServerGetInfo(NULL, 33 100, 34 (LPBYTE*)&pServer); 35 if (Status != NERR_Success) 36 return Status; 37 38 ConPuts(StdOut, L"\n"); 39 ConResPrintf(StdOut, IDS_GROUP_GROUPS, pServer->sv100_name); 40 ConPuts(StdOut, L"\n\n"); 41 PrintPadding(L'-', 79); 42 ConPuts(StdOut, L"\n"); 43 44 NetApiBufferFree(pServer); 45 46 Status = NetGroupEnum(NULL, 47 0, 48 (LPBYTE*)&pBuffer, 49 MAX_PREFERRED_LENGTH, 50 &dwRead, 51 &dwTotal, 52 &ResumeHandle); 53 if (Status != NERR_Success) 54 return Status; 55 56 qsort(pBuffer, 57 dwRead, 58 sizeof(PGROUP_INFO_0), 59 CompareInfo); 60 61 for (i = 0; i < dwRead; i++) 62 { 63 if (pBuffer[i].grpi0_name) 64 ConPrintf(StdOut, L"*%s\n", pBuffer[i].grpi0_name); 65 } 66 67 NetApiBufferFree(pBuffer); 68 69 return NERR_Success; 70 } 71 72 73 static 74 NET_API_STATUS 75 DisplayGroup(LPWSTR lpGroupName) 76 { 77 PGROUP_INFO_1 pGroupInfo = NULL; 78 PGROUP_USERS_INFO_0 pUsers = NULL; 79 LPWSTR *pNames = NULL; 80 DWORD dwRead = 0; 81 DWORD dwTotal = 0; 82 DWORD_PTR ResumeHandle = 0; 83 DWORD i; 84 INT nPaddedLength = 15; 85 NET_API_STATUS Status; 86 87 Status = NetGroupGetInfo(NULL, 88 lpGroupName, 89 1, 90 (LPBYTE*)&pGroupInfo); 91 if (Status != NERR_Success) 92 return Status; 93 94 Status = NetGroupGetUsers(NULL, 95 lpGroupName, 96 0, 97 (LPBYTE*)&pUsers, 98 MAX_PREFERRED_LENGTH, 99 &dwRead, 100 &dwTotal, 101 &ResumeHandle); 102 if (Status != NERR_Success) 103 goto done; 104 105 pNames = RtlAllocateHeap(RtlGetProcessHeap(), 106 HEAP_ZERO_MEMORY, 107 dwRead * sizeof(LPWSTR)); 108 if (pNames == NULL) 109 { 110 Status = ERROR_OUTOFMEMORY; 111 goto done; 112 } 113 114 for (i = 0; i < dwRead; i++) 115 { 116 pNames[i] = pUsers[i].grui0_name; 117 } 118 119 PrintPaddedResourceString(IDS_GROUP_NAME, nPaddedLength); 120 ConPrintf(StdOut, L"%s\n", pGroupInfo->grpi1_name); 121 122 PrintPaddedResourceString(IDS_GROUP_COMMENT, nPaddedLength); 123 ConPrintf(StdOut, L"%s\n", pGroupInfo->grpi1_comment); 124 125 ConPuts(StdOut, L"\n"); 126 127 ConResPuts(StdOut, IDS_GROUP_MEMBERS); 128 ConPuts(StdOut, L"\n\n"); 129 130 PrintPadding(L'-', 79); 131 ConPuts(StdOut, L"\n"); 132 133 for (i = 0; i < dwRead; i++) 134 { 135 if (pNames[i]) 136 ConPrintf(StdOut, L"%s\n", pNames[i]); 137 } 138 139 done: 140 if (pNames != NULL) 141 RtlFreeHeap(RtlGetProcessHeap(), 0, pNames); 142 143 if (pUsers != NULL) 144 NetApiBufferFree(pUsers); 145 146 if (pGroupInfo != NULL) 147 NetApiBufferFree(pGroupInfo); 148 149 return Status; 150 } 151 152 153 INT 154 cmdGroup( 155 INT argc, 156 WCHAR **argv) 157 { 158 INT i, j; 159 INT result = 0; 160 ULONG dwUserCount = 0; 161 BOOL bAdd = FALSE; 162 BOOL bDelete = FALSE; 163 #if 0 164 BOOL bDomain = FALSE; 165 #endif 166 PWSTR pGroupName = NULL; 167 PWSTR pComment = NULL; 168 PWSTR *pUsers = NULL; 169 GROUP_INFO_0 Info0; 170 GROUP_INFO_1 Info1; 171 GROUP_INFO_1002 Info1002; 172 NET_API_STATUS Status; 173 174 if (argc == 2) 175 { 176 Status = EnumerateGroups(); 177 ConPrintf(StdOut, L"Status: %lu\n", Status); 178 return 0; 179 } 180 else if (argc == 3) 181 { 182 Status = DisplayGroup(argv[2]); 183 ConPrintf(StdOut, L"Status: %lu\n", Status); 184 return 0; 185 } 186 187 i = 2; 188 if (argv[i][0] != L'/') 189 { 190 pGroupName = argv[i]; 191 i++; 192 } 193 194 for (j = i; j < argc; j++) 195 { 196 if (argv[j][0] == L'/') 197 break; 198 199 dwUserCount++; 200 } 201 202 if (dwUserCount > 0) 203 { 204 pUsers = RtlAllocateHeap(RtlGetProcessHeap(), 205 HEAP_ZERO_MEMORY, 206 dwUserCount * sizeof(PGROUP_USERS_INFO_0)); 207 if (pUsers == NULL) 208 return 0; 209 } 210 211 j = 0; 212 for (; i < argc; i++) 213 { 214 if (argv[i][0] == L'/') 215 break; 216 217 pUsers[j] = argv[i]; 218 j++; 219 } 220 221 for (; i < argc; i++) 222 { 223 if (_wcsicmp(argv[i], L"/help") == 0) 224 { 225 ConResPuts(StdOut, IDS_GENERIC_SYNTAX); 226 PrintNetMessage(MSG_GROUP_SYNTAX); 227 PrintNetMessage(MSG_GROUP_HELP); 228 ConResPuts(StdOut, IDS_GENERIC_PAGE); 229 return 0; 230 } 231 else if (_wcsicmp(argv[i], L"/add") == 0) 232 { 233 bAdd = TRUE; 234 } 235 else if (_wcsicmp(argv[i], L"/delete") == 0) 236 { 237 bDelete = TRUE; 238 } 239 else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0) 240 { 241 pComment = &argv[i][9]; 242 } 243 else if (_wcsicmp(argv[i], L"/domain") == 0) 244 { 245 ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/DOMAIN"); 246 #if 0 247 bDomain = TRUE; 248 #endif 249 } 250 else 251 { 252 PrintErrorMessage(3506/*, argv[i]*/); 253 result = 1; 254 goto done; 255 } 256 } 257 258 if (pGroupName == NULL) 259 { 260 result = 1; 261 goto done; 262 } 263 264 if (bAdd && bDelete) 265 { 266 result = 1; 267 goto done; 268 } 269 270 if (pUsers == NULL) 271 { 272 if (!bAdd && !bDelete && pComment != NULL) 273 { 274 /* Set group comment */ 275 Info1002.grpi1002_comment = pComment; 276 Status = NetGroupSetInfo(NULL, 277 pGroupName, 278 1002, 279 (LPBYTE)&Info1002, 280 NULL); 281 ConPrintf(StdOut, L"Status: %lu\n", Status); 282 } 283 else if (bAdd && !bDelete) 284 { 285 /* Add the group */ 286 if (pComment == NULL) 287 { 288 Info0.grpi0_name = pGroupName; 289 } 290 else 291 { 292 Info1.grpi1_name = pGroupName; 293 Info1.grpi1_comment = pComment; 294 } 295 296 Status = NetGroupAdd(NULL, 297 (pComment == NULL) ? 0 : 1, 298 (pComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1, 299 NULL); 300 ConPrintf(StdOut, L"Status: %lu\n", Status); 301 } 302 else if (!bAdd && bDelete && pComment == NULL) 303 { 304 /* Delete the group */ 305 Status = NetGroupDel(NULL, 306 pGroupName); 307 ConPrintf(StdOut, L"Status: %lu\n", Status); 308 } 309 else 310 { 311 result = 1; 312 } 313 } 314 else 315 { 316 if (bAdd && !bDelete && pComment == NULL) 317 { 318 /* Add group user */ 319 for (i = 0; i < dwUserCount; i++) 320 { 321 Status = NetGroupAddUser(NULL, 322 pGroupName, 323 pUsers[i]); 324 if (Status != NERR_Success) 325 break; 326 } 327 ConPrintf(StdOut, L"Status: %lu\n", Status); 328 } 329 else if (!bAdd && bDelete && pComment == NULL) 330 { 331 /* Delete group members */ 332 for (i = 0; i < dwUserCount; i++) 333 { 334 Status = NetGroupDelUser(NULL, 335 pGroupName, 336 pUsers[i]); 337 if (Status != NERR_Success) 338 break; 339 } 340 ConPrintf(StdOut, L"Status: %lu\n", Status); 341 } 342 else 343 { 344 result = 1; 345 } 346 } 347 348 done: 349 if (pUsers != NULL) 350 RtlFreeHeap(RtlGetProcessHeap(), 0, pUsers); 351 352 if (result != 0) 353 { 354 ConResPuts(StdOut, IDS_GENERIC_SYNTAX); 355 PrintNetMessage(MSG_GROUP_SYNTAX); 356 } 357 358 return result; 359 } 360 361 /* EOF */ 362