https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bf76e1bf20c0da25c9245…
commit bf76e1bf20c0da25c9245d01566a6f796f54e929
Author:     Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Aug 26 00:13:14 2018 +0200
Commit:     Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Aug 26 00:13:14 2018 +0200
    [NET] Add a date parser for the expires option of the net user command
---
 base/applications/network/net/cmdUser.c | 132 +++++++++++++++++++++++++++++++-
 1 file changed, 130 insertions(+), 2 deletions(-)
diff --git a/base/applications/network/net/cmdUser.c
b/base/applications/network/net/cmdUser.c
index d093ffc9e0..a67476e13d 100644
--- a/base/applications/network/net/cmdUser.c
+++ b/base/applications/network/net/cmdUser.c
@@ -488,6 +488,130 @@ BuildWorkstationsList(
 }
+static
+BOOL
+ReadNumber(
+    PWSTR *s,
+    PWORD pwValue)
+{
+    if (!iswdigit(**s))
+        return FALSE;
+
+    while (iswdigit(**s))
+    {
+        *pwValue = *pwValue * 10 + **s - L'0';
+        (*s)++;
+    }
+
+    return TRUE;
+}
+
+
+static
+BOOL
+ReadSeparator(
+    PWSTR *s)
+{
+    if (**s == L'/' || **s == L'.')
+    {
+        (*s)++;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+static
+BOOL
+ParseDate(
+    PWSTR s,
+    PULONG pSeconds)
+{
+    SYSTEMTIME SystemTime = {0};
+    FILETIME LocalFileTime, FileTime;
+    LARGE_INTEGER Time;
+    INT nDateFormat = 0;
+    PWSTR p = s;
+
+    if (!*s)
+        return FALSE;
+
+    GetLocaleInfoW(LOCALE_USER_DEFAULT,
+                   LOCALE_IDATE,
+                   (PWSTR)&nDateFormat,
+                   sizeof(INT));
+
+    switch (nDateFormat)
+    {
+        case 0: /* mmddyy */
+        default:
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            break;
+
+        case 1: /* ddmmyy */
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            break;
+
+        case 2: /* yymmdd */
+            if (!ReadNumber(&p, &SystemTime.wYear))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wMonth))
+                return FALSE;
+            if (!ReadSeparator(&p))
+                return FALSE;
+            if (!ReadNumber(&p, &SystemTime.wDay))
+                return FALSE;
+            break;
+    }
+
+    /* if only entered two digits: */
+    /*   assume 2000's if value less than 80 */
+    /*   assume 1900's if value greater or equal 80 */
+    if (SystemTime.wYear <= 99)
+    {
+        if (SystemTime.wYear >= 80)
+            SystemTime.wYear += 1900;
+        else
+            SystemTime.wYear += 2000;
+    }
+
+    if (!SystemTimeToFileTime(&SystemTime, &LocalFileTime))
+        return FALSE;
+
+    if (!LocalFileTimeToFileTime(&LocalFileTime, &FileTime))
+        return FALSE;
+
+    Time.u.LowPart = FileTime.dwLowDateTime;
+    Time.u.HighPart = FileTime.dwHighDateTime;
+
+    if (!RtlTimeToSecondsSince1970(&Time, pSeconds))
+        return FALSE;
+
+    return TRUE;
+}
+
+
 INT
 cmdUser(
     INT argc,
@@ -655,10 +779,14 @@ cmdUser(
             {
                 pUserInfo->usri4_acct_expires = TIMEQ_FOREVER;
             }
-            else
+            else if (!ParseDate(p, &pUserInfo->usri4_acct_expires))
             {
+                ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE,
L"/EXPIRES");
+                result = 1;
+                goto done;
+
                 /* FIXME: Parse the date */
-                ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED,
L"/EXPIRES");
+//                ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED,
L"/EXPIRES");
             }
         }
         else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)