Browse Source

But fix: On Windows 11, Windows 10 version was logged

As part of refactoring, calling GetProductInfo unconditionally as it should be supported on all Windows version we support
Also querying ProductName from 64-bit key, as JCL does (does not help with Windows 11 though)

Source commit: f5f6c075df730b9e5283d6490647bf0c11b23629
Martin Prikryl 10 months ago
parent
commit
b0f03a87ba
6 changed files with 63 additions and 58 deletions
  1. 1 9
      source/WinSCP.cpp
  2. 59 25
      source/core/Common.cpp
  3. 2 1
      source/core/Common.h
  4. 0 19
      source/windows/Tools.cpp
  5. 0 1
      source/windows/Tools.h
  6. 1 3
      source/windows/WinMain.cpp

+ 1 - 9
source/WinSCP.cpp

@@ -46,15 +46,7 @@ WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
     AppLogFmt(L"Mouse wheel: %s, msg: %d, scroll lines: %d", (BooleanToEngStr(Mouse->WheelPresent), int(Mouse->RegWheelMessage), Mouse->WheelScrollLines));
     AppLogFmt(L"ACP: %d", (static_cast<int>(GetACP())));
     AppLogFmt(L"Win32 platform: %d", (Win32Platform()));
-    DWORD Type;
-    if (GetWindowsProductType(Type))
-    {
-      AppLogFmt(L"Windows product type: %x", (static_cast<int>(Type)));
-    }
-    else
-    {
-      AppLog(L"No Windows product type");
-    }
+    AppLogFmt(L"Windows product type: %x", (static_cast<int>(GetWindowsProductType())));
     AppLogFmt(L"Win64: %s", (BooleanToEngStr(IsWin64())));
     AddStartupSequence(L"T");
 

+ 59 - 25
source/core/Common.cpp

@@ -3010,6 +3010,25 @@ void AddToShellFileListCommandLine(UnicodeString & List, const UnicodeString & V
   AddToList(List, Arg, L" ");
 }
 //---------------------------------------------------------------------------
+bool IsWin64()
+{
+  static int Result = -1;
+  if (Result < 0)
+  {
+    Result = 0;
+    BOOL Wow64Process = FALSE;
+    if (IsWow64Process(GetCurrentProcess(), &Wow64Process))
+    {
+      if (Wow64Process)
+      {
+        Result = 1;
+      }
+    }
+  }
+
+  return (Result > 0);
+}
+//---------------------------------------------------------------------------
 bool __fastcall IsWin7()
 {
   return CheckWin32Version(6, 1);
@@ -3121,43 +3140,58 @@ UnicodeString __fastcall DefaultEncodingName()
   return ADefaultEncodingName;
 }
 //---------------------------------------------------------------------------
-bool _fastcall GetWindowsProductType(DWORD & Type)
+DWORD GetWindowsProductType()
 {
-  bool Result;
-  HINSTANCE Kernel32 = GetModuleHandle(kernel32);
-  typedef BOOL WINAPI (* TGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
-  TGetProductInfo GetProductInfo =
-      (TGetProductInfo)GetProcAddress(Kernel32, "GetProductInfo");
-  if (GetProductInfo == NULL)
-  {
-    Result = false;
-  }
-  else
-  {
-    GetProductInfo(Win32MajorVersion(), Win32MinorVersion(), 0, 0, &Type);
-    Result = true;
-  }
+  DWORD Result = 0;
+  GetProductInfo(Win32MajorVersion(), Win32MinorVersion(), 0, 0, &Result);
   return Result;
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall WindowsProductName()
 {
   UnicodeString Result;
-  TRegistry * Registry = new TRegistry(KEY_READ);
-  try
+  // On Windows 11 "ProductName" is still "Windows 10"
+  if (IsWin11())
   {
-    Registry->RootKey = HKEY_LOCAL_MACHINE;
-    if (Registry->OpenKey(L"SOFTWARE", false) &&
-        Registry->OpenKey(L"Microsoft", false) &&
-        Registry->OpenKey(L"Windows NT", false) &&
-        Registry->OpenKey(L"CurrentVersion", false))
+    Result = L"Windows 11"; // fallback value
+
+    HMODULE WinBrandLib = LoadLibrary(L"winbrand.dll");
+    if (WinBrandLib != NULL)
     {
-      Result = Registry->ReadString(L"ProductName");
+      typedef LPWSTR (* TBrandingFormatString)(LPCWSTR);
+      TBrandingFormatString BrandingFormatString =
+        reinterpret_cast<TBrandingFormatString>(GetProcAddress(WinBrandLib, "BrandingFormatString"));
+      if (BrandingFormatString != NULL)
+      {
+        LPWSTR Brand = BrandingFormatString(L"%WINDOWS_LONG%");
+        if (Brand != NULL)
+        {
+          Result = Brand;
+          GlobalFree(Brand);
+        }
+      }
+      FreeLibrary(WinBrandLib);
     }
-    delete Registry;
   }
-  catch(...)
+  else
   {
+    try
+    {
+      // JCL GetWindowsProductName claims that reading 64-bit key gets correct values, but on Windows 11, neither works
+      unsigned int Access = KEY_READ | FLAGMASK(IsWin64(), KEY_WOW64_64KEY);
+      std::unique_ptr<TRegistry> Registry(new TRegistry(Access));
+      Registry->RootKey = HKEY_LOCAL_MACHINE;
+      if (Registry->OpenKey(L"SOFTWARE", false) &&
+          Registry->OpenKey(L"Microsoft", false) &&
+          Registry->OpenKey(L"Windows NT", false) &&
+          Registry->OpenKey(L"CurrentVersion", false))
+      {
+        Result = Registry->ReadString(L"ProductName");
+      }
+    }
+    catch(...)
+    {
+    }
   }
   return Result;
 }

+ 2 - 1
source/core/Common.h

@@ -145,6 +145,7 @@ bool __fastcall CutTokenEx(UnicodeString & Str, UnicodeString & Token,
   UnicodeString * RawToken = NULL, UnicodeString * Separator = NULL);
 void __fastcall AddToList(UnicodeString & List, const UnicodeString & Value, const UnicodeString & Delimiter);
 void AddToShellFileListCommandLine(UnicodeString & List, const UnicodeString & Value);
+bool IsWin64();
 bool __fastcall IsWin7();
 bool __fastcall IsWin8();
 bool __fastcall IsWin10();
@@ -164,7 +165,7 @@ UnicodeString __fastcall SizeToStr(__int64 Size);
 LCID __fastcall GetDefaultLCID();
 UnicodeString __fastcall DefaultEncodingName();
 UnicodeString __fastcall WindowsProductName();
-bool _fastcall GetWindowsProductType(DWORD & Type);
+DWORD GetWindowsProductType();
 UnicodeString __fastcall WindowsVersion();
 UnicodeString __fastcall WindowsVersionLong();
 bool __fastcall IsDirectoryWriteable(const UnicodeString & Path);

+ 0 - 19
source/windows/Tools.cpp

@@ -1187,25 +1187,6 @@ void __fastcall CopyToClipboard(TStrings * Strings)
   }
 }
 //---------------------------------------------------------------------------
-bool __fastcall IsWin64()
-{
-  static int Result = -1;
-  if (Result < 0)
-  {
-    Result = 0;
-    BOOL Wow64Process = FALSE;
-    if (IsWow64Process(GetCurrentProcess(), &Wow64Process))
-    {
-      if (Wow64Process)
-      {
-        Result = 1;
-      }
-    }
-  }
-
-  return (Result > 0);
-}
-//---------------------------------------------------------------------------
 static void __fastcall AcquireShutDownPrivileges()
 {
   HANDLE Token;

+ 0 - 1
source/windows/Tools.h

@@ -66,7 +66,6 @@ bool __fastcall FontDialog(TFont * Font);
 bool __fastcall SaveDialog(UnicodeString Title, UnicodeString Filter,
   UnicodeString DefaultExt, UnicodeString & FileName);
 bool __fastcall AutodetectProxy(UnicodeString & HostName, int & PortNumber);
-bool __fastcall IsWin64();
 void __fastcall CopyToClipboard(UnicodeString Text);
 void __fastcall CopyToClipboard(TStrings * Strings);
 void __fastcall ShutDownWindows();

+ 1 - 3
source/windows/WinMain.cpp

@@ -535,9 +535,7 @@ void __fastcall UpdateStaticUsage()
 
   Configuration->Usage->Set(L"WindowsVersion", (WindowsVersionLong()));
   Configuration->Usage->Set(L"WindowsProductName", (WindowsProductName()));
-  DWORD Type;
-  GetWindowsProductType(Type);
-  Configuration->Usage->Set(L"WindowsProductType", (static_cast<int>(Type)));
+  Configuration->Usage->Set(L"WindowsProductType", (static_cast<int>(GetWindowsProductType())));
   Configuration->Usage->Set(L"Windows64", IsWin64());
   Configuration->Usage->Set(L"UWP", IsUWP());
   Configuration->Usage->Set(L"PackageName", GetPackageName());