1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS net command 4 * FILE: base/applications/network/net/cmdLocalGroup.c 5 * PURPOSE: 6 * 7 * PROGRAMMERS: Eric Kohl 8 */ 9 10 #include "net.h" 11 12 13 static 14 int 15 CompareInfo(const void *a, 16 const void *b) 17 { 18 return _wcsicmp(((PLOCALGROUP_INFO_0)a)->lgrpi0_name, 19 ((PLOCALGROUP_INFO_0)b)->lgrpi0_name); 20 } 21 22 23 static 24 NET_API_STATUS 25 EnumerateLocalGroups(VOID) 26 { 27 PLOCALGROUP_INFO_0 pBuffer = NULL; 28 PSERVER_INFO_100 pServer = NULL; 29 DWORD dwRead = 0, dwTotal = 0; 30 DWORD i; 31 DWORD_PTR ResumeHandle = 0; 32 NET_API_STATUS Status; 33 34 35 Status = NetServerGetInfo(NULL, 36 100, 37 (LPBYTE*)&pServer); 38 if (Status != NERR_Success) 39 return Status; 40 41 ConPuts(StdOut, L"\n"); 42 PrintMessageStringV(4405, pServer->sv100_name); 43 ConPuts(StdOut, L"\n"); 44 PrintPadding(L'-', 79); 45 ConPuts(StdOut, L"\n"); 46 47 NetApiBufferFree(pServer); 48 49 Status = NetLocalGroupEnum(NULL, 50 0, 51 (LPBYTE*)&pBuffer, 52 MAX_PREFERRED_LENGTH, 53 &dwRead, 54 &dwTotal, 55 &ResumeHandle); 56 if (Status != NERR_Success) 57 return Status; 58 59 qsort(pBuffer, 60 dwRead, 61 sizeof(PLOCALGROUP_INFO_0), 62 CompareInfo); 63 64 for (i = 0; i < dwRead; i++) 65 { 66 if (pBuffer[i].lgrpi0_name) 67 ConPrintf(StdOut, L"*%s\n", pBuffer[i].lgrpi0_name); 68 } 69 70 NetApiBufferFree(pBuffer); 71 72 return NERR_Success; 73 } 74 75 76 static 77 NET_API_STATUS 78 DisplayLocalGroup(LPWSTR lpGroupName) 79 { 80 PLOCALGROUP_INFO_1 pGroupInfo = NULL; 81 PLOCALGROUP_MEMBERS_INFO_3 pMembers = NULL; 82 PSERVER_INFO_100 pServer = NULL; 83 LPWSTR *pNames = NULL; 84 DWORD dwRead = 0; 85 DWORD dwTotal = 0; 86 DWORD_PTR ResumeHandle = 0; 87 DWORD i; 88 DWORD len; 89 INT nPaddedLength = 18; 90 NET_API_STATUS Status; 91 92 Status = NetLocalGroupGetInfo(NULL, 93 lpGroupName, 94 1, 95 (LPBYTE*)&pGroupInfo); 96 if (Status != NERR_Success) 97 return Status; 98 99 Status = NetLocalGroupGetMembers(NULL, 100 lpGroupName, 101 3, 102 (LPBYTE*)&pMembers, 103 MAX_PREFERRED_LENGTH, 104 &dwRead, 105 &dwTotal, 106 &ResumeHandle); 107 if (Status != NERR_Success) 108 goto done; 109 110 Status = NetServerGetInfo(NULL, 111 100, 112 (LPBYTE*)&pServer); 113 if (Status != NERR_Success) 114 goto done; 115 116 pNames = RtlAllocateHeap(RtlGetProcessHeap(), 117 HEAP_ZERO_MEMORY, 118 dwRead * sizeof(LPWSTR)); 119 if (pNames == NULL) 120 { 121 Status = ERROR_OUTOFMEMORY; 122 goto done; 123 } 124 125 len = wcslen(pServer->sv100_name); 126 for (i = 0; i < dwRead; i++) 127 { 128 if (!wcsncmp(pMembers[i].lgrmi3_domainandname, pServer->sv100_name, len)) 129 pNames[i] = &pMembers[i].lgrmi3_domainandname[len + 1]; 130 else 131 pNames[i] = pMembers[i].lgrmi3_domainandname; 132 } 133 134 PrintPaddedMessageString(4406, nPaddedLength); 135 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_name); 136 137 PrintPaddedMessageString(4407, nPaddedLength); 138 ConPrintf(StdOut, L"%s\n", pGroupInfo->lgrpi1_comment); 139 140 ConPuts(StdOut, L"\n"); 141 142 PrintMessageString(4408); 143 ConPuts(StdOut, L"\n"); 144 145 PrintPadding(L'-', 79); 146 ConPuts(StdOut, L"\n"); 147 148 for (i = 0; i < dwRead; i++) 149 { 150 if (pNames[i]) 151 ConPrintf(StdOut, L"%s\n", pNames[i]); 152 } 153 154 done: 155 if (pNames != NULL) 156 RtlFreeHeap(RtlGetProcessHeap(), 0, pNames); 157 158 if (pServer != NULL) 159 NetApiBufferFree(pServer); 160 161 if (pMembers != NULL) 162 NetApiBufferFree(pMembers); 163 164 if (pGroupInfo != NULL) 165 NetApiBufferFree(pGroupInfo); 166 167 return Status; 168 } 169 170 171 INT 172 cmdLocalGroup( 173 INT argc, 174 WCHAR **argv) 175 { 176 INT i, j; 177 INT result = 0; 178 ULONG dwMemberCount = 0; 179 BOOL bAdd = FALSE; 180 BOOL bDelete = FALSE; 181 #if 0 182 BOOL bDomain = FALSE; 183 #endif 184 LPWSTR lpGroupName = NULL; 185 LPWSTR lpComment = NULL; 186 LPLOCALGROUP_MEMBERS_INFO_3 lpMembers = NULL; 187 LOCALGROUP_INFO_0 Info0; 188 LOCALGROUP_INFO_1 Info1; 189 LOCALGROUP_INFO_1002 Info1002; 190 NET_API_STATUS Status; 191 192 if (argc == 2) 193 { 194 Status = EnumerateLocalGroups(); 195 ConPrintf(StdOut, L"Status: %lu\n", Status); 196 return 0; 197 } 198 else if (argc == 3) 199 { 200 Status = DisplayLocalGroup(argv[2]); 201 ConPrintf(StdOut, L"Status: %lu\n", Status); 202 return 0; 203 } 204 205 i = 2; 206 if (argv[i][0] != L'/') 207 { 208 lpGroupName = argv[i]; 209 i++; 210 } 211 212 for (j = i; j < argc; j++) 213 { 214 if (argv[j][0] == L'/') 215 break; 216 217 dwMemberCount++; 218 } 219 220 ConPrintf(StdOut, L"Member count: %lu\n", dwMemberCount); 221 222 if (dwMemberCount > 0) 223 { 224 lpMembers = RtlAllocateHeap(RtlGetProcessHeap(), 225 HEAP_ZERO_MEMORY, 226 dwMemberCount * sizeof(LPLOCALGROUP_MEMBERS_INFO_3)); 227 if (lpMembers == NULL) 228 return 0; 229 } 230 231 j = 0; 232 for (; i < argc; i++) 233 { 234 if (argv[i][0] == L'/') 235 break; 236 237 lpMembers[j].lgrmi3_domainandname = argv[i]; 238 j++; 239 } 240 241 for (; i < argc; i++) 242 { 243 if (_wcsicmp(argv[i], L"/help") == 0) 244 { 245 PrintMessageString(4381); 246 ConPuts(StdOut, L"\n"); 247 PrintNetMessage(MSG_LOCALGROUP_SYNTAX); 248 PrintNetMessage(MSG_LOCALGROUP_HELP); 249 return 0; 250 } 251 else if (_wcsicmp(argv[i], L"/add") == 0) 252 { 253 bAdd = TRUE; 254 } 255 else if (_wcsicmp(argv[i], L"/delete") == 0) 256 { 257 bDelete = TRUE; 258 } 259 else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0) 260 { 261 lpComment = &argv[i][9]; 262 } 263 else if (_wcsicmp(argv[i], L"/domain") == 0) 264 { 265 ConPuts(StdErr, L"The /DOMAIN option is not supported yet.\n"); 266 #if 0 267 bDomain = TRUE; 268 #endif 269 } 270 else 271 { 272 PrintErrorMessage(3506/*, argv[i]*/); 273 result = 1; 274 goto done; 275 } 276 } 277 278 if (lpGroupName == NULL) 279 { 280 result = 1; 281 goto done; 282 } 283 284 if (bAdd && bDelete) 285 { 286 result = 1; 287 goto done; 288 } 289 290 #if 0 291 ConPrintf(StdOut, L"Group:\n %s\n", lpGroupName); 292 293 if (lpMembers != NULL) 294 { 295 ConPuts(StdOut, L"\nMembers:\n"); 296 for (i = 0; i < dwMemberCount; i++) 297 ConPrintf(StdOut, L" %s\n", lpMembers[i].lgrmi3_domainandname); 298 } 299 300 if (lpComment != NULL) 301 { 302 ConPrintf(StdOut, L"\nComment:\n %s\n", lpComment); 303 } 304 #endif 305 306 if (lpMembers == NULL) 307 { 308 if (!bAdd && !bDelete && lpComment != NULL) 309 { 310 /* Set group comment */ 311 Info1002.lgrpi1002_comment = lpComment; 312 Status = NetLocalGroupSetInfo(NULL, 313 lpGroupName, 314 1002, 315 (LPBYTE)&Info1002, 316 NULL); 317 ConPrintf(StdOut, L"Status: %lu\n", Status); 318 } 319 else if (bAdd && !bDelete) 320 { 321 /* Add the group */ 322 if (lpComment == NULL) 323 { 324 Info0.lgrpi0_name = lpGroupName; 325 } 326 else 327 { 328 Info1.lgrpi1_name = lpGroupName; 329 Info1.lgrpi1_comment = lpComment; 330 } 331 332 Status = NetLocalGroupAdd(NULL, 333 (lpComment == NULL) ? 0 : 1, 334 (lpComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1, 335 NULL); 336 ConPrintf(StdOut, L"Status: %lu\n", Status); 337 } 338 else if (!bAdd && bDelete && lpComment == NULL) 339 { 340 /* Delete the group */ 341 Status = NetLocalGroupDel(NULL, 342 lpGroupName); 343 ConPrintf(StdOut, L"Status: %lu\n", Status); 344 } 345 else 346 { 347 result = 1; 348 } 349 } 350 else 351 { 352 if (bAdd && !bDelete && lpComment == NULL) 353 { 354 /* Add group members */ 355 Status = NetLocalGroupAddMembers(NULL, 356 lpGroupName, 357 3, 358 (LPBYTE)lpMembers, 359 dwMemberCount); 360 ConPrintf(StdOut, L"Status: %lu\n", Status); 361 } 362 else if (!bAdd && bDelete && lpComment == NULL) 363 { 364 /* Delete group members */ 365 Status = NetLocalGroupDelMembers(NULL, 366 lpGroupName, 367 3, 368 (LPBYTE)lpMembers, 369 dwMemberCount); 370 ConPrintf(StdOut, L"Status: %lu\n", Status); 371 } 372 else 373 { 374 result = 1; 375 } 376 } 377 378 done: 379 if (lpMembers != NULL) 380 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMembers); 381 382 if (result != 0) 383 { 384 PrintMessageString(4381); 385 ConPuts(StdOut, L"\n"); 386 PrintNetMessage(MSG_LOCALGROUP_SYNTAX); 387 } 388 389 return result; 390 } 391 392 /* EOF */ 393