ReactOS 0.4.15-dev-7788-g1ad9096
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 {
67 CharLowerW(UsrBuf);
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 wprintf(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 wprintf(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
127
128 return TmpBuffer;
129}
130
131void WhoamiPrintHeader(int HeaderId)
132{
133 PWSTR Header = WhoamiLoadRcString(HeaderId);
135
136 if (NoHeader || PrintFormat == csv)
137 return;
138
139 wprintf(L"\n%s\n", Header);
140
141 while (Length--)
142 wprintf(L"-");
143
144 wprintf(L"\n\n");
145}
146
147typedef struct
148{
151 LPWSTR Content[1];
153
154/* create and prepare a new table for printing */
156{
159 sizeof(WhoamiTable) + sizeof(LPWSTR) * Rows * Cols);
160
161 // wprintf(L"DEBUG: Allocating %dx%d elem table for printing.\n\n", Rows, Cols);
162
163 if (!pTable)
164 {
165 wprintf(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 1 + wcslen(Entry) * sizeof(Entry[0]));
181
182 // wprintf(L"DEBUG: Setting table value '%lp' '%ls' for %lu %lu.\n", entry, entry, row, col);
183
184 if (!Target)
185 exit(1);
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/* print and deallocate the table */
200{
201 UINT i, j;
202 UINT CurRow, CurCol;
203 UINT *ColLength;
204
205
206 if (!pTable)
207 {
208 wprintf(L"ERROR: The table passed for display is empty.\n");
209 exit(1);
210 }
211
212 /* if we are going to print a *list* or *table*; take note of the total
213 column size, as we will need it later on when printing them in a tabular
214 fashion, according to their windows counterparts */
215
216 if (PrintFormat != csv)
217 {
218 ColLength = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UINT) * pTable->Cols);
219
220 if (PrintFormat == list)
221 {
222 for (j = 0; j < pTable->Cols; j++)
223 if (pTable->Content[j])
224 {
225 UINT ThisLength = wcslen(pTable->Content[j]);
226
227 /* now that we're here, seize the opportunity and add those pesky ":" */
228 pTable->Content[j][ThisLength++] = L':';
229 pTable->Content[j][ThisLength] = UNICODE_NULL;
230
231 ColLength[0] = max(ThisLength, ColLength[0]);
232 }
233 }
234 else
235 {
236 for (j = 0; j < pTable->Cols; j++)
237 for (i = 0; i < pTable->Rows; i++)
238 if (pTable->Content[i * pTable->Cols + j])
239 {
240 UINT ThisLength = wcslen(pTable->Content[i * pTable->Cols + j]);
241 ColLength[j] = max(ThisLength, ColLength[j]);
242 }
243 }
244 }
245
246 switch (PrintFormat)
247 {
248 case csv:
249 {
250 for (i = 0; i < pTable->Rows; i++)
251 {
252 if (!pTable->Content[i * pTable->Cols])
253 continue;
254
255 /* if the user especified /nh then skip the column labels */
256 if (NoHeader && i == 0)
257 continue;
258
259 for (j = 0; j < pTable->Cols; j++)
260 {
261 if (pTable->Content[i * pTable->Cols + j])
262 {
263 wprintf(L"\"%s\"%s",
264 pTable->Content[i * pTable->Cols + j],
265 (j+1 < pTable->Cols ? L"," : L""));
266 }
267 }
268 wprintf(L"\n");
269 }
270
271 break;
272
273 }
274
275 case list:
276 {
277 UINT FinalRow = 0;
278
279 /* 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 */
280 for (CurRow = 1; CurRow < pTable->Rows; CurRow++)
281 {
282 /* if the first member of this row isn't available, then forget it */
283 if (!pTable->Content[CurRow * pTable->Cols])
284 continue;
285
286 FinalRow = CurRow;
287 }
288
289 for (CurRow = 1; CurRow < pTable->Rows; CurRow++)
290 {
291 /* if the first member of this row isn't available, then forget it */
292 if (!pTable->Content[CurRow * pTable->Cols])
293 continue;
294
295 /* if the user especified /nh then skip the column labels */
296 if (NoHeader && i == 0)
297 continue;
298
299 for (CurCol = 0; CurCol < pTable->Cols; CurCol++)
300 {
301 wprintf(L"%-*s %s\n",
302 ColLength[0],
303 pTable->Content[CurCol],
304 pTable->Content[CurRow * pTable->Cols + CurCol]);
305 }
306
307 /* don't add two carriage returns at the very end */
308 if (CurRow != FinalRow)
309 wprintf(L"\n");
310 }
311
312 break;
313 }
314
315
316 case table:
317 default:
318 {
319 for (i = 0; i < pTable->Rows; i++)
320 {
321 /* if the first member of this row isn't available, then forget it */
322 if (!pTable->Content[i * pTable->Cols])
323 continue;
324
325 /* if the user especified /nh then skip the column labels too */
326 if (NoHeader && i == 0)
327 continue;
328
329 for (j = 0; j < pTable->Cols; j++)
330 {
331 if (pTable->Content[i * pTable->Cols + j])
332 {
333 wprintf(L"%-*s ", ColLength[j], pTable->Content[i * pTable->Cols + j]);
334 }
335 }
336 wprintf(L"\n");
337
338 /* add the cute underline thingie for the table header */
339 if (i == 0)
340 {
341 for (j = 0; j < pTable->Cols; j++)
342 {
343 DWORD Length = ColLength[j];
344
345 while (Length--)
346 wprintf(L"=");
347
348 /* a spacing between all the columns except for the last one */
349 if (pTable->Cols != (i + 1))
350 wprintf(L" ");
351 }
352
353 wprintf(L"\n");
354 }
355 }
356
357 }
358 }
359
360 /* fixme: when many tables are displayed in a single run we
361 have to sandwich carriage returns in between. */
362 // if (!final_entry)
363 wprintf(L"\n");
364
365 for (i = 0; i < pTable->Rows; i++)
366 for (j = 0; j < pTable->Cols; j++)
367 WhoamiFree(pTable->Content[i * pTable->Cols + j]);
368
370
371 if (PrintFormat != csv)
372 HeapFree(GetProcessHeap(), 0, ColLength);
373}
374
376{
378 DWORD dwIndex = 0;
379 LPWSTR pSidStr = 0;
380 PSID pSid = 0;
381
382 if (pGroupInfo == NULL)
383 return 0;
384
385 /* lets see if we can find the logon SID in that list, should be there */
386 for (dwIndex = 0; dwIndex < pGroupInfo->GroupCount; dwIndex++)
387 {
388 if ((pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
389 {
390 pSid = pGroupInfo->Groups[dwIndex].Sid;
391 }
392 }
393
394 if (pSid == 0)
395 {
396 WhoamiFree(pGroupInfo);
397 wprintf(L"ERROR: Couldn't find the logon SID.\n");
398 return 1;
399 }
400 if (!ConvertSidToStringSidW(pSid, &pSidStr))
401 {
402 WhoamiFree(pGroupInfo);
403 wprintf(L"ERROR: Couldn't convert the logon SID to a string.\n");
404 return 1;
405 }
406 else
407 {
408 /* let's show our converted logon SID */
409 wprintf(L"%s\n", pSidStr);
410 }
411
412 /* cleanup our allocations */
413 LocalFree(pSidStr);
414 WhoamiFree(pGroupInfo);
415
416 return 0;
417}
418
419int WhoamiUser(void)
420{
422 LPWSTR pUserStr = NULL;
423 LPWSTR pSidStr = NULL;
424 WhoamiTable *UserTable = NULL;
425
426 if (pUserInfo == NULL)
427 {
428 return 1;
429 }
430
431 pUserStr = WhoamiGetUser(NameSamCompatible);
432 if (pUserStr == NULL)
433 {
434 WhoamiFree(pUserInfo);
435 return 1;
436 }
437
438 UserTable = WhoamiAllocTable(2, 2);
439
441
442 /* set the column labels */
445
446 ConvertSidToStringSidW(pUserInfo->User.Sid, &pSidStr);
447
448 /* set the values for our single row of data */
449 WhoamiSetTable(UserTable, pUserStr, 1, 0);
450 WhoamiSetTable(UserTable, pSidStr, 1, 1);
451
452 WhoamiPrintTable(UserTable);
453
454 /* cleanup our allocations */
455 LocalFree(pSidStr);
456 WhoamiFree(pUserInfo);
457 WhoamiFree(pUserStr);
458
459 return 0;
460}
461
463{
464 DWORD dwIndex = 0;
465 LPWSTR pSidStr = 0;
466
467 static WCHAR szGroupName[255] = {0};
468 static WCHAR szDomainName[255] = {0};
469
470 DWORD cchGroupName = _countof(szGroupName);
471 DWORD cchDomainName = _countof(szGroupName);
472
473 SID_NAME_USE Use = 0;
474 BYTE SidNameUseStr[12] =
475 {
476 /* SidTypeUser */ -1,
477 /* SidTypeGroup */ -1,
478 /* SidTypeDomain */ -1,
479 /* SidTypeUser */ -1,
480 /* SidTypeAlias */ IDS_TP_ALIAS,
481 /* SidTypeWellKnownGroup */ IDS_TP_WELL_KNOWN_GROUP,
482 /* SidTypeDeletedAccount */ -1,
483 /* SidTypeInvalid */ -1,
484 /* SidTypeUnknown */ -1,
485 /* SidTypeComputer */ -1,
486 /* SidTypeLabel */ IDS_TP_LABEL
487 };
488
490 UINT PrintingRow;
491 WhoamiTable *GroupTable = NULL;
492
493 if (pGroupInfo == NULL)
494 {
495 return 1;
496 }
497
498 /* the header is the first (0) row, so we start in the second one (1) */
499 PrintingRow = 1;
500
501 GroupTable = WhoamiAllocTable(pGroupInfo->GroupCount + 1, 4);
502
504
509
510 for (dwIndex = 0; dwIndex < pGroupInfo->GroupCount; dwIndex++)
511 {
513 pGroupInfo->Groups[dwIndex].Sid,
514 (LPWSTR)&szGroupName,
515 &cchGroupName,
516 (LPWSTR)&szDomainName,
517 &cchDomainName,
518 &Use);
519
520 /* the original tool seems to limit the list to these kind of SID items */
521 if ((Use == SidTypeWellKnownGroup || Use == SidTypeAlias ||
522 Use == SidTypeLabel) && !(pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID))
523 {
524 wchar_t tmpBuffer[666];
525
526 /* looks like windows treats 0x60 as 0x7 for some reason, let's just nod and call it a day:
527 0x60 is SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED
528 0x07 is SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED */
529
530 if (pGroupInfo->Groups[dwIndex].Attributes == 0x60)
531 pGroupInfo->Groups[dwIndex].Attributes = 0x07;
532
533 /* 1- format it as DOMAIN\GROUP if the domain exists, or just GROUP if not */
534 _snwprintf((LPWSTR)&tmpBuffer,
535 _countof(tmpBuffer),
536 L"%s%s%s",
537 szDomainName,
538 cchDomainName ? L"\\" : L"",
539 szGroupName);
540
541 WhoamiSetTable(GroupTable, tmpBuffer, PrintingRow, 0);
542
543 /* 2- let's find out the group type by using a simple lookup table for lack of a better method */
544 WhoamiSetTable(GroupTable, WhoamiLoadRcString(SidNameUseStr[Use]), PrintingRow, 1);
545
546 /* 3- turn that SID into text-form */
547 ConvertSidToStringSidW(pGroupInfo->Groups[dwIndex].Sid, &pSidStr);
548
549 WhoamiSetTable(GroupTable, pSidStr, PrintingRow, 2);
550
551 LocalFree(pSidStr);
552
553 /* 4- reuse that buffer for appending the attributes in text-form at the very end */
554 ZeroMemory(tmpBuffer, sizeof(tmpBuffer));
555
556 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_MANDATORY)
558 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
560 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_ENABLED)
562 if (pGroupInfo->Groups[dwIndex].Attributes & SE_GROUP_OWNER)
564
565 /* remove the last comma (', ' which is 2 wchars) of the buffer, let's keep it simple */
566 tmpBuffer[max(wcslen(tmpBuffer) - 2, 0)] = UNICODE_NULL;
567
568 WhoamiSetTable(GroupTable, tmpBuffer, PrintingRow, 3);
569
570 PrintingRow++;
571 }
572
573 /* reset the buffers so that we can reuse them */
574 ZeroMemory(szGroupName, sizeof(szGroupName));
575 ZeroMemory(szDomainName, sizeof(szDomainName));
576
577 cchGroupName = 255;
578 cchDomainName = 255;
579 }
580
581 WhoamiPrintTable(GroupTable);
582
583 /* cleanup our allocations */
584 WhoamiFree((LPVOID)pGroupInfo);
585
586 return 0;
587}
588
589int WhoamiPriv(void)
590{
592 DWORD dwResult = 0, dwIndex = 0;
593 WhoamiTable *PrivTable = NULL;
594
595 if (pPrivInfo == NULL)
596 {
597 return 1;
598 }
599
600 PrivTable = WhoamiAllocTable(pPrivInfo->PrivilegeCount + 1, 3);
601
603
607
608 for (dwIndex = 0; dwIndex < pPrivInfo->PrivilegeCount; dwIndex++)
609 {
610 PWSTR PrivName = NULL, DispName = NULL;
611 DWORD PrivNameSize = 0, DispNameSize = 0;
612 BOOL ret = FALSE;
613
615 &pPrivInfo->Privileges[dwIndex].Luid,
616 NULL,
617 &PrivNameSize);
618
619 PrivName = HeapAlloc(GetProcessHeap(), 0, ++PrivNameSize*sizeof(WCHAR));
620
622 &pPrivInfo->Privileges[dwIndex].Luid,
623 PrivName,
624 &PrivNameSize);
625
626 WhoamiSetTableDyn(PrivTable, PrivName, dwIndex + 1, 0);
627
628
629 /* try to grab the size of the string, also, beware, as this call is
630 unimplemented in ReactOS/Wine at the moment */
631
632 LookupPrivilegeDisplayNameW(NULL, PrivName, NULL, &DispNameSize, &dwResult);
633
634 DispName = HeapAlloc(GetProcessHeap(), 0, ++DispNameSize * sizeof(WCHAR));
635
636 ret = LookupPrivilegeDisplayNameW(NULL, PrivName, DispName, &DispNameSize, &dwResult);
637
638 if (ret && DispName)
639 {
640 // wprintf(L"DispName: %d %x '%s'\n", DispNameSize, GetLastError(), DispName);
641 WhoamiSetTableDyn(PrivTable, DispName, dwIndex + 1, 1);
642 }
643 else
644 {
645 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_UNKNOWN_DESCRIPTION), dwIndex + 1, 1);
646
647 if (DispName != NULL)
648 WhoamiFree(DispName);
649 }
650
651 if (pPrivInfo->Privileges[dwIndex].Attributes & SE_PRIVILEGE_ENABLED)
652 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_STATE_ENABLED), dwIndex + 1, 2);
653 else
654 WhoamiSetTable(PrivTable, WhoamiLoadRcString(IDS_STATE_DISABLED), dwIndex + 1, 2);
655 }
656
657 WhoamiPrintTable(PrivTable);
658
659 /* cleanup our allocations */
660 WhoamiFree(pPrivInfo);
661
662 return 0;
663}
664
665int wmain(int argc, WCHAR* argv[])
666{
667 #define WAM_USER 1<<0
668 #define WAM_GROUPS 1<<1
669 #define WAM_PRIV 1<<2
670
671 INT i;
672 BYTE WamBit = 0;
673
674 /* Initialize the Console Standard Streams */
676
677
678 /* * * * * * * * * * * * * * * *
679 * A: no parameters whatsoever */
680
681 if (argc == 1)
682 {
683 /* if there's no arguments just choose the simple path and display the user's identity in lowercase */
684 LPWSTR UserBuffer = WhoamiGetUser(NameSamCompatible);
685
686 if (UserBuffer)
687 {
688 wprintf(L"%s\n", UserBuffer);
689 WhoamiFree(UserBuffer);
690 return 0;
691 }
692 else
693 {
694 return 1;
695 }
696 }
697
698 /* first things first-- let's detect and manage both printing modifiers (/fo and /nh) */
699 for (i = 1; i < argc; i++)
700 {
701 if (wcsicmp(argv[i], L"/nh") == 0)
702 {
704
705 if (NoHeader == FALSE)
706 {
707 NoHeader = TRUE;
708 // wprintf(L"Headers disabled!\n");
710 }
711 }
712 }
713
714 for (i = 1; i < argc; i++)
715 {
716 if (wcsicmp(argv[i], L"/fo") == 0)
717 {
718 if ((i + 1) < argc)
719 {
720 // wprintf(L"exists another param after /fo\n");
721
723
724 if (wcsicmp(argv[i + 1], L"table") == 0 && PrintFormat != table)
725 {
727 // wprintf(L"Changed to table format\n");
729 BlankArgument(i + 1, argv);
730 }
731 else if (wcsicmp(argv[i + 1], L"list") == 0 && PrintFormat != list)
732 {
734 // wprintf(L"Changed to list format\n");
736 BlankArgument(i + 1, argv);
737
738 /* looks like you can't use the "/fo list /nh" options together
739 for some stupid reason */
740 if (PrintFormat == list && NoHeader != FALSE)
741 {
743 return 1;
744 }
745 }
746 else if (wcsicmp(argv[i + 1], L"csv") == 0 && PrintFormat != csv)
747 {
749 // wprintf(L"Changed to csv format\n");
751 BlankArgument(i + 1, argv);
752 }
753 /* /nh or /fo after /fo isn't parsed as a value */
754 else if (wcsicmp(argv[i + 1], L"/nh") == 0 || wcsicmp(argv[i + 1], L"/fo") == 0
755
756 /* same goes for the other named options, not ideal, but works */
757 || wcsicmp(argv[i + 1], L"/priv") == 0
758 || wcsicmp(argv[i + 1], L"/groups") == 0
759 || wcsicmp(argv[i + 1], L"/user") == 0
760 || wcsicmp(argv[i + 1], L"/all") == 0
761 || wcsicmp(argv[i + 1], L"") == 0)
762 {
763 goto FoValueExpected;
764 }
765 else
766 {
768 return 1;
769 }
770 }
771 else
772 {
773 FoValueExpected:
774
776 return 1;
777 }
778 }
779 }
780
781 if (NoHeaderArgCount >= 2)
782 {
784 return 1;
785 }
786 /* special case when there's just a /nh as argument; it outputs nothing */
787 else if (NoHeaderArgCount == 1 && argc == 2)
788 {
789 return 0;
790 }
791
792 if (PrintFormatArgCount >= 2)
793 {
795 return 1;
796 }
797 /* if there's just /fo <format>... call it invalid */
798 else if (PrintFormatArgCount == 1 && argc == 3)
799 {
800 goto InvalidSyntax;
801 }
802
803 /* * * * * * * * * * * * * *
804 * B: one single parameter */
805
806 if (argc == 2)
807 {
808 /* now let's try to parse the triumvirate of simpler, single (1) arguments... plus help */
809 if (wcsicmp(argv[1], L"/?") == 0)
810 {
812 return 0;
813 }
814
815 else if (wcsicmp(argv[1], L"/upn") == 0)
816 {
817 LPWSTR UserBuffer = WhoamiGetUser(NameUserPrincipal);
818
819 if (UserBuffer)
820 {
821 wprintf(L"%s\n", UserBuffer);
822 WhoamiFree(UserBuffer);
823 return 0;
824 }
825 else
826 {
828 return 1;
829 }
830 }
831
832 else if (wcsicmp(argv[1], L"/fqdn") == 0)
833 {
834 LPWSTR UserBuffer = WhoamiGetUser(NameFullyQualifiedDN);
835
836 if (UserBuffer)
837 {
838 wprintf(L"%s\n", UserBuffer);
839 WhoamiFree(UserBuffer);
840 return 0;
841 }
842 else
843 {
845 return 1;
846 }
847 }
848
849 else if (wcsicmp(argv[1], L"/logonid") == 0)
850 {
851 return WhoamiLogonId();
852 }
853 }
854
855 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
856 * C: One main parameter with extra tasty modifiers to play with */
857
858 /* sometimes is just easier to whitelist for lack of a better method */
859 for (i=1; i<argc; i++)
860 {
861 if ((wcsicmp(argv[i], L"/user") != 0) &&
862 (wcsicmp(argv[i], L"/groups") != 0) &&
863 (wcsicmp(argv[i], L"/priv") != 0) &&
864 (wcsicmp(argv[i], L"/all") != 0) &&
865 (wcsicmp(argv[i], L"") != 0))
866 {
868 return 1;
869 }
870 }
871
872 if (GetArgument(L"/user", argc, argv))
873 {
874 WamBit |= WAM_USER;
875 }
876
877 if (GetArgument(L"/groups", argc, argv))
878 {
879 WamBit |= WAM_GROUPS;
880 }
881
882 if (GetArgument(L"/priv", argc, argv))
883 {
884 WamBit |= WAM_PRIV;
885 }
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}
static int argc
Definition: ServiceArgs.c:12
#define IDS_HELP
Definition: resource.h:3
#define ConInitStdStreams()
Definition: fc.c:13
#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
#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
#define wcsicmp
Definition: compat.h:15
static DWORD DWORD * dwLength
Definition: fusion.c:86
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
@ 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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
enum _SID_NAME_USE SID_NAME_USE
@ SidTypeAlias
Definition: lsa.idl:121
@ SidTypeWellKnownGroup
Definition: lsa.idl:122
@ SidTypeLabel
Definition: lsa.idl:127
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static PSID pSid
Definition: security.c:74
#define argv
Definition: mplay32.c:18
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 UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
int wmain()
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define exit(n)
Definition: config.h:202
#define _countof(array)
Definition: sndvol32.h:68
BOOLEAN WINAPI GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
Definition: sspi.c:1079
#define StringCchCat
Definition: strsafe.h:317
base of all file and directory entries
Definition: entries.h:83
UINT Rows
Definition: whoami.c:149
UINT Cols
Definition: whoami.c:150
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1018
$ULONG GroupCount
Definition: setypes.h:1014
$ULONG PrivilegeCount
Definition: setypes.h:1023
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1024
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
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
int ret
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
int WhoamiUser(void)
Definition: whoami.c:419
#define RC_STRING_MAX_SIZE
LPWSTR WhoamiLoadRcString(INT ResId)
Definition: whoami.c:121
int WhoamiLogonId(void)
Definition: whoami.c:375
void WhoamiPrintHeader(int HeaderId)
Definition: whoami.c:131
#define wprintf(...)
Definition: whoami.c:18
void WhoamiPrintTable(WhoamiTable *pTable)
Definition: whoami.c:199
VOID * WhoamiGetTokenInfo(TOKEN_INFORMATION_CLASS TokenType)
Definition: whoami.c:81
UINT PrintFormatArgCount
Definition: whoami.c:22
BOOL GetArgument(WCHAR *arg, int argc, WCHAR *argv[])
Definition: whoami.c:33
int WhoamiPriv(void)
Definition: whoami.c:589
int WhoamiGroups(void)
Definition: whoami.c:462
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
WhoamiTable * WhoamiAllocTable(UINT Rows, UINT Cols)
Definition: whoami.c:155
void WhoamiSetTableDyn(WhoamiTable *pTable, WCHAR *Entry, UINT Row, UINT Col)
Definition: whoami.c:193
enum @3 PrintFormat
void BlankArgument(int argc, WCHAR *argv[])
Definition: whoami.c:50
#define WAM_PRIV
LPWSTR WhoamiGetUser(EXTENDED_NAME_FORMAT NameFormat)
Definition: whoami.c:57
@ list
Definition: whoami.c:28
@ csv
Definition: whoami.c:29
@ table
Definition: whoami.c:27
@ undefined
Definition: whoami.c:26
#define WAM_GROUPS
#define WAM_USER
BOOL NoHeader
Definition: whoami.c:20
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)
_In_ ULONG Rows
Definition: haltypes.h:7
struct _TOKEN_GROUPS * PTOKEN_GROUPS
struct _TOKEN_USER * PTOKEN_USER
@ TokenGroups
Definition: setypes.h:967
@ TokenPrivileges
Definition: setypes.h:968
@ TokenUser
Definition: setypes.h:966
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
enum _TOKEN_INFORMATION_CLASS TOKEN_INFORMATION_CLASS
#define TOKEN_READ
Definition: setypes.h:951
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193