Partial merge of condrv_restructure branch r65657.
[reactos.git] / reactos / 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 PrintPadding(L'-', 79);
45 PrintToConsole(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 PrintToConsole(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 PrintPaddedResourceString(IDS_LOCALGROUP_ALIAS_NAME, nPaddedLength);
135 PrintToConsole(L"%s\n", pGroupInfo->lgrpi1_name);
136
137 PrintPaddedResourceString(IDS_LOCALGROUP_COMMENT, nPaddedLength);
138 PrintToConsole(L"%s\n", pGroupInfo->lgrpi1_comment);
139
140 PrintToConsole(L"\n");
141
142 PrintResourceString(IDS_LOCALGROUP_MEMBERS);
143 PrintToConsole(L"\n\n");
144
145 PrintPadding(L'-', 79);
146 PrintToConsole(L"\n");
147
148 for (i = 0; i < dwRead; i++)
149 {
150 if (pNames[i])
151 PrintToConsole(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 printf("Status: %lu\n", Status);
196 return 0;
197 }
198 else if (argc == 3)
199 {
200 Status = DisplayLocalGroup(argv[2]);
201 printf("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 printf("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 PrintResourceString(IDS_LOCALGROUP_HELP);
246 return 0;
247 }
248 else if (_wcsicmp(argv[i], L"/add") == 0)
249 {
250 bAdd = TRUE;
251 }
252 else if (_wcsicmp(argv[i], L"/delete") == 0)
253 {
254 bDelete = TRUE;
255 }
256 else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0)
257 {
258 lpComment = &argv[i][9];
259 }
260 else if (_wcsicmp(argv[i], L"/domain") == 0)
261 {
262 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED, L"/DOMAIN");
263 #if 0
264 bDomain = TRUE;
265 #endif
266 }
267 else
268 {
269 result = 1;
270 goto done;
271 }
272 }
273
274 if (lpGroupName == NULL)
275 {
276 result = 1;
277 goto done;
278 }
279
280 if (bAdd && bDelete)
281 {
282 result = 1;
283 goto done;
284 }
285
286 #if 0
287 printf("Group:\n %S\n", lpGroupName);
288
289 if (lpMembers != NULL)
290 {
291 printf("\nMembers:\n");
292 for (i = 0; i < dwMemberCount; i++)
293 printf(" %S\n", lpMembers[i].lgrmi3_domainandname);
294 }
295
296 if (lpComment != NULL)
297 {
298 printf("\nComment:\n %S\n", lpComment);
299 }
300 #endif
301
302 if (lpMembers == NULL)
303 {
304 if (!bAdd && !bDelete && lpComment != NULL)
305 {
306 /* Set group comment */
307 Info1002.lgrpi1002_comment = lpComment;
308 Status = NetLocalGroupSetInfo(NULL,
309 lpGroupName,
310 1002,
311 (LPBYTE)&Info1002,
312 NULL);
313 printf("Status: %lu\n", Status);
314 }
315 else if (bAdd && !bDelete)
316 {
317 /* Add the group */
318 if (lpComment == NULL)
319 {
320 Info0.lgrpi0_name = lpGroupName;
321 }
322 else
323 {
324 Info1.lgrpi1_name = lpGroupName;
325 Info1.lgrpi1_comment = lpComment;
326 }
327
328 Status = NetLocalGroupAdd(NULL,
329 (lpComment == NULL) ? 0 : 1,
330 (lpComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1,
331 NULL);
332 printf("Status: %lu\n", Status);
333 }
334 else if (!bAdd && bDelete && lpComment == NULL)
335 {
336 /* Delete the group */
337 Status = NetLocalGroupDel(NULL,
338 lpGroupName);
339 printf("Status: %lu\n", Status);
340 }
341 else
342 {
343 result = 1;
344 }
345 }
346 else
347 {
348 if (bAdd && !bDelete && lpComment == NULL)
349 {
350 /* Add group members */
351 Status = NetLocalGroupAddMembers(NULL,
352 lpGroupName,
353 3,
354 (LPBYTE)lpMembers,
355 dwMemberCount);
356 printf("Status: %lu\n", Status);
357 }
358 else if (!bAdd && bDelete && lpComment == NULL)
359 {
360 /* Delete group members */
361 Status = NetLocalGroupDelMembers(NULL,
362 lpGroupName,
363 3,
364 (LPBYTE)lpMembers,
365 dwMemberCount);
366 printf("Status: %lu\n", Status);
367 }
368 else
369 {
370 result = 1;
371 }
372 }
373
374 done:
375 if (lpMembers != NULL)
376 RtlFreeHeap(RtlGetProcessHeap(), 0, lpMembers);
377
378 if (result != 0)
379 PrintResourceString(IDS_LOCALGROUP_SYNTAX);
380
381 return result;
382 }
383
384 /* EOF */