2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE: base/applications/network/net/cmdUser.c
7 * PROGRAMMERS: Eric Kohl
13 #define SECONDS_PER_DAY (60 * 60 * 24)
14 #define SECONDS_PER_HOUR (60 * 60)
15 #define HOURS_PER_DAY 24
16 #define DAYS_PER_WEEK 7
18 typedef struct _COUNTY_TABLE
22 } COUNTRY_TABLE
, *PCOUNTRY_TABLE
;
25 static WCHAR szPasswordChars
[] = L
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%_-+:";
26 static COUNTRY_TABLE CountryTable
[] =
27 { { 0, 5080}, // System Default
28 { 1, 5081}, // United States
29 { 2, 5082}, // Canada (French)
30 { 3, 5083}, // Latin America
31 { 31, 5084}, // Netherlands
32 { 32, 5085}, // Belgium
33 { 33, 5086}, // France
36 { 41, 5088}, // Switzerland
37 { 44, 5089}, // United Kingdom
38 { 45, 5091}, // Denmark
39 { 46, 5092}, // Sweden
40 { 47, 5093}, // Norway
41 { 49, 5094}, // Germany
42 { 61, 5095}, // Australia
45 { 86, 5098}, // China (PRC)
46 { 88, 5099}, // Taiwan
48 {351, 5101}, // Portugal
49 {358, 5102}, // Finland
50 {785, 5103}, // Arabic
51 {972, 5104} }; // Hebrew
53 //static PWSTR DaysArray[] = {L"So", L"Mo", L"Di", L"Mi", L"Do", L"Fr", L"Sa"};
54 static PWSTR DaysArray
[] = {L
"Sun", L
"Mon", L
"Tue", L
"Wed", L
"Thu", L
"Fri", L
"Sat"};
58 CompareInfo(const void *a
, const void *b
)
60 return _wcsicmp(((PUSER_INFO_0
)a
)->usri0_name
,
61 ((PUSER_INFO_0
)b
)->usri0_name
);
69 PUSER_INFO_0 pBuffer
= NULL
;
70 PSERVER_INFO_100 pServer
= NULL
;
71 DWORD dwRead
= 0, dwTotal
= 0;
73 DWORD ResumeHandle
= 0;
74 NET_API_STATUS Status
;
76 Status
= NetServerGetInfo(NULL
,
79 if (Status
!= NERR_Success
)
82 ConPuts(StdOut
, L
"\n");
83 PrintMessageStringV(4410, pServer
->sv100_name
);
84 ConPuts(StdOut
, L
"\n");
85 PrintPadding(L
'-', 79);
86 ConPuts(StdOut
, L
"\n");
88 NetApiBufferFree(pServer
);
92 Status
= NetUserEnum(NULL
,
100 if ((Status
!= NERR_Success
) && (Status
!= ERROR_MORE_DATA
))
105 sizeof(PUSER_INFO_0
),
108 for (i
= 0; i
< dwRead
; i
++)
110 if (pBuffer
[i
].usri0_name
)
111 ConPrintf(StdOut
, L
"%s\n", pBuffer
[i
].usri0_name
);
114 NetApiBufferFree(pBuffer
);
117 while (Status
== ERROR_MORE_DATA
);
125 PrintDateTime(DWORD dwSeconds
)
129 SYSTEMTIME SystemTime
;
130 WCHAR DateBuffer
[80];
131 WCHAR TimeBuffer
[80];
133 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
134 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
135 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
136 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
137 FileTimeToSystemTime(&FileTime
, &SystemTime
);
139 GetDateFormatW(LOCALE_USER_DEFAULT
,
144 ARRAYSIZE(DateBuffer
));
146 GetTimeFormatW(LOCALE_USER_DEFAULT
,
151 ARRAYSIZE(TimeBuffer
));
153 ConPrintf(StdOut
, L
"%s %s", DateBuffer
, TimeBuffer
);
159 PrintLocalTime(DWORD dwSeconds
)
163 SYSTEMTIME SystemTime
;
164 WCHAR TimeBuffer
[80];
166 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
167 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
168 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
169 FileTimeToSystemTime(&FileTime
, &SystemTime
);
171 GetTimeFormatW(LOCALE_USER_DEFAULT
,
176 ARRAYSIZE(TimeBuffer
));
178 ConPrintf(StdOut
, L
"%s", TimeBuffer
);
184 GetTimeInSeconds(VOID
)
190 GetSystemTimeAsFileTime(&FileTime
);
191 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
192 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
193 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
201 GetCountryFromCountryCode(
202 _In_ DWORD dwCountryCode
,
203 _In_ DWORD dwCountryLength
,
204 _Out_ PWSTR szCountryBuffer
)
208 for (i
= 0; i
< ARRAYSIZE(CountryTable
); i
++)
210 if (CountryTable
[i
].dwCountryCode
== dwCountryCode
)
212 if (szCountryBuffer
!= NULL
&& dwCountryLength
> 0)
214 FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_IGNORE_INSERTS
,
216 CountryTable
[i
].dwMessageId
,
237 DWORD dwIndex
= dwBitNumber
/ 8;
238 BYTE Mask
= 1 << (dwBitNumber
& 7);
240 return ((pBitmap
[dwIndex
] & Mask
) != 0);
250 DWORD dwIndex
= dwBitNumber
/ 8;
251 BYTE Mask
= 1 << (dwBitNumber
& 7);
253 pBitmap
[dwIndex
] |= Mask
;
260 DWORD dwUnitsPerWeek
,
264 DWORD dwUnitsPerDay
, dwBitNumber
, dwSecondsPerUnit
;
265 DWORD dwStartTime
, dwEndTime
, dwStartDay
, dwEndDay
, dwBias
;
266 BOOL bBitValue
, bFirst
= TRUE
;
267 TIME_ZONE_INFORMATION TimeZoneInformation
;
269 GetTimeZoneInformation(&TimeZoneInformation
);
270 dwBias
= (TimeZoneInformation
.Bias
/ 60) * SECONDS_PER_HOUR
;
272 if ((dwUnitsPerWeek
== 0) ||
273 ((dwUnitsPerWeek
%7) != 0))
276 dwUnitsPerDay
= dwUnitsPerWeek
/ 7;
278 if (((dwUnitsPerDay
% 24) != 0) ||
279 ((dwUnitsPerDay
/ 24) > 6))
282 dwSecondsPerUnit
= (SECONDS_PER_DAY
) / dwUnitsPerDay
;
284 for (dwBitNumber
= 0; dwBitNumber
< dwUnitsPerWeek
; dwBitNumber
++)
286 bBitValue
= GetBitValue(pLogonHours
, dwBitNumber
);
289 dwStartTime
= dwSecondsPerUnit
* dwBitNumber
;
291 while (bBitValue
!= 0 && dwBitNumber
< dwUnitsPerWeek
)
294 if (dwBitNumber
< dwUnitsPerWeek
)
295 bBitValue
= GetBitValue(pLogonHours
, dwBitNumber
);
298 dwEndTime
= dwSecondsPerUnit
* dwBitNumber
;
301 PrintPadding(L
' ', nPaddedLength
);
303 if (dwStartTime
== 0 && dwEndTime
== (SECONDS_PER_DAY
* 7))
305 PrintMessageString(4302);
306 ConPuts(StdOut
, L
"\n");
310 dwStartDay
= dwStartTime
/ SECONDS_PER_DAY
;
311 dwEndDay
= (dwEndTime
/ SECONDS_PER_DAY
) % 7;
313 PrintMessageString(4307 + dwStartDay
);
314 ConPuts(StdOut
, L
" ");
316 /* Convert from GMT to local timezone */
317 PrintLocalTime((dwStartTime
% SECONDS_PER_DAY
) - dwBias
);
319 ConPrintf(StdOut
, L
" - ");
320 if (dwStartDay
!= dwEndDay
)
322 PrintMessageString(4307 + dwEndDay
);
323 ConPuts(StdOut
, L
" ");
326 /* Convert from GMT to local timezone */
327 PrintLocalTime((dwEndTime
% SECONDS_PER_DAY
) - dwBias
);
328 ConPuts(StdOut
, L
"\n");
338 PrintMessageString(4434);
339 ConPuts(StdOut
, L
"\n");
346 DisplayUser(LPWSTR lpUserName
)
348 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
349 PUSER_INFO_4 pUserInfo
= NULL
;
350 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
351 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
352 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
353 DWORD dwGroupRead
, dwGroupTotal
;
357 INT nPaddedLength
= 36;
358 NET_API_STATUS Status
;
360 /* Modify the user */
361 Status
= NetUserGetInfo(NULL
,
364 (LPBYTE
*)&pUserInfo
);
365 if (Status
!= NERR_Success
)
368 Status
= NetUserModalsGet(NULL
,
370 (LPBYTE
*)&pUserModals
);
371 if (Status
!= NERR_Success
)
374 Status
= NetUserGetLocalGroups(NULL
,
378 (LPBYTE
*)&pLocalGroupInfo
,
379 MAX_PREFERRED_LENGTH
,
382 if (Status
!= NERR_Success
)
385 Status
= NetUserGetGroups(NULL
,
388 (LPBYTE
*)&pGroupInfo
,
389 MAX_PREFERRED_LENGTH
,
392 if (Status
!= NERR_Success
)
395 PrintPaddedMessageString(4411, nPaddedLength
);
396 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_name
);
398 PrintPaddedMessageString(4412, nPaddedLength
);
399 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_full_name
);
401 PrintPaddedMessageString(4413, nPaddedLength
);
402 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_comment
);
404 PrintPaddedMessageString(4414, nPaddedLength
);
405 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_usr_comment
);
407 PrintPaddedMessageString(4416, nPaddedLength
);
408 GetCountryFromCountryCode(pUserInfo
->usri4_country_code
,
409 ARRAYSIZE(szCountry
), szCountry
);
410 ConPrintf(StdOut
, L
"%03ld (%s)\n", pUserInfo
->usri4_country_code
, szCountry
);
412 PrintPaddedMessageString(4419, nPaddedLength
);
413 if (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)
414 PrintMessageString(4301);
415 else if (pUserInfo
->usri4_flags
& UF_LOCKOUT
)
416 PrintMessageString(4440);
418 PrintMessageString(4300);
419 ConPuts(StdOut
, L
"\n");
421 PrintPaddedMessageString(4420, nPaddedLength
);
422 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
423 PrintMessageString(4305);
425 PrintDateTime(pUserInfo
->usri4_acct_expires
);
426 ConPuts(StdOut
, L
"\n\n");
428 PrintPaddedMessageString(4421, nPaddedLength
);
429 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
430 PrintDateTime(dwLastSet
);
431 ConPuts(StdOut
, L
"\n");
433 PrintPaddedMessageString(4422, nPaddedLength
);
434 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
435 PrintMessageString(4305);
437 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
438 ConPuts(StdOut
, L
"\n");
440 PrintPaddedMessageString(4423, nPaddedLength
);
441 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
442 ConPuts(StdOut
, L
"\n");
444 PrintPaddedMessageString(4437, nPaddedLength
);
445 PrintMessageString((pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? 4301 : 4300);
446 ConPuts(StdOut
, L
"\n");
448 PrintPaddedMessageString(4438, nPaddedLength
);
449 PrintMessageString((pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? 4301 : 4300);
450 ConPuts(StdOut
, L
"\n\n");
452 PrintPaddedMessageString(4424, nPaddedLength
);
453 if (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0)
454 PrintMessageString(4302);
456 ConPrintf(StdOut
, L
"%s", pUserInfo
->usri4_workstations
);
457 ConPuts(StdOut
, L
"\n");
459 PrintPaddedMessageString(4429, nPaddedLength
);
460 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_script_path
);
462 PrintPaddedMessageString(4439, nPaddedLength
);
463 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_profile
);
465 PrintPaddedMessageString(4436, nPaddedLength
);
466 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_home_dir
);
468 PrintPaddedMessageString(4430, nPaddedLength
);
469 if (pUserInfo
->usri4_last_logon
== 0)
470 PrintMessageString(4305);
472 PrintDateTime(pUserInfo
->usri4_last_logon
);
473 ConPuts(StdOut
, L
"\n\n");
475 PrintPaddedMessageString(4432, nPaddedLength
);
476 if (pUserInfo
->usri4_logon_hours
== NULL
)
478 PrintMessageString(4302);
479 ConPuts(StdOut
, L
"\n");
483 PrintLogonHours(pUserInfo
->usri4_units_per_week
,
484 pUserInfo
->usri4_logon_hours
,
488 ConPuts(StdOut
, L
"\n");
489 PrintPaddedMessageString(4427, nPaddedLength
);
490 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
492 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
495 PrintPadding(L
' ', nPaddedLength
);
496 ConPrintf(StdOut
, L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
501 ConPuts(StdOut
, L
"\n");
504 PrintPaddedMessageString(4431, nPaddedLength
);
505 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
507 for (i
= 0; i
< dwGroupTotal
; i
++)
510 PrintPadding(L
' ', nPaddedLength
);
511 ConPrintf(StdOut
, L
"*%s\n", pGroupInfo
[i
].grui0_name
);
516 ConPuts(StdOut
, L
"\n");
520 if (pGroupInfo
!= NULL
)
521 NetApiBufferFree(pGroupInfo
);
523 if (pLocalGroupInfo
!= NULL
)
524 NetApiBufferFree(pLocalGroupInfo
);
526 if (pUserModals
!= NULL
)
527 NetApiBufferFree(pUserModals
);
529 if (pUserInfo
!= NULL
)
530 NetApiBufferFree(pUserInfo
);
542 WCHAR szPassword1
[PWLEN
+ 1];
543 WCHAR szPassword2
[PWLEN
+ 1];
546 *lpAllocated
= FALSE
;
550 PrintMessageString(4358);
551 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
552 ConPuts(StdOut
, L
"\n");
554 PrintMessageString(4361);
555 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
556 ConPuts(StdOut
, L
"\n");
558 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
559 wcscmp(szPassword1
, szPassword2
) == 0)
561 ptr
= HeapAlloc(GetProcessHeap(),
563 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
566 wcscpy(ptr
, szPassword1
);
574 ConPuts(StdOut
, L
"\n");
575 PrintMessageString(3728);
584 GenerateRandomPassword(
588 LPWSTR pPassword
= NULL
;
589 INT nCharsLen
, i
, nLength
= 8;
591 srand(GetTickCount());
593 pPassword
= HeapAlloc(GetProcessHeap(),
595 (nLength
+ 1) * sizeof(WCHAR
));
596 if (pPassword
== NULL
)
599 nCharsLen
= wcslen(szPasswordChars
);
601 for (i
= 0; i
< nLength
; i
++)
603 pPassword
[i
] = szPasswordChars
[rand() % nCharsLen
];
606 *lpPassword
= pPassword
;
613 BuildWorkstationsList(
614 _Out_ PWSTR
*pWorkstationsList
,
617 BOOL isLastSep
, isSep
;
625 /* Check for invalid characters in the raw string */
626 if (wcspbrk(pRaw
, L
"/[]=?\\+:.") != NULL
)
629 /* Count the number of workstations in the list and
630 * the required buffer size */
633 nRawLength
= wcslen(pRaw
);
634 for (i
= 0; i
< nRawLength
; i
++)
637 if (c
== L
',' || c
== L
';')
642 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
649 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
659 /* Leave, if there are no workstations in the list */
662 pWorkstationsList
= NULL
;
666 /* Fail if there are more than eight workstations in the list */
670 /* Allocate the buffer for the clean workstation list */
671 pList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nLength
* sizeof(WCHAR
));
673 return ERROR_NOT_ENOUGH_MEMORY
;
675 /* Build the clean workstation list */
678 nRawLength
= wcslen(pRaw
);
679 for (i
= 0, j
= 0; i
< nRawLength
; i
++)
682 if (c
== L
',' || c
== L
';')
687 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
698 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
706 *pWorkstationsList
= pList
;
721 while (iswdigit(**s
))
723 *pwValue
= *pwValue
* 10 + **s
- L
'0';
736 if (**s
== L
'/' || **s
== L
'.')
752 SYSTEMTIME SystemTime
= {0};
753 FILETIME LocalFileTime
, FileTime
;
761 GetLocaleInfoW(LOCALE_USER_DEFAULT
,
770 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
772 if (!ReadSeparator(&p
))
774 if (!ReadNumber(&p
, &SystemTime
.wDay
))
776 if (!ReadSeparator(&p
))
778 if (!ReadNumber(&p
, &SystemTime
.wYear
))
783 if (!ReadNumber(&p
, &SystemTime
.wDay
))
785 if (!ReadSeparator(&p
))
787 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
789 if (!ReadSeparator(&p
))
791 if (!ReadNumber(&p
, &SystemTime
.wYear
))
796 if (!ReadNumber(&p
, &SystemTime
.wYear
))
798 if (!ReadSeparator(&p
))
800 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
802 if (!ReadSeparator(&p
))
804 if (!ReadNumber(&p
, &SystemTime
.wDay
))
809 /* if only entered two digits: */
810 /* assume 2000's if value less than 80 */
811 /* assume 1900's if value greater or equal 80 */
812 if (SystemTime
.wYear
<= 99)
814 if (SystemTime
.wYear
>= 80)
815 SystemTime
.wYear
+= 1900;
817 SystemTime
.wYear
+= 2000;
820 if (!SystemTimeToFileTime(&SystemTime
, &LocalFileTime
))
823 if (!LocalFileTimeToFileTime(&LocalFileTime
, &FileTime
))
826 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
827 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
829 if (!RtlTimeToSecondsSince1970(&Time
, pSeconds
))
845 if (!iswdigit(pszString
[0]))
849 while (iswdigit(*pChar
))
851 lHour
= lHour
* 10 + *pChar
- L
'0';
861 if ((*pChar
!= UNICODE_NULL
) &&
865 if ((_wcsicmp(pChar
, L
"am") == 0) ||
866 (_wcsicmp(pChar
, L
"a.m.") == 0))
871 else if ((_wcsicmp(pChar
, L
"pm") == 0) ||
872 (_wcsicmp(pChar
, L
"p.m.") == 0))
897 for (i
= 0; i
< ARRAYSIZE(DaysArray
); i
++)
899 if (_wcsicmp(pszString
, DaysArray
[i
]) == 0)
914 PBYTE
*ppLogonBitmap
,
915 PDWORD pdwUnitsPerWeek
)
917 TIME_ZONE_INFORMATION TimeZoneInformation
;
918 PBYTE pLogonBitmap
= NULL
;
919 DWORD dwError
= ERROR_SUCCESS
;
922 WCHAR prevSep
, nextSep
;
923 DWORD dwStartDay
, dwEndDay
, i
, j
;
924 LONG lStartHour
, lEndHour
, lBias
;
928 GetTimeZoneInformation(&TimeZoneInformation
);
929 lBias
= TimeZoneInformation
.Bias
/ 60;
931 pLogonBitmap
= HeapAlloc(GetProcessHeap(),
934 if (pLogonBitmap
== NULL
)
935 return ERROR_OUTOFMEMORY
;
937 if (*pszParams
== UNICODE_NULL
)
942 if (wcsicmp(pszParams
, L
"all") == 0)
944 FillMemory(pLogonBitmap
, UNITS_PER_WEEK
/ 8, 0xFF);
948 ZeroMemory(&DayBitmap
, sizeof(DayBitmap
));
949 ZeroMemory(HourBitmap
, sizeof(HourBitmap
));
951 ZeroMemory(szBuffer
, sizeof(szBuffer
));
954 prevSep
= UNICODE_NULL
;
955 nextSep
= UNICODE_NULL
;
958 if (*ptr1
!= L
'-' && *ptr1
!= L
',' && *ptr1
!= L
';' && *ptr1
!= UNICODE_NULL
)
970 /* Set first value */
971 if (iswdigit(szBuffer
[0]))
974 if (!ParseHour(szBuffer
, &lStartHour
))
980 /* Convert from local timezone to GMT */
983 lStartHour
+= UNITS_PER_WEEK
;
984 else if (lStartHour
> UNITS_PER_WEEK
)
985 lStartHour
-= UNITS_PER_WEEK
;
987 SetBitValue(HourBitmap
, (DWORD
)lStartHour
);
992 if (!ParseDay(szBuffer
, &dwStartDay
))
998 SetBitValue(&DayBitmap
, dwStartDay
);
1003 /* Set second value */
1004 if (iswdigit(szBuffer
[0]))
1007 if (!ParseHour(szBuffer
, &lEndHour
))
1013 if (lEndHour
< lStartHour
)
1014 lEndHour
+= HOURS_PER_DAY
;
1015 else if (lEndHour
== lStartHour
)
1016 lEndHour
= lStartHour
+ HOURS_PER_DAY
;
1018 /* Convert from local timezone to GMT */
1021 lEndHour
+= UNITS_PER_WEEK
;
1022 else if (lEndHour
> UNITS_PER_WEEK
)
1023 lEndHour
-= UNITS_PER_WEEK
;
1025 for (i
= (DWORD
)lStartHour
; i
< (DWORD
)lEndHour
; i
++)
1026 SetBitValue(HourBitmap
, i
);
1031 if (!ParseDay(szBuffer
, &dwEndDay
))
1037 if (dwEndDay
<= dwStartDay
)
1038 dwEndDay
+= DAYS_PER_WEEK
;
1040 for (i
= dwStartDay
; i
<= dwEndDay
; i
++)
1041 SetBitValue(&DayBitmap
, i
% DAYS_PER_WEEK
);
1045 if (*ptr1
== L
';' || *ptr1
== UNICODE_NULL
)
1047 /* Fill the logon hour bitmap */
1048 for (i
= 0; i
< DAYS_PER_WEEK
; i
++)
1050 if (GetBitValue(&DayBitmap
, i
))
1052 for (j
= 0; j
< 48; j
++)
1054 if (GetBitValue(HourBitmap
, j
))
1055 SetBitValue(pLogonBitmap
, ((i
* HOURS_PER_DAY
) + j
) % UNITS_PER_WEEK
);
1060 /* Reset the Bitmaps */
1061 ZeroMemory(&DayBitmap
, sizeof(DayBitmap
));
1062 ZeroMemory(HourBitmap
, sizeof(HourBitmap
));
1065 if (*ptr1
== UNICODE_NULL
)
1068 ZeroMemory(szBuffer
, sizeof(szBuffer
));
1076 printf("LogonBitmap:\n");
1077 for (i
= 0; i
< DAYS_PER_WEEK
; i
++)
1080 printf("%lu: %02x%02x%02x\n", i
, pLogonHours
[j
+ 2], pLogonHours
[j
+ 1], pLogonHours
[j
+ 0]);
1086 if (dwError
== ERROR_SUCCESS
)
1088 *ppLogonBitmap
= pLogonBitmap
;
1089 *pdwUnitsPerWeek
= UNITS_PER_WEEK
;
1093 if (pLogonBitmap
!= NULL
)
1094 HeapFree(GetProcessHeap(), 0, pLogonBitmap
);
1095 *ppLogonBitmap
= NULL
;
1096 *pdwUnitsPerWeek
= 0;
1111 BOOL bDelete
= FALSE
;
1113 BOOL bDomain
= FALSE
;
1115 BOOL bRandomPassword
= FALSE
;
1116 LPWSTR lpUserName
= NULL
;
1117 LPWSTR lpPassword
= NULL
;
1118 PUSER_INFO_4 pUserInfo
= NULL
;
1119 USER_INFO_4 UserInfo
;
1120 LPWSTR pWorkstations
= NULL
;
1124 BOOL bPasswordAllocated
= FALSE
;
1125 PBYTE pLogonHours
= NULL
;
1126 DWORD dwUnitsPerWeek
;
1127 NET_API_STATUS Status
;
1130 if ((i
< argc
) && (argv
[i
][0] != L
'/'))
1132 lpUserName
= argv
[i
];
1133 // ConPrintf(StdOut, L"User: %s\n", lpUserName);
1137 if ((i
< argc
) && (argv
[i
][0] != L
'/'))
1139 lpPassword
= argv
[i
];
1140 // ConPrintf(StdOut, L"Password: %s\n", lpPassword);
1144 for (j
= i
; j
< argc
; j
++)
1146 if (_wcsicmp(argv
[j
], L
"/help") == 0)
1148 PrintNetMessage(MSG_USER_HELP
);
1151 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
1155 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
1159 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
1161 ConPuts(StdErr
, L
"The /DOMAIN option is not supported yet.\n");
1166 else if (_wcsicmp(argv
[j
], L
"/random") == 0)
1168 bRandomPassword
= TRUE
;
1169 GenerateRandomPassword(&lpPassword
,
1170 &bPasswordAllocated
);
1174 if (lpUserName
== NULL
&& lpPassword
== NULL
)
1176 Status
= EnumerateUsers();
1177 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1180 else if (lpUserName
!= NULL
&& lpPassword
== NULL
&& argc
== 3)
1182 Status
= DisplayUser(lpUserName
);
1183 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1187 if (bAdd
&& bDelete
)
1193 /* Interactive password input */
1194 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
1196 ReadPassword(&lpPassword
,
1197 &bPasswordAllocated
);
1200 if (!bAdd
&& !bDelete
)
1202 /* Modify the user */
1203 Status
= NetUserGetInfo(NULL
,
1206 (LPBYTE
*)&pUserInfo
);
1207 if (Status
!= NERR_Success
)
1209 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1214 else if (bAdd
&& !bDelete
)
1217 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
1219 UserInfo
.usri4_name
= lpUserName
;
1220 UserInfo
.usri4_password
= lpPassword
;
1221 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
1222 UserInfo
.usri4_acct_expires
= TIMEQ_FOREVER
;
1223 UserInfo
.usri4_primary_group_id
= DOMAIN_GROUP_RID_USERS
;
1225 pUserInfo
= &UserInfo
;
1228 for (j
= i
; j
< argc
; j
++)
1230 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
1233 if (_wcsicmp(p
, L
"yes") == 0)
1235 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
1237 else if (_wcsicmp(p
, L
"no") == 0)
1239 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
1243 PrintMessageStringV(3952, L
"/ACTIVE");
1248 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
1250 pUserInfo
->usri4_comment
= &argv
[j
][9];
1252 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
1255 value
= wcstoul(p
, &endptr
, 10);
1258 PrintMessageStringV(3952, L
"/COUNTRYCODE");
1263 /* Verify the country code */
1264 if (GetCountryFromCountryCode(value
, 0, NULL
))
1265 pUserInfo
->usri4_country_code
= value
;
1267 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
1270 if (_wcsicmp(p
, L
"never") == 0)
1272 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
1274 else if (!ParseDate(p
, &pUserInfo
->usri4_acct_expires
))
1276 PrintMessageStringV(3952, L
"/EXPIRES");
1281 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
1283 pUserInfo
->usri4_full_name
= &argv
[j
][10];
1285 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
1287 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
1289 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
1292 if (_wcsicmp(p
, L
"yes") == 0)
1294 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
1296 else if (_wcsicmp(p
, L
"no") == 0)
1298 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
1302 PrintMessageStringV(3952, L
"/PASSWORDCHG");
1307 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
1310 if (_wcsicmp(p
, L
"yes") == 0)
1312 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
1314 else if (_wcsicmp(p
, L
"no") == 0)
1316 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
1320 PrintMessageStringV(3952, L
"/PASSWORDREQ");
1325 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
1327 pUserInfo
->usri4_profile
= &argv
[j
][13];
1329 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
1331 pUserInfo
->usri4_script_path
= &argv
[j
][12];
1333 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
1335 Status
= ParseLogonHours(&argv
[j
][7],
1338 if (Status
== ERROR_SUCCESS
)
1340 pUserInfo
->usri4_logon_hours
= pLogonHours
;
1341 pUserInfo
->usri4_units_per_week
= dwUnitsPerWeek
;
1345 PrintMessageString(Status
);
1349 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
1351 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
1353 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
1356 if (wcscmp(p
, L
"*") == 0 || wcscmp(p
, L
"") == 0)
1358 pUserInfo
->usri4_workstations
= NULL
;
1362 Status
= BuildWorkstationsList(&pWorkstations
, p
);
1363 if (Status
== NERR_Success
)
1365 pUserInfo
->usri4_workstations
= pWorkstations
;
1369 ConPrintf(StdOut
, L
"Status %lu\n\n", Status
);
1377 if (!bAdd
&& !bDelete
)
1379 /* Modify the user */
1380 Status
= NetUserSetInfo(NULL
,
1385 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1387 else if (bAdd
&& !bDelete
)
1390 Status
= NetUserAdd(NULL
,
1394 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1396 else if (!bAdd
&& bDelete
)
1398 /* Delete the user */
1399 Status
= NetUserDel(NULL
,
1401 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1404 if (Status
== NERR_Success
&&
1405 lpPassword
!= NULL
&&
1406 bRandomPassword
== TRUE
)
1408 PrintMessageStringV(3968, lpUserName
, lpPassword
);
1412 if (pLogonHours
!= NULL
)
1413 HeapFree(GetProcessHeap(), 0, pLogonHours
);
1415 if (pWorkstations
!= NULL
)
1416 HeapFree(GetProcessHeap(), 0, pWorkstations
);
1418 if ((bPasswordAllocated
== TRUE
) && (lpPassword
!= NULL
))
1419 HeapFree(GetProcessHeap(), 0, lpPassword
);
1421 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
1422 NetApiBufferFree(pUserInfo
);
1426 PrintMessageString(4381);
1427 ConPuts(StdOut
, L
"\n");
1428 PrintNetMessage(MSG_USER_SYNTAX
);