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