[NET] Add a date parser for the expires option of the net user command
authorEric Kohl <eric.kohl@reactos.org>
Sat, 25 Aug 2018 22:13:14 +0000 (00:13 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 25 Aug 2018 22:13:14 +0000 (00:13 +0200)
base/applications/network/net/cmdUser.c

index d093ffc..a67476e 100644 (file)
@@ -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)