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