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