ReactOS 0.4.16-dev-2613-g9533ad7
whoami.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Whoami
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/cmdutils/whoami/whoami.c
5 * PURPOSE: Displays information about the current local user, groups and privileges.
6 * PROGRAMMERS: Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
7 */
8
9#define SECURITY_WIN32
10#include <security.h>
11#include <sddl.h>
12#include <strsafe.h>
13
14#include <conutils.h>
15
16#include "resource.h"
17
18#define wprintf(...) ConPrintf(StdOut, ##__VA_ARGS__)
19
23
24enum
25{
29 csv
31
32
34{
35 int i;
36
37 if (!arg)
38 return FALSE;
39
40 for (i = 1; i < argc; i++)
41 {
42 if (_wcsicmp(argv[i], arg) == 0)
43 return TRUE;
44 }
45
46 return FALSE;
47}
48
49/* blanking out the accepted modifiers will make filtering easier later on */
51{
52 argv[argc] = L"";
53}
54
55/* helper functions; let's keep it tidy to avoid redundancies */
56
57LPWSTR WhoamiGetUser(EXTENDED_NAME_FORMAT NameFormat)
58{
60 ULONG UsrSiz = MAX_PATH;
61
62 if (UsrBuf == NULL)
63 return NULL;
64
65 if (GetUserNameExW(NameFormat, UsrBuf, &UsrSiz))
66 {
68 return UsrBuf;
69 }
70
71 HeapFree(GetProcessHeap(), 0, UsrBuf);
72 return NULL;
73}
74
76{
77 return HeapFree(GetProcessHeap(), 0, Buffer);
78}
79
80
82{
83 HANDLE hToken = 0;
84 DWORD dwLength = 0;
85 VOID* pTokenInfo = 0;
86
88 {
91 NULL,
93 &dwLength);
94
96 {
98 if (pTokenInfo == NULL)
99 {
100 ConPuts(StdErr, L"ERROR: not enough memory to allocate the token structure.\n");
101 exit(1);
102 }
103 }
104
105 if (!GetTokenInformation(hToken, TokenType,
106 (LPVOID)pTokenInfo,
107 dwLength,
108 &dwLength))
109 {
110 ConPrintf(StdErr, L"ERROR 0x%x: could not get token information.\n", GetLastError());
111 WhoamiFree(pTokenInfo);
112 exit(1);
113 }
114
115 CloseHandle(hToken);
116 }
117
118 return pTokenInfo;
119}
120
122{
123#define RC_STRING_MAX_SIZE 850
124 static WCHAR TmpBuffer[RC_STRING_MAX_SIZE];
125
126 LoadStringW(NULL, ResId, TmpBuffer, _countof(TmpBuffer));
127 return TmpBuffer;
128}
129
131{
134
135 if (NoHeader || PrintFormat == csv)
136 return;
137
138 Length = (DWORD)LoadStringW(NULL, HeaderId, (LPWSTR)&Header, 0);
139 if (!Length || !Header)
140 return;
141
142 wprintf(L"\n%.*s\n", Length, Header);
143
144 while (Length--)
145 wprintf(L"-");
146
147 wprintf(L"\n\n");
148}
149
150typedef struct
151{
154 LPWSTR Content[1];
156
157/* Create and prepare a new table for printing */
159{
162 sizeof(WhoamiTable) + sizeof(LPWSTR) * Rows * Cols);
163 if (!pTable)
164 {
165 ConPuts(StdErr, L"ERROR: Not enough memory for displaying the table.\n");
166 exit(1);
167 }
168
169 pTable->Rows = Rows;
170 pTable->Cols = Cols;
171
172 return pTable;
173}
174
175/* Allocate and fill a new entry in the table */
177{
180 (wcslen(Entry) + 1) * sizeof(Entry[0]));
181 if (!Target)
182 {
183 ConPuts(StdErr, L"ERROR: Not enough memory for adding a table entry.\n");
184 exit(1);
185 }
186
188
189 pTable->Content[Row * pTable->Cols + Col] = Target;
190}
191
192/* Fill a new entry in the table */
194{
195 pTable->Content[Row * pTable->Cols + Col] = Entry;
196}
197
198/* Deallocate the table */
200{
201 UINT i, j;
202
203 for (i = 0; i < pTable->Rows; i++)
204 {
205 for (j = 0; j < pTable->Cols; j++)
206 {
207 if (!pTable->Content[i * pTable->Cols + j])
208 continue;
209 WhoamiFree(pTable->Content[i * pTable->Cols + j]);
210 }
211 }
212
214}
215
216/* Print the table */
218{
219 UINT i, j;
220 UINT CurRow, CurCol;
221 UINT SingleColLen = 0;
222 PUINT ColLength = &SingleColLen;
223
224 if (!pTable)
225 {
226 ConPuts(StdErr, L"ERROR: The table passed for display is empty.\n");
227 exit(1);
228 }
229
230 /*
231 * If we are going to print a *list* or *table*; take note of the total
232 * column size, as we will need it later on when printing them in a tabular
233 * fashion, similarly to their Windows counterparts.
234 */
235 if (PrintFormat == list)
236 {
237 for (j = 0; j < pTable->Cols; j++)
238 {
239 if (pTable->Content[j])
240 {
241 UINT ThisLength = (UINT)wcslen(pTable->Content[j]);
242 ColLength[0] = max(ThisLength, ColLength[0]);
243 }
244 }
245 }
246 else if (PrintFormat != csv) // So, == table
247 {
248 ColLength = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UINT) * pTable->Cols);
249
250 for (j = 0; j < pTable->Cols; j++)
251 {
252 for (i = 0; i < pTable->Rows; i++)
253 {
254 if (pTable->Content[i * pTable->Cols + j])
255 {
256 UINT ThisLength = (UINT)wcslen(pTable->Content[i * pTable->Cols + j]);
257 ColLength[j] = max(ThisLength, ColLength[j]);
258 }
259 }
260 }
261 }
262
263 switch (PrintFormat)
264 {
265 case csv:
266 {
267 for (i = 0; i < pTable->Rows; i++)
268 {
269 if (!pTable->Content[i * pTable->Cols])
270 continue;
271
272 /* If the user specified /nh then skip the column labels */
273 if (NoHeader && i == 0)
274 continue;
275
276 for (j = 0; j < pTable->Cols; j++)
277 {
278 if (pTable->Content[i * pTable->Cols + j])
279 {
280 wprintf(L"\"%s\"%s",
281 pTable->Content[i * pTable->Cols + j],
282 (j+1 < pTable->Cols ? L"," : L""));
283 }
284 }
285 wprintf(L"\n");
286 }
287 break;
288 }
289
290 case list:
291 {
292 UINT FinalRow = 0;
293
294 // FIXME: we need to do two passes to find out which entry is the last one shown, or not null this is not exactly optimal
295 for (CurRow = 1; CurRow < pTable->Rows; CurRow++)
296 {
297 /* If the first member of this row isn't available, skip it */
298 if (!pTable->Content[CurRow * pTable->Cols])
299 continue;
300
301 FinalRow = CurRow;
302 }
303
304 for (CurRow = 1; CurRow < pTable->Rows; CurRow++)
305 {
306 /* If the first member of this row isn't available, skip it */
307 if (!pTable->Content[CurRow * pTable->Cols])
308 continue;
309
310 /* If the user specified /nh then skip the column labels */
311 if (NoHeader && i == 0)
312 continue;
313
314 for (CurCol = 0; CurCol < pTable->Cols; CurCol++)
315 {
316#if 0 // Looks better with the ':' aligned, but it's not what Windows does.
317 /* ItemName<indent>: ItemValue */
318 wprintf(L"%-*s: %s\n",
319 ColLength[0] + 1,
320 pTable->Content[CurCol],
321 pTable->Content[CurRow * pTable->Cols + CurCol]);
322#else // The ':' immediately follows the ItemName.
323 /* ItemName:<indent> ItemValue */
324 UINT nIndent = ColLength[0] - (UINT)wcslen(pTable->Content[CurCol]);
325 wprintf(L"%s:%*s %s\n",
326 pTable->Content[CurCol],
327 nIndent, L"",
328 pTable->Content[CurRow * pTable->Cols + CurCol]);
329#endif
330 }
331
332 /* Don't add two carriage returns at the very end */
333 if (CurRow != FinalRow)
334 wprintf(L"\n");
335 }
336
337 break;
338 }
339
340 case table:
341 default:
342 {
343 for (i = 0; i < pTable->Rows; i++)
344 {
345 /* If the first member of this row isn't available, skip it */
346 if (!pTable->Content[i * pTable->Cols])
347 continue;
348
349 /* If the user specified /nh then skip the column labels too */
350 if (NoHeader && i == 0)
351 continue;
352
353 for (j = 0; j < pTable->Cols; j++)
354 {
355 if (pTable->Content[i * pTable->Cols + j])
356 {
357 wprintf(L"%-*s ", ColLength[j], pTable->Content[i * pTable->Cols + j]);
358 }
359 }
360 wprintf(L"\n");
361
362 /* Add the underline separators for the table headers */
363 if (i == 0)
364 {
365 for (j = 0; j < pTable->Cols; j++)
366 {
367 UINT Length = ColLength[j];
368
369 while (Length--)
370 wprintf(L"=");
371
372 /* A spacing between all the columns except for the last one */
373 if (pTable->Cols != (i + 1))
374 wprintf(L" ");
375 }
376
377 wprintf(L"\n");
378 }
379 }
380 }
381 }
382
383 /* fixme: when many tables are displayed in a single run we
384 have to sandwich carriage returns in between. */
385 // if (!final_entry)
386 wprintf(L"\n");
387
388 if (ColLength != &SingleColLen)
389 HeapFree(GetProcessHeap(), 0, ColLength);
390}
391
393{
395 DWORD dwIndex = 0;
396 LPWSTR pSidStr = 0;
397 PSID pSid = 0;
398
399 if (pGroupInfo == NULL)
400 return 0;
401
402 /* lets see if we can find the logon SID in that list, should be there */
403 for (dwIndex = 0; dwIndex < pGroupInfo->GroupCount; dwIndex++)
404 {
405 if ((pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
406 {
407 pSid = pGroupInfo->Groups[dwIndex].Sid;
408 }
409 }
410
411 if (pSid == 0)
412 {
413 WhoamiFree(pGroupInfo);
414 ConPuts(StdErr, L"ERROR: Couldn't find the logon SID.\n");
415 return 1;
416 }
417 if (!ConvertSidToStringSidW(pSid, &pSidStr))
418 {
419 WhoamiFree(pGroupInfo);
420 ConPuts(StdErr, L"ERROR: Couldn't convert the logon SID to a string.\n");
421 return 1;
422 }
423 else
424 {
425 /* let's show our converted logon SID */
426 wprintf(L"%s\n", pSidStr);
427 }
428
429 /* cleanup our allocations */
430 LocalFree(pSidStr);
431 WhoamiFree(pGroupInfo);
432
433 return 0;
434}
435
436int WhoamiUser(void)
437{
439 LPWSTR pUserStr = NULL;
440 LPWSTR pSidStr = NULL;
441 WhoamiTable *UserTable = NULL;
442
443 if (pUserInfo == NULL)
444 {
445 return 1;
446 }
447
448 pUserStr = WhoamiGetUser(NameSamCompatible);
449 if (pUserStr == NULL)
450 {
451 WhoamiFree(pUserInfo);
452 return 1;
453 }
454
455 UserTable = WhoamiAllocTable(2, 2);
456
458
459 /* set the column labels */
462
463 ConvertSidToStringSidW(pUserInfo->User.Sid, &pSidStr);
464
465 /* set the values for our single row of data */
466 WhoamiSetTable(UserTable, pUserStr, 1, 0);
467 WhoamiSetTable(UserTable, pSidStr, 1, 1);
468
469 WhoamiPrintTable(UserTable);
470
471 /* cleanup our allocations */
472 WhoamiFreeTable(UserTable);
473 LocalFree(pSidStr);
474 WhoamiFree(pUserInfo);
475 WhoamiFree(pUserStr);
476
477 return 0;
478}
479
481{
482 DWORD dwIndex = 0;
483 LPWSTR pSidStr = 0;
484
485 static WCHAR szGroupName[255] = {0};
486 static WCHAR szDomainName[255] = {0};
487 DWORD cchGroupName, cchDomainName;
488
489 SID_NAME_USE Use = 0;
490 BYTE SidNameUseStr[12] =
491 {
492 /* SidTypeUser */ -1,
493 /* SidTypeGroup */ -1,
494 /* SidTypeDomain */ -1,
495 /* SidTypeUser */ -1,
496 /* SidTypeAlias */ IDS_TP_ALIAS,
497 /* SidTypeWellKnownGroup */ IDS_TP_WELL_KNOWN_GROUP,
498 /* SidTypeDeletedAccount */ -1,
499 /* SidTypeInvalid */ -1,
500 /* SidTypeUnknown */ -1,
501 /* SidTypeComputer */ -1,
502 /* SidTypeLabel */ IDS_TP_LABEL
503 };
504
506 UINT PrintingRow;
507 WhoamiTable *GroupTable = NULL;
508
509 if (pGroupInfo == NULL)
510 {
511 return 1;
512 }
513
514 /* the header is the first (0) row, so we start in the second one (1) */
515 PrintingRow = 1;
516
517 GroupTable = WhoamiAllocTable(pGroupInfo->GroupCount + 1, 4);
518
520
525
526 for (dwIndex = 0; dwIndex < pGroupInfo->GroupCount; dwIndex++)
527 {
528 /* Reset the buffers so that we can reuse them */
529 *szGroupName = *szDomainName = UNICODE_NULL;
530 cchGroupName = _countof(szGroupName);
531 cchDomainName = _countof(szDomainName);
532
534 pGroupInfo->Groups[dwIndex].Sid,
535 (LPWSTR)&szGroupName,
536 &cchGroupName,
537 (LPWSTR)&szDomainName,
538 &cchDomainName,
539 &Use);
540
541 /* the original tool seems to limit the list to these kind of SID items */
542 if ((Use == SidTypeWellKnownGroup || Use == SidTypeAlias ||
543 Use == SidTypeLabel) && !(pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID))
544 {
545 WCHAR tmpBuffer[666];
546
547 /* looks like Windows treats 0x60 as 0x7 for some reason, let's just nod and call it a day:
548 0x60 is SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED
549 0x07 is SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED */
550
551 if (pGroupInfo->Groups[dwIndex].Attributes == 0x60)
552 pGroupInfo->Groups[dwIndex].Attributes = 0x07;
553
554 /* 1- format it as DOMAIN\GROUP if the domain exists, or just GROUP if not */
555 _snwprintf(tmpBuffer,
556 _countof(tmpBuffer),
557 L"%s%s%s",
558 szDomainName,
559 cchDomainName ? L"\\" : L"",
560 szGroupName);
561
562 WhoamiSetTable(GroupTable, tmpBuffer, PrintingRow, 0);
563
564 /* 2- let's find out the group type by using a simple lookup table for lack of a better method */
565 WhoamiSetTable(GroupTable, WhoamiLoadRcString(SidNameUseStr[Use]), PrintingRow, 1);
566
567 /* 3- turn that SID into text-form */
568 ConvertSidToStringSidW(pGroupInfo->Groups[dwIndex].Sid, &pSidStr);
569
570 WhoamiSetTable(GroupTable, pSidStr, PrintingRow, 2);
571
572 LocalFree(pSidStr);
573
574 /* 4- reuse that buffer for appending the attributes in text-form at the very end */
575 ZeroMemory(tmpBuffer, sizeof(tmpBuffer));
576
577 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_MANDATORY)
579 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
581 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_ENABLED)
583 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_OWNER)
585
586 /* remove the last comma (', ' which is 2 wchars) of the buffer, let's keep it simple */
587 tmpBuffer[max(wcslen(tmpBuffer) - 2, 0)] = UNICODE_NULL;
588
589 WhoamiSetTable(GroupTable, tmpBuffer, PrintingRow, 3);
590
591 PrintingRow++;
592 }
593 }
594
595 WhoamiPrintTable(GroupTable);
596
597 /* cleanup our allocations */
598 WhoamiFreeTable(GroupTable);
599 WhoamiFree(pGroupInfo);
600
601 return 0;
602}
603
604int WhoamiPriv(void)
605{
607 DWORD dwResult = 0, dwIndex = 0;
608 WhoamiTable *PrivTable = NULL;
609
610 if (pPrivInfo == NULL)
611 {
612 return 1;
613 }
614
615 PrivTable = WhoamiAllocTable(pPrivInfo->PrivilegeCount + 1, 3);
616
618
622
623 for (dwIndex = 0; dwIndex < pPrivInfo->PrivilegeCount; dwIndex++)
624 {
625 PWSTR PrivName = NULL, DispName = NULL;
626 DWORD PrivNameSize = 0, DispNameSize = 0;
627 BOOL ret = FALSE;
628
630 &pPrivInfo->Privileges[dwIndex].Luid,
631 NULL,
632 &PrivNameSize);
633
634 PrivName = HeapAlloc(GetProcessHeap(), 0, ++PrivNameSize * sizeof(WCHAR));
635
637 &pPrivInfo->Privileges[dwIndex].Luid,
638 PrivName,
639 &PrivNameSize);
640
641 WhoamiSetTableDyn(PrivTable, PrivName, dwIndex + 1, 0);
642
643
644 /* try to grab the size of the string, also, beware, as this call is
645 unimplemented in ReactOS/Wine at the moment */
646
647 LookupPrivilegeDisplayNameW(NULL, PrivName, NULL, &DispNameSize, &dwResult);
648
649 DispName = HeapAlloc(GetProcessHeap(), 0, ++DispNameSize * sizeof(WCHAR));
650
651 ret = LookupPrivilegeDisplayNameW(NULL, PrivName, DispName, &DispNameSize, &dwResult);
652
653 if (ret && DispName)
654 {
655 // wprintf(L"DispName: %d %x '%s'\n", DispNameSize, GetLastError(), DispName);
656 WhoamiSetTableDyn(PrivTable, DispName, dwIndex + 1, 1);
657 }
658 else
659 {
660 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_UNKNOWN_DESCRIPTION), dwIndex + 1, 1);
661
662 if (DispName != NULL)
663 WhoamiFree(DispName);
664 }
665
666 if (pPrivInfo->Privileges[dwIndex].Attributes & SE_PRIVILEGE_ENABLED)
667 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_STATE_ENABLED), dwIndex + 1, 2);
668 else
669 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_STATE_DISABLED), dwIndex + 1, 2);
670 }
671
672 WhoamiPrintTable(PrivTable);
673
674 /* cleanup our allocations */
675 WhoamiFreeTable(PrivTable);
676 WhoamiFree(pPrivInfo);
677
678 return 0;
679}
680
681int wmain(int argc, WCHAR* argv[])
682{
683#define WAM_USER (1 << 0)
684#define WAM_GROUPS (1 << 1)
685#define WAM_PRIV (1 << 2)
686
687 INT i;
688 BYTE WamBit = 0;
689
690 /* Initialize the Console Standard Streams */
692
693 /* * * * * * * * * * * * * * * *
694 * A: no parameters whatsoever */
695
696 if (argc == 1)
697 {
698 /* if there's no arguments just choose the simple path and display the user's identity in lowercase */
699 LPWSTR UserBuffer = WhoamiGetUser(NameSamCompatible);
700 if (UserBuffer)
701 {
702 wprintf(L"%s\n", UserBuffer);
703 WhoamiFree(UserBuffer);
704 return 0;
705 }
706 else
707 {
708 return 1;
709 }
710 }
711
712 /* first things first-- let's detect and manage both printing modifiers (/fo and /nh) */
713 for (i = 1; i < argc; i++)
714 {
715 if (_wcsicmp(argv[i], L"/nh") == 0)
716 {
718
719 if (NoHeader == FALSE)
720 {
721 NoHeader = TRUE;
723 }
724 }
725 }
726
727 for (i = 1; i < argc; i++)
728 {
729 if (_wcsicmp(argv[i], L"/fo") == 0)
730 {
731 if ((i + 1) < argc)
732 {
734
735 if (_wcsicmp(argv[i + 1], L"table") == 0 && PrintFormat != table)
736 {
739 BlankArgument(i + 1, argv);
740 }
741 else if (_wcsicmp(argv[i + 1], L"list") == 0 && PrintFormat != list)
742 {
745 BlankArgument(i + 1, argv);
746
747 /* looks like you can't use the "/fo list /nh" options together
748 for some stupid reason */
749 if (PrintFormat == list && NoHeader != FALSE)
750 {
752 return 1;
753 }
754 }
755 else if (_wcsicmp(argv[i + 1], L"csv") == 0 && PrintFormat != csv)
756 {
759 BlankArgument(i + 1, argv);
760 }
761 /* /nh or /fo after /fo isn't parsed as a value */
762 else if (_wcsicmp(argv[i + 1], L"/nh") == 0 || _wcsicmp(argv[i + 1], L"/fo") == 0
763 /* same goes for the other named options, not ideal, but works */
764 || _wcsicmp(argv[i + 1], L"/priv") == 0
765 || _wcsicmp(argv[i + 1], L"/groups") == 0
766 || _wcsicmp(argv[i + 1], L"/user") == 0
767 || _wcsicmp(argv[i + 1], L"/all") == 0
768 || _wcsicmp(argv[i + 1], L"") == 0)
769 {
770 goto FoValueExpected;
771 }
772 else
773 {
775 return 1;
776 }
777 }
778 else
779 {
780 FoValueExpected:
782 return 1;
783 }
784 }
785 }
786
787 if (NoHeaderArgCount >= 2)
788 {
790 return 1;
791 }
792 /* special case when there's just a /nh as argument; it outputs nothing */
793 else if (NoHeaderArgCount == 1 && argc == 2)
794 {
795 return 0;
796 }
797
798 if (PrintFormatArgCount >= 2)
799 {
801 return 1;
802 }
803 /* if there's just /fo <format>... call it invalid */
804 else if (PrintFormatArgCount == 1 && argc == 3)
805 {
806 goto InvalidSyntax;
807 }
808
809 /* * * * * * * * * * * * * *
810 * B: one single parameter */
811
812 if (argc == 2)
813 {
814 /* now let's try to parse the triumvirate of simpler, single (1) arguments... plus help */
815 if (_wcsicmp(argv[1], L"/?") == 0)
816 {
818 return 0;
819 }
820 else if (_wcsicmp(argv[1], L"/upn") == 0)
821 {
822 LPWSTR UserBuffer = WhoamiGetUser(NameUserPrincipal);
823
824 if (UserBuffer)
825 {
826 wprintf(L"%s\n", UserBuffer);
827 WhoamiFree(UserBuffer);
828 return 0;
829 }
830 else
831 {
833 return 1;
834 }
835 }
836 else if (_wcsicmp(argv[1], L"/fqdn") == 0)
837 {
838 LPWSTR UserBuffer = WhoamiGetUser(NameFullyQualifiedDN);
839
840 if (UserBuffer)
841 {
842 wprintf(L"%s\n", UserBuffer);
843 WhoamiFree(UserBuffer);
844 return 0;
845 }
846 else
847 {
849 return 1;
850 }
851 }
852 else if (_wcsicmp(argv[1], L"/logonid") == 0)
853 {
854 return WhoamiLogonId();
855 }
856 }
857
858 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
859 * C: One main parameter with extra tasty modifiers to play with */
860
861 /* sometimes is just easier to whitelist for lack of a better method */
862 for (i = 1; i < argc; i++)
863 {
864 if ((_wcsicmp(argv[i], L"/user") != 0) &&
865 (_wcsicmp(argv[i], L"/groups") != 0) &&
866 (_wcsicmp(argv[i], L"/priv") != 0) &&
867 (_wcsicmp(argv[i], L"/all") != 0) &&
868 (_wcsicmp(argv[i], L"") != 0))
869 {
871 return 1;
872 }
873 }
874
875 if (GetArgument(L"/user", argc, argv))
876 {
877 WamBit |= WAM_USER;
878 }
879 if (GetArgument(L"/groups", argc, argv))
880 {
881 WamBit |= WAM_GROUPS;
882 }
883 if (GetArgument(L"/priv", argc, argv))
884 {
885 WamBit |= WAM_PRIV;
886 }
887 if (GetArgument(L"/all", argc, argv))
888 {
889 /* one can't have it /all and any of the other options at the same time */
890 if ((WamBit & (WAM_USER | WAM_GROUPS | WAM_PRIV)) == 0)
891 {
892 WamBit |= (WAM_USER | WAM_GROUPS | WAM_PRIV);
893 }
894 else
895 {
896 goto InvalidSyntax;
897 }
898 }
899
900 if (WamBit & WAM_USER)
901 {
902 WhoamiUser();
903 }
904 if (WamBit & WAM_GROUPS)
905 {
906 WhoamiGroups();
907 }
908 if (WamBit & WAM_PRIV)
909 {
910 WhoamiPriv();
911 }
912
913 return 0;
914
917 return 1;
918}
#define IDS_HELP
Definition: resource.h:3
#define IDS_ATTR_GROUP_ENABLED
Definition: resource.h:22
#define IDS_COL_ATTRIB
Definition: resource.h:11
#define IDS_TP_WELL_KNOWN_GROUP
Definition: resource.h:16
#define IDS_ERROR_1TIMES
Definition: resource.h:34
#define IDS_ERROR_NH_LIST
Definition: resource.h:37
#define IDS_ATTR_GROUP_OWNER
Definition: resource.h:23
#define IDS_TP_LABEL
Definition: resource.h:18
#define IDS_ERROR_FQDN
Definition: resource.h:31
#define IDS_ATTR_GROUP_ENABLED_BY_DEFAULT
Definition: resource.h:21
#define IDS_USER_HEADER
Definition: resource.h:3
#define IDS_STATE_ENABLED
Definition: resource.h:27
#define IDS_GROU_HEADER
Definition: resource.h:4
#define IDS_COL_USER_NAME
Definition: resource.h:7
#define IDS_ATTR_GROUP_MANDATORY
Definition: resource.h:20
#define IDS_COL_PRIV_NAME
Definition: resource.h:12
#define IDS_TP_ALIAS
Definition: resource.h:17
#define IDS_STATE_DISABLED
Definition: resource.h:28
#define IDS_ERROR_UPN
Definition: resource.h:30
#define IDS_COL_SID
Definition: resource.h:10
#define IDS_ERROR_INVALIDARG
Definition: resource.h:36
#define IDS_ERROR_VALUEXPECTED
Definition: resource.h:32
#define IDS_COL_GROUP_NAME
Definition: resource.h:8
#define IDS_COL_STATE
Definition: resource.h:14
#define IDS_ERROR_INVALIDSYNTAX
Definition: resource.h:35
#define IDS_ERROR_VALUENOTALLOWED
Definition: resource.h:33
#define IDS_UNKNOWN_DESCRIPTION
Definition: resource.h:25
#define IDS_PRIV_HEADER
Definition: resource.h:5
#define IDS_COL_TYPE
Definition: resource.h:9
#define IDS_COL_DESCRIPTION
Definition: resource.h:13
Definition: bufpool.h:45
Definition: Header.h:9
Definition: list.h:37
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: conutils_noros.h:8
#define ConInitStdStreams()
Definition: conutils_noros.h:5
void ConPrintf(FILE *fp, LPCWSTR psz,...)
#define StdOut
Definition: conutils_noros.h:6
void ConResPrintf(FILE *fp, UINT nID,...)
#define StdErr
Definition: conutils_noros.h:7
void ConResPuts(FILE *fp, UINT nID)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName, LPDWORD cchDisplayName, LPDWORD lpLanguageId)
Definition: misc.c:901
BOOL WINAPI LookupPrivilegeNameW(LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName, LPDWORD cchName)
Definition: misc.c:832
BOOL WINAPI LookupAccountSidW(LPCWSTR pSystemName, PSID pSid, LPWSTR pAccountName, LPDWORD pdwAccountName, LPWSTR pDomainName, LPDWORD pdwDomainName, PSID_NAME_USE peUse)
Definition: misc.c:537
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static DWORD DWORD * dwLength
Definition: fusion.c:86
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3808
MonoAssembly int argc
Definition: metahost.c:107
_ACRTIMP int __cdecl _snwprintf(wchar_t *, size_t, const wchar_t *,...)
Definition: wcs.c:1493
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
@ InvalidSyntax
Definition: eventcreate.c:713
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
enum _SID_NAME_USE SID_NAME_USE
@ SidTypeAlias
Definition: lsa.idl:121
@ SidTypeWellKnownGroup
Definition: lsa.idl:122
@ SidTypeLabel
Definition: lsa.idl:127
#define ZeroMemory
Definition: minwinbase.h:31
static PSID pSid
Definition: security.c:115
#define argv
Definition: mplay32.c:18
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:411
#define SE_GROUP_OWNER
Definition: setypes.h:93
#define SE_GROUP_LOGON_ID
Definition: setypes.h:98
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
#define SE_GROUP_ENABLED
Definition: setypes.h:92
#define DWORD
Definition: nt_native.h:44
#define LOCALE_USER_DEFAULT
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
short WCHAR
Definition: pedump.c:58
int wmain()
wcscpy
#define exit(n)
Definition: config.h:202
#define LoadStringW
Definition: utils.h:64
Entry
Definition: section.c:5210
#define _countof(array)
Definition: sndvol32.h:70
BOOLEAN WINAPI GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
Definition: sspi.c:1079
#define StringCchCat
Definition: strsafe.h:317
UINT Rows
Definition: whoami.c:152
UINT Cols
Definition: whoami.c:153
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1030
$ULONG GroupCount
Definition: setypes.h:1026
$ULONG PrivilegeCount
Definition: setypes.h:1035
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1036
SID_AND_ATTRIBUTES User
Definition: setypes.h:1022
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
@ list
Definition: whoami.c:28
@ csv
Definition: whoami.c:29
@ table
Definition: whoami.c:27
@ undefined
Definition: whoami.c:26
int WhoamiUser(void)
Definition: whoami.c:436
#define RC_STRING_MAX_SIZE
int WhoamiLogonId(void)
Definition: whoami.c:392
#define wprintf(...)
Definition: whoami.c:18
void WhoamiPrintTable(WhoamiTable *pTable)
Definition: whoami.c:217
VOID * WhoamiGetTokenInfo(TOKEN_INFORMATION_CLASS TokenType)
Definition: whoami.c:81
UINT PrintFormatArgCount
Definition: whoami.c:22
void WhoamiFreeTable(WhoamiTable *pTable)
Definition: whoami.c:199
BOOL GetArgument(WCHAR *arg, int argc, WCHAR *argv[])
Definition: whoami.c:33
int WhoamiPriv(void)
Definition: whoami.c:604
int WhoamiGroups(void)
Definition: whoami.c:480
UINT NoHeaderArgCount
Definition: whoami.c:21
BOOL WhoamiFree(VOID *Buffer)
Definition: whoami.c:75
void WhoamiSetTable(WhoamiTable *pTable, WCHAR *Entry, UINT Row, UINT Col)
Definition: whoami.c:176
LPWSTR WhoamiLoadRcString(UINT ResId)
Definition: whoami.c:121
WhoamiTable * WhoamiAllocTable(UINT Rows, UINT Cols)
Definition: whoami.c:158
void WhoamiSetTableDyn(WhoamiTable *pTable, WCHAR *Entry, UINT Row, UINT Col)
Definition: whoami.c:193
void BlankArgument(int argc, WCHAR *argv[])
Definition: whoami.c:50
#define WAM_PRIV
LPWSTR WhoamiGetUser(EXTENDED_NAME_FORMAT NameFormat)
Definition: whoami.c:57
#define WAM_GROUPS
enum @7 PrintFormat
void WhoamiPrintHeader(UINT HeaderId)
Definition: whoami.c:130
#define WAM_USER
BOOL NoHeader
Definition: whoami.c:20
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LCMAP_LOWERCASE
Definition: winnls.h:197
_In_ ULONG Rows
Definition: haltypes.h:17
struct _TOKEN_GROUPS * PTOKEN_GROUPS
struct _TOKEN_USER * PTOKEN_USER
@ TokenGroups
Definition: setypes.h:979
@ TokenPrivileges
Definition: setypes.h:980
@ TokenUser
Definition: setypes.h:978
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
enum _TOKEN_INFORMATION_CLASS TOKEN_INFORMATION_CLASS
#define TOKEN_READ
Definition: setypes.h:963
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
unsigned char BYTE
Definition: xxhash.c:193