[RAPPS] Update check, license type
[reactos.git] / reactos / base / applications / rapps / misc.cpp
index 26e548a..159c739 100644 (file)
@@ -8,6 +8,8 @@
  */
 
 #include "rapps.h"
+#include <atlsimpcoll.h>
+#include <atlstr.h> 
 
 /* SESSION Operation */
 #define EXTRACT_FILLFILELIST  0x00000001
@@ -18,6 +20,8 @@ WCHAR szCachedINISectionLocale[MAX_PATH] = L"Section.";
 WCHAR szCachedINISectionLocaleNeutral[MAX_PATH] = {0};
 BYTE bCachedSectionStatus = FALSE;
 
+#define STR_VERSION_CURRENT L"CURRENT"
+
 typedef struct
 {
     int erfOper;
@@ -495,5 +499,116 @@ UINT ParserGetInt(LPCWSTR lpKeyName, LPCWSTR lpFileName)
     RtlInitUnicodeString(&BufferW, Buffer);
     RtlUnicodeStringToInteger(&BufferW, 0, &Result);
 
-    return Result;
+    return (UINT)Result;
+}
+
+template<typename XCHAR>
+inline BOOL IsCharNumeric(XCHAR ch)
+{
+    return IsCharAlphaNumeric(ch) && !IsCharAlpha(ch);
+}
+
+
+//Parses version string that can be formatted as 1.2.3-4b (or CURRENT)
+//Returns int buffer and it's size
+BOOL
+ParseVersion(_In_z_ LPCWSTR szVersion, _Outptr_ PVERSION_INFO Version)
+{
+    ATL::CStringW szVersionSingleInt = L"";
+    BOOL bHasParsed = TRUE;
+    INT VersionCharCount = 0;
+    INT VersionLength = lstrlenW(szVersion);
+    StringCbCopyW(Version->szVersion, VersionLength * sizeof(szVersion), szVersion);
+    //CURRENT
+    if (!StrCmpW(szVersion, STR_VERSION_CURRENT))
+    {
+        Version->VersionSize = NULL;
+        return bHasParsed;
+    }
+
+    Version->VersionSize = 0;
+    //int expected every iteration, quit the loop if its not a number
+    while (Version->VersionSize < MAX_VERSION 
+        && IsCharNumeric(szVersion[VersionCharCount]) 
+        && VersionCharCount < VersionLength)
+    {
+        for (; IsCharNumeric(szVersion[VersionCharCount]) && VersionCharCount < VersionLength; ++VersionCharCount)
+        {
+            szVersionSingleInt += szVersion[VersionCharCount];
+        }
+        if (szVersionSingleInt.IsEmpty())
+        {
+            bHasParsed = FALSE;
+            continue;
+        }
+        INT IntResult = StrToIntW(szVersionSingleInt.GetBuffer());
+        Version->arrVersion[Version->VersionSize] = IntResult;
+        ++Version->VersionSize;
+        szVersionSingleInt.Empty();
+        ++VersionCharCount;
+    }
+
+    if (IsCharAlphaW(szVersion[VersionCharCount]))
+    {
+        Version->cVersionSuffix = szVersion[VersionCharCount];
+    }
+    else
+        Version->cVersionSuffix = NULL;
+    return bHasParsed;
+}
+
+//Compares versions 
+//In:   Zero terminated strings of versions
+//Out:  TRUE if first is bigger than second, FALSE if else
+BOOL
+CompareVersionsStrings(_In_z_ LPCWSTR sczVersionLeft, _In_z_ LPCWSTR sczVersionRight)
+{
+    VERSION_INFO LeftVersion, RightVersion;
+
+    if (!ParseVersion(sczVersionLeft, &LeftVersion)
+        || !ParseVersion(sczVersionRight, &RightVersion))
+    {
+        return FALSE;
+    }
+
+    return CompareVersions(&LeftVersion, &RightVersion);  
+}
+
+BOOL
+CompareVersions(_In_ PVERSION_INFO LeftVersion, _In_ PVERSION_INFO RightVersion)
+{
+    //CURRENT 
+    if (!LeftVersion->VersionSize || !RightVersion->VersionSize)
+    {
+        return FALSE;
+    }
+    //1.2.3 > 1.2
+    INT SizeDiff = LeftVersion->VersionSize - RightVersion->VersionSize;
+    if (SizeDiff > 0)
+    {
+        return TRUE;
+    }
+    if (SizeDiff < 0)
+    {
+        return FALSE;
+    }
+    //2.0.0 > 1.9.9
+    for (INT i = 0; i < LeftVersion->VersionSize && i < RightVersion->VersionSize && i < MAX_VERSION; ++i)
+    {
+        if (LeftVersion->arrVersion[i] > RightVersion->arrVersion[i])
+        {
+            return TRUE;
+        }
+        if (LeftVersion->arrVersion[i] < RightVersion->arrVersion[i])
+        {
+            return FALSE;
+        }
+    }
+    //1.2.3b > 1.2.3
+    if (LeftVersion->cVersionSuffix > RightVersion->cVersionSuffix)
+    {
+        return TRUE;
+    }
+
+    return FALSE;
 }
\ No newline at end of file