Compare commits

...

105 Commits

Author SHA1 Message Date
a98ef46c5d MSI: Squash INSTALLLEVEL 1,2,3 → 1
Our default used to be INSTALLLEVEL 3, but Microsoft default is 1. By
overriding Microsoft default in Property table, we override the
INSTALLLEVEL user might have specified on the command line.

Since our installations no longer use "Minimal/Typical/Full", we may
squash "Minimal" and "Typical" into Minimal.

Signed-off-by: Simon Rozman <simon@rozman.si>
2025-03-13 14:15:04 +01:00
22c335242b Switch from phased-out MIDL_PASS to __midl
Signed-off-by: Simon Rozman <simon@rozman.si>
2024-03-11 15:51:56 +01:00
46495773c2 Move keypair source out of source folder
This allows us to use `git clean` without risking to loose keypair,
since it is typically .gitignored and not included in the Git
repository.

Signed-off-by: Simon Rozman <simon@rozman.si>
2022-10-05 19:16:05 +02:00
76124075fc Update translation templates
Signed-off-by: Simon Rozman <simon@rozman.si>
2022-02-17 14:09:54 +01:00
214dfc2017 MSI: Discontinue prefixed row IDs in tables
humanSimon, is this really you? 😉

Signed-off-by: Simon Rozman <simon@rozman.si>
2022-02-15 13:08:31 +01:00
a2441233b4 Update Copyright year
Signed-off-by: Simon Rozman <simon@rozman.si>
2022-01-07 11:36:26 +01:00
0ba186c984 Switch to SPDX license notice
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 08:37:10 +01:00
8affb4c95a Cleanup project files
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 08:37:10 +01:00
5b1c1fc23d Resolve charset .idtx/.idt confusion
NMake inline files are always created using ACP. The "1252" in the .idtx
header has no effect on this. However, we must encode the .idt files
using correct charset/codepage regardless the ACP being used on the
building machine.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-19 14:19:58 +01:00
8bf3810032 Silence Code Analysis warnings about unscoped enums
wxWidgets is using unscoped enums and should continue so for backward
compatibility.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-15 11:49:49 +01:00
625549838e Convert asserts to proper checks and log error
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 16:12:29 +02:00
165894247e Cleanup UPDATER_API
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-30 12:03:21 +02:00
924971bb3b Copyright: Bump year
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-25 08:33:26 +01:00
e3c9b3aa62 Add copyright colophon to .rc files
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 11:10:07 +01:00
2084188819 Add UTF-8 BOM markers
MSVC needs them to use correct charset when Language for non-Unicode
programs is set to Windows-1252 or anything different than UTF-8.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 10:55:52 +01:00
67124a8434 Enable Windows 10 ARM64 support
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-14 23:57:35 +01:00
dc4cc1b22e Makefile: Optimize building
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-03 14:44:29 +01:00
8baf612a6c Switch to SHA-256 (phase 2)
We switched to a new update catalog file that is using SHA-256 hashes
and signatures.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:47:43 +01:00
e7617949b3 Reapply "Unify component GUIDs across platforms"
This reverts commit fbbf89ba55004c6b94b5f5b3d149d0176ca83477.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:21:24 +01:00
5c06968d76 Reapply "Unify component GUIDs across languages"
This reverts commit 278cce1b4c17c8da9e615bae986bc9fe6eb670b3.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:21:24 +01:00
877c2cc357 Switch to SHA-256 (phase 1)
Updater will treat all hashes as SHA-256 when checking for updates in
the new catalog - the future releases.

While we keep hashing and signing the old catalog file using SHA-1 - the
past releases.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:21:19 +01:00
07d891aa37 Fix parameter descriptions
wxString doesn't convert to const char * correctly.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 12:54:33 +01:00
fbbf89ba55 Revert "Unify component GUIDs across platforms"
This reverts commit 4cd1196d14d17407c561a2be461f3a93432c84e6.

Due to Active Setup StubPath bug in already deployed MSI packages we can
fix automatically using minor update only, we cannot change the
component GUIDs just yet.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-24 13:26:55 +01:00
278cce1b4c Revert "Unify component GUIDs across languages"
This reverts commit caff6295344c8e151c80a115012ec83f66b860d6.

Due to Active Setup StubPath bug in already deployed MSI packages we can
fix automatically using minor update only, we cannot change the
component GUIDs just yet.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-24 13:26:34 +01:00
349c42fe57 Fix flapping update process
The m_ok variable was not initialized, and set to true in case of
successful initialization - it depended on pure luck.

Since debug versions usually initialize stack and heap allocated memory
(to 0xCD or something like that), this explains why update check was
failing silently and randomly in release versions.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 13:18:13 +01:00
51c7ed11c0 Address some additional code analysis warnings
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 13:08:41 +01:00
4846cdbc9f Remove excessive wxExtend dependency to parallelize building
Updater is static library and does not require linking wxExtend library.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 13:07:17 +01:00
82e69f072d Fix WinMain annotation to match the official one
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 12:35:55 +01:00
e2cf7d09f8 Make wxUpdCheckThread::wxResult scoped enum
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 12:35:25 +01:00
de9535b961 Suppress wxWidgets code analysis warnings
Rather than addressing numerous code analysis warnings Microsoft Visual
Studio 2019 reports for wxWidgets upstream, disable code analysis for
the time being. But only for the wxWidgets part. We still want to know
what the code analysis has to say about our code.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-12 12:20:44 +01:00
154cd798e4 Extend copyright year
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 15:38:53 +01:00
4cd1196d14 Unify component GUIDs across platforms
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 12:16:20 +01:00
caff629534 Unify component GUIDs across languages
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 12:08:14 +01:00
e7954e7c73 MSI: Automate language-dependent folder property names
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 11:55:37 +01:00
e6c51e923f Make enum wxHexDecodeMode scoped
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 14:59:12 +01:00
62a7d4e715 Rename stdafx.h to pch.h
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 14:10:17 +01:00
d885fd9a9a Unify platform designations
.sln uses the same as .vcxproj files

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 13:49:29 +01:00
5ae6dd56c2 Switch to Visual Studio 2019
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-19 11:50:06 +02:00
6fbcede83b Switch to Transifex project for localization 2018-09-19 12:02:34 +02:00
c08b40f2dc Stop using "<>" in translations
This confuses Transifex to believe "<input file>" is some kind of
markup.
2018-09-19 10:51:38 +02:00
7d04dc2052 Update translation template 2018-09-19 09:06:57 +02:00
5bfe66bfbf Fix invalid filename report on error 2018-09-17 09:37:23 +02:00
c6b0ebd28e Add missing Updater public key to UpdCheck.exe resources 2018-09-17 09:05:46 +02:00
10c55e4ce9 Check HTTP status 200 before parsing the response 2018-09-17 08:58:02 +02:00
38238d1183 Extend copyright year 2018-09-07 23:51:15 +02:00
ab2ff99b0d Add UPDATER_BIN_DIR check 2018-09-07 23:21:14 +02:00
dcdbaa6483 Make Updater static library 2018-09-07 22:35:35 +02:00
33428a913b Fix platform suffixes 2018-09-07 21:16:16 +02:00
78b6f629b7 Fix down-casting 2018-09-07 20:46:59 +02:00
514bcfc8ec Introduce ARM64 support 2018-09-07 14:20:19 +02:00
fdf187cf6d Fix down-casting 2018-09-07 14:18:49 +02:00
89d610a306 Switch to Visual Studio 2017 2018-09-07 14:04:56 +02:00
d432b767bb Fix down-casting 2018-09-07 14:03:24 +02:00
abc8e3914a Remove MFC dependency 2018-09-07 14:01:58 +02:00
c160d4b9eb Use local wxWidget DLLs 2018-09-03 10:00:08 +02:00
c9e24ccca9 Update wxExtend sub-module 2018-09-01 06:47:59 +02:00
9f119e3182 Synchronize MSI download User-Agent 2017-12-22 13:03:46 +01:00
c25cf09b9a Copyright extended to 2017 2017-04-18 14:03:35 +02:00
5e6427ab00 Required package language determined correctly now 2016-10-18 12:56:01 +02:00
3bad9473ae User-Agent header includes application name now 2016-10-14 08:46:42 +02:00
598f0b7963 Updating task triggering adjusted to workaround Windows 10 Task Scheduler 0x800710e0 bug 2016-10-13 12:32:16 +02:00
2ca5b4d9d1 Independent Updater version replaced with product version for correct versioning of DLL and EXE files when updating product 2016-10-11 13:13:44 +02:00
a9a04f8df3 MSI module Makefile simplified 2016-10-11 11:12:43 +02:00
3cab0a45a9 Locale is set using wxExtend's wxInitializeLocale() helper function now 2016-10-05 12:29:40 +02:00
4baae59fd5 Translations update 2016-10-05 10:54:25 +02:00
365c675780 rcxgettext.exe dependency eliminated 2016-09-19 10:45:50 +02:00
83298f96da Adaptation to MSIBuild updates
- Source file English "en_US" instead of generic "En" now
- MSIBUILD_LANG_PO merged to LANG
2016-09-19 09:51:06 +02:00
07c11ef392 Generation of localized IDT files simplified 2016-09-06 16:40:15 +02:00
6434a51171 Silent installations should not restart computer any more 2016-07-22 01:12:18 +02:00
429cab9e20 wxExtend library referencing updated 2016-07-18 08:51:10 +02:00
bec0e13581 Support for Russian localization introduced 2016-07-14 18:07:13 +02:00
55548e1059 Custom Abort() method for aborting foreground update check added 2016-06-02 20:29:33 +02:00
7271221bd4 Slovenian translation update 2016-06-02 20:28:59 +02:00
54846632f3 When product is up-to-date the Updater saves metadata as well, to indicate up-to-dateness on next check 2016-05-24 23:18:10 +02:00
9657f9ae9c Odd warning about "/.." removed 2016-05-24 23:07:26 +02:00
40fd616e5d Temporary repository catalog file is now removed after no longer needed 2016-05-24 22:12:46 +02:00
71f66668bf Repository catalog is downloaded to an intermediate file as wxXmlDocument failed to load it from wxInputStream directly 2016-05-24 22:07:52 +02:00
dfef267ac6 Log messages updated 2016-05-24 22:06:17 +02:00
66b2934da8 wxUpdCheckThread::DownloadUpdatePackage() does the file-existence check before calculating hash, to avoid unnecessary warning in the log 2016-05-24 21:45:44 +02:00
ff28695e80 wxUpdCheckThread::LaunchUpdate() method extended 2016-05-24 21:44:43 +02:00
bf28f7f55e Auto-pointers introduced to reduce possible memory-leak scenarios 2016-05-24 21:43:32 +02:00
986deb3fef Text update 2016-05-24 21:40:49 +02:00
529bd00da5 Update check logic moved to standalone DLL to make it reusable 2016-05-24 16:50:36 +02:00
54e64515d4 German and Russian translation stub added 2016-05-13 20:04:46 +02:00
f1a3ae730a Update package file download sets User-Agent header too now 2016-04-04 15:36:14 +02:00
e88f1b429f UpdPublish utility added 2016-04-01 19:19:39 +02:00
348e4a461f Hash calculation uses wxCryptoHash::HashFile() method now. 2016-04-01 19:19:14 +02:00
c425de942c Aesthetic modifications 2016-04-01 14:46:13 +02:00
4a391058bd Translations updated 2016-04-01 14:23:49 +02:00
c53bd0285f Cleanup and reorganization 2016-04-01 13:28:05 +02:00
02b080c3ef Cleanup 2016-04-01 13:24:20 +02:00
5f708a6d42 Stale stdex dependencies removed 2016-04-01 13:24:07 +02:00
e8a0d13541 MSIBuildCfg.mak moved 2016-03-30 15:07:07 +02:00
28b00d37dc Friendlier parameter names 2016-03-30 13:16:47 +02:00
840f1bce06 MSIBuild support added 2016-03-30 11:37:43 +02:00
64ca04f468 UpdCheck no longer requires admin-elevation as it is not modifying system state itself. That's msiexec.exe spawned process' job. 2016-03-30 09:57:19 +02:00
a5f71f6965 Update package cleanup added 2016-03-29 15:32:12 +02:00
ada90646ac Download and installation of update packages added 2016-03-29 15:15:36 +02:00
4ecd6260aa Hash reading issue fixed 2016-03-29 15:15:06 +02:00
7410c6e611 Output logging changed to use standard C++ stream now 2016-03-29 15:14:21 +02:00
bdf071f5d7 Support for multiple package URLs added
Packages are verified against SHA1 hash instead of signature now
2016-03-29 12:38:07 +02:00
453a1c08e2 User-Agent header added to Updater requests 2016-03-29 11:14:18 +02:00
8bc1d0157e CachePath removed 2016-03-25 13:24:58 +01:00
e31849680f Merge branch 'CachePath' 2016-03-25 13:23:52 +01:00
6e9f1f2c4a Copyright notice added 2016-03-25 13:15:16 +01:00
63 changed files with 2863 additions and 790 deletions

5
.gitignore vendored
View File

@ -1,6 +1,3 @@
/*.opensdf /.vs
/*.sdf
/*.suo
/ipch
*.user *.user
temp temp

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright © 2016-2022 Amebis
KEY_DIR=..\include KEY_DIR=..\include
###################################################################### ######################################################################
# Main targets # Main targets
###################################################################### ######################################################################
@ -15,6 +19,7 @@ Clean ::
# Folder creation # Folder creation
###################################################################### ######################################################################
"$(APPDATA)\Updater" \
"$(KEY_DIR)" : "$(KEY_DIR)" :
if not exist $@ md $@ if not exist $@ md $@
@ -24,20 +29,21 @@ Clean ::
###################################################################### ######################################################################
GenRSAKeypair :: \ GenRSAKeypair :: \
"$(APPDATA)\Updater" \
"$(KEY_DIR)" \ "$(KEY_DIR)" \
"$(KEY_DIR)\UpdaterKeyPrivate.bin" \ "$(KEY_DIR)\UpdaterKeyPrivate.bin" \
"$(KEY_DIR)\UpdaterKeyPublic.bin" "$(KEY_DIR)\UpdaterKeyPublic.bin"
"$(KEY_DIR)\UpdaterKeypair.txt" : "$(APPDATA)\Updater\Keypair.txt" :
openssl.exe genrsa -out $@ 4096 openssl.exe genrsa -out $@ 4096
"$(KEY_DIR)\UpdaterKeyPrivate.bin" : "$(KEY_DIR)\UpdaterKeypair.txt" "$(KEY_DIR)\UpdaterKeyPrivate.bin" : "$(APPDATA)\Updater\Keypair.txt"
if exist $@ del /f /q $@ if exist $@ del /f /q $@
if exist "$(@:"=).tmp" del /f /q "$(@:"=).tmp" if exist "$(@:"=).tmp" del /f /q "$(@:"=).tmp"
openssl.exe rsa -in $** -inform PEM -outform DER -out "$(@:"=).tmp" openssl.exe rsa -in $** -inform PEM -outform DER -out "$(@:"=).tmp"
move /y "$(@:"=).tmp" $@ > NUL move /y "$(@:"=).tmp" $@ > NUL
"$(KEY_DIR)\UpdaterKeyPublic.bin" : "$(KEY_DIR)\UpdaterKeypair.txt" "$(KEY_DIR)\UpdaterKeyPublic.bin" : "$(APPDATA)\Updater\Keypair.txt"
if exist $@ del /f /q $@ if exist $@ del /f /q $@
if exist "$(@:"=).tmp" del /f /q "$(@:"=).tmp" if exist "$(@:"=).tmp" del /f /q "$(@:"=).tmp"
openssl.exe rsa -in $** -inform PEM -outform DER -out "$(@:"=).tmp" -pubout openssl.exe rsa -in $** -inform PEM -outform DER -out "$(@:"=).tmp" -pubout

9
UpdCheck/MSIBuild/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
/*-1.idt
/*-2.idt
/*-2.idtx
/*.Binary-1
/*.Binary-2
/*.Icon-1
/*.Icon-2
/*.lst
/*.msm

BIN
UpdCheck/MSIBuild/Makefile Normal file

Binary file not shown.

View File

@ -1,25 +1,11 @@
/* /*
Copyright 2016 Amebis SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#define IDR_KEY_PUBLIC 1 #define IDR_KEY_PUBLIC 1
#if !defined(RC_INVOKED) && !defined(MIDL_PASS) #if !defined(RC_INVOKED) && !defined(__midl)
#endif // !defined(RC_INVOKED) && !defined(MIDL_PASS) #endif // !defined(RC_INVOKED) && !defined(__midl)

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\lib\wxExtend\include;..\..\lib\stdex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -9,6 +13,10 @@
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -20,88 +28,67 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}</ProjectGuid> <ProjectGuid>{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UpdCheck</RootNamespace> <RootNamespace>UpdCheck</RootNamespace>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Label="Configuration" Condition="'$(Platform)'=='ARM64'">
<ConfigurationType>Application</ConfigurationType> <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings" />
</ImportGroup> <ImportGroup Label="PropertySheets">
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\Win32.props" /> <Import Project="..\..\include\$(Platform).props" />
<Import Project="..\..\include\Debug.props" /> <Import Project="..\..\include\$(Configuration).props" />
<Import Project="UpdCheck.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\x64.props" />
<Import Project="..\..\include\Debug.props" />
<Import Project="UpdCheck.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\Win32.props" />
<Import Project="..\..\include\Release.props" />
<Import Project="UpdCheck.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\x64.props" />
<Import Project="..\..\include\Release.props" />
<Import Project="UpdCheck.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\Updater\include;..\..\lib\wxExtend\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="UpdCheck.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="UpdCheck.rc" /> <ResourceCompile Include="UpdCheck.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<POCompile Include="locale\de_DE.po" />
<POCompile Include="locale\ru_RU.po" />
<POCompile Include="locale\sl_SI.po" /> <POCompile Include="locale\sl_SI.po" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="locale\sl_SI.po" /> <None Include="locale\UpdCheck.pot" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\lib\wxExtend\build\wxExtend.vcxproj"> <ProjectReference Include="..\..\lib\wxExtend\build\wxExtendLib.vcxproj">
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project> <Project>{D3E29951-D9F5-486D-A167-20AE8E90B1FA}</Project>
</ProjectReference>
<ProjectReference Include="..\Updater\build\Updater.vcxproj">
<Project>{990d8cf9-4457-4dc0-aa18-4968ef434741}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets" />
</ImportGroup>
</Project> </Project>

View File

@ -22,15 +22,12 @@
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="stdafx.cpp"> <ClCompile Include="pch.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h"> <ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UpdCheck.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@ -40,7 +37,18 @@
</ResourceCompile> </ResourceCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="locale\sl_SI.po"> <POCompile Include="locale\de_DE.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\ru_RU.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
<ItemGroup>
<None Include="locale\UpdCheck.pot">
<Filter>Resource Files\Localization</Filter> <Filter>Resource Files\Localization</Filter>
</None> </None>
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,63 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: UpdCheck\n"
"POT-Creation-Date: 2022-02-17 13:30+0100\n"
"PO-Revision-Date: 2016-03-30 11:37+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: MSIBuild/en_US.ARM64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.ARM64.Release.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Automatic Updating"
msgstr ""
#: MSIBuild/en_US.ARM64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.ARM64.Release.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Task for background product updating"
msgstr ""
#: MSIBuild/en_US.ARM64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.ARM64.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[SimpleProductName] Update"
msgstr ""
#: MSIBuild/en_US.ARM64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.ARM64.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[Manufacturer]"
msgstr ""
#: MSIBuild/en_US.ARM64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.ARM64.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "Regularly checks for program updates, downloads, and installs them"
msgstr ""

54
UpdCheck/locale/de_DE.po Normal file
View File

@ -0,0 +1,54 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: UpdCheck\n"
"POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-03-30 11:37+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: German (Germany) (https://www.transifex.com/amebis/teams/91597/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Automatic Updating"
msgstr ""
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Task for background product updating"
msgstr ""
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[SimpleProductName] Update"
msgstr ""
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[Manufacturer]"
msgstr "[Manufacturer]"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "Regularly checks for program updates, downloads, and installs them"
msgstr ""

55
UpdCheck/locale/ru_RU.po Normal file
View File

@ -0,0 +1,55 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: UpdCheck\n"
"POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-03-30 11:37+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Russian (Russia) (https://www.transifex.com/amebis/teams/91597/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Automatic Updating"
msgstr "Автоматическое обновление"
#: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Task for background product updating"
msgstr "Задача фонового обновления продукта"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[SimpleProductName] Update"
msgstr "[SimpleProductName] Обновление"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[Manufacturer]"
msgstr "[Manufacturer]"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "Regularly checks for program updates, downloads, and installs them"
msgstr ""
"Регулярно проверяет, доступны ли обновления программы, и устанавливает их."

View File

@ -1,30 +1,54 @@
#
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: UpdCheck\n" "Project-Id-Version: UpdCheck\n"
"POT-Creation-Date: 2016-03-15 10:56+0100\n" "POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-03-15 10:57+0100\n" "PO-Revision-Date: 2016-03-30 11:37+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Slovenian (Slovenia) (https://www.transifex.com/amebis/teams/91597/sl_SI/)\n"
"Language: sl_SI\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n" "Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n" "X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n" "X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:40 #: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
msgid "Show this help message" #: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
msgstr "Pokaži to sporočilo pomoči" #: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Automatic Updating"
msgstr "Samodejno posodabljanje"
#: main.cpp:41 #: MSIBuild/en_US.Win32.Debug.Feature-2.idtx:4
msgid "input file" #: MSIBuild/en_US.Win32.Release.Feature-2.idtx:4
msgstr "vhodna datoteka" #: MSIBuild/en_US.x64.Debug.Feature-2.idtx:4
#: MSIBuild/en_US.x64.Release.Feature-2.idtx:4
msgid "Task for background product updating"
msgstr "Opravilo za samodejno posodabljanje izdelka"
#: main.cpp:42 #: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
msgid "output file" #: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
msgstr "izhodna datoteka" #: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[SimpleProductName] Update"
msgstr "Posodabljanje [SimpleProductName]"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "[Manufacturer]"
msgstr "[Manufacturer]"
#: MSIBuild/en_US.Win32.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.Win32.Release.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Debug.ScheduledTask-2.idtx:4
#: MSIBuild/en_US.x64.Release.ScheduledTask-2.idtx:4
msgid "Regularly checks for program updates, downloads, and installs them"
msgstr "Redno preverja za posodobitve programa, prenese in jih namesti"

View File

@ -1,300 +1,54 @@
/* /*
Copyright 2016 Amebis SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "stdafx.h" #include "pch.h"
///
/// Module initializer
///
class wxUpdCheckInitializer : public wxInitializer
{
protected:
FILE *m_pLogFile;
public:
wxConfig m_config;
wxString m_path;
wxLocale m_locale;
public:
wxUpdCheckInitializer();
virtual ~wxUpdCheckInitializer();
};
wxUpdCheckInitializer::wxUpdCheckInitializer() :
m_pLogFile(NULL),
m_config(wxT(UPDATER_CFG_APPLICATION) wxT("\\Updater"), wxT(UPDATER_CFG_VENDOR)),
wxInitializer()
{
if (wxInitializer::IsOk()) {
// Set desired locale.
wxLanguage language = (wxLanguage)m_config.Read(wxT("Language"), wxLANGUAGE_DEFAULT);
if (wxLocale::IsAvailable(language))
wxVERIFY(m_locale.Init(language));
if (!m_config.Read(wxT("CachePath"), &m_path))
m_path = wxFileName::GetTempDir();
if (!wxEndsWithPathSeparator(m_path))
m_path += wxFILE_SEP_PATH;
if (!wxDirExists(m_path))
wxMkdir(m_path);
m_pLogFile = fopen(m_path + wxT(UPDATER_LOG_FILE), "w+");
if (m_pLogFile)
delete wxLog::SetActiveTarget(new wxLogStderr(m_pLogFile));
} else
m_pLogFile = NULL;
}
wxUpdCheckInitializer::~wxUpdCheckInitializer()
{
if (m_pLogFile != NULL) {
delete wxLog::SetActiveTarget(NULL);
fclose(m_pLogFile);
}
}
/// ///
/// Main function /// Main function
/// ///
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{ {
wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program"); wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");
// Initialize wxWidgets. // Initialize wxWidgets.
wxUpdCheckInitializer initializer; wxInitializer initializer;
if (!initializer.IsOk()) if (!initializer.IsOk())
return -1; return -1;
// Create RSA AES cryptographic context. // Initialize configuration.
wxCryptoSessionRSAAES cs; wxConfigBase *cfgPrev = wxConfigBase::Set(new wxConfig(wxT(PRODUCT_CFG_APPLICATION), wxT(PRODUCT_CFG_VENDOR)));
if (!cs.IsOk()) if (cfgPrev) wxDELETE(cfgPrev);
return -1;
// Import public key. // Initialize locale.
wxCryptoKey ck; wxLocale locale;
{ #pragma warning(suppress: 26812) // wxLanguage is unscoped
HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(IDR_KEY_PUBLIC), RT_RCDATA); wxLanguage lang_ui;
wxASSERT_MSG(res, wxT("public key not found")); if (wxInitializeLocale(locale, &lang_ui)) {
HGLOBAL res_handle = ::LoadResource(NULL, res); // Do not add translation catalog, to keep log messages in English.
wxASSERT_MSG(res_handle, wxT("loading resource failed")); // Log files are for help-desk and should remain globally intelligible.
//wxVERIFY(locale.AddCatalog(wxT("Updater") wxT(wxExtendVersion)));
if (!ck.ImportPublic(cs, ::LockResource(res_handle), ::SizeofResource(NULL, res)))
return -1;
} }
long val; // Create output folder.
wxDateTime last_checked = initializer.m_config.Read(wxT("LastChecked"), &val) ? wxDateTime((time_t)val) : wxInvalidDateTime; wxString path(wxFileName::GetTempDir());
if (!wxEndsWithPathSeparator(path))
path += wxFILE_SEP_PATH;
if (!wxDirExists(path))
wxMkdir(path);
for (const wxChar *server = wxT(UPDATER_HTTP_SERVER); server[0]; server += wcslen(server) + 1) { // Prepare log file.
wxXmlDocument doc; wxFFile log_file(path + wxT("Updater-") wxT(PRODUCT_CFG_APPLICATION) wxT(".log"), wxT("wt"));
if (log_file.IsOpened())
delete wxLog::SetActiveTarget(new wxLogStderr(log_file.fp()));
wxLogStatus(wxT("Contacting repository at %s..."), server); wxUpdCheckThread worker(lang_ui == wxLANGUAGE_DEFAULT ? wxT("en_US") : wxLocale::GetLanguageCanonicalName(lang_ui));
const wxUpdCheckThread::wxResult res = worker.CheckForUpdate();
// Load repository database. switch (res) {
wxHTTP http; case wxUpdCheckThread::wxResult::UpdateAvailable: return worker.LaunchUpdate(NULL, true) ? 0 : 1;
if (last_checked.IsValid()) case wxUpdCheckThread::wxResult::UpToDate : return 0;
http.SetHeader(wxS("If-Modified-Since"), last_checked.Format(wxS("%a, %d %b %Y %H:%M:%S %z"))); default : return static_cast<int>(res);
if (!http.Connect(server, UPDATER_HTTP_PORT)) {
wxLogWarning(wxT("Error resolving %s server name."), server);
continue;
}
wxInputStream *httpStream = http.GetInputStream(wxS(UPDATER_HTTP_PATH));
if (!httpStream) {
if (http.GetResponse() == 304) {
wxLogStatus(wxT("Repository did not change since the last time..."));
return 0;
}
wxLogWarning(wxT("Error response received from server %s (port %u) requesting %s."), server, UPDATER_HTTP_PORT, UPDATER_HTTP_PATH);
continue;
}
wxLogStatus(wxT("Loading repository catalogue..."));
if (!doc.Load(*httpStream, "UTF-8", wxXMLDOC_KEEP_WHITESPACE_NODES)) {
wxLogWarning(wxT("Error loading repository catalogue."));
wxDELETE(httpStream);
http.Close();
continue;
}
wxDELETE(httpStream);
http.Close();
wxLogStatus(wxT("Verifying repository catalogue signature..."));
// Find the (first) signature.
wxXmlNode *document = doc.GetDocumentNode();
std::vector<BYTE> sig;
for (wxXmlNode *prolog = document->GetChildren(); prolog; prolog = prolog->GetNext()) {
if (prolog->GetType() == wxXML_COMMENT_NODE) {
wxString content = prolog->GetContent();
size_t content_len = content.length();
if (content_len >= _countof(wxS(UPDATER_SIGNATURE_MARK)) - 1 &&
memcmp((const wxStringCharType*)content, wxS(UPDATER_SIGNATURE_MARK), sizeof(wxStringCharType)*(_countof(wxS(UPDATER_SIGNATURE_MARK)) - 1)) == 0)
{
// Read the signature.
size_t signature_len = content_len - (_countof(wxS(UPDATER_SIGNATURE_MARK)) - 1);
sig.resize(wxBase64DecodedSize(signature_len));
size_t res = wxBase64Decode(sig.data(), sig.capacity(), content.Right(signature_len), wxBase64DecodeMode_SkipWS);
if (res != wxCONV_FAILED) {
sig.resize(res);
// Remove the signature as it is not a part of the validation check.
document->RemoveChild(prolog);
wxDELETE(prolog);
break;
} else
sig.clear();
}
}
}
if (sig.empty()) {
wxLogWarning(wxT("Signature not found in the repository catalogue."));
continue;
}
// Hash the content.
wxCryptoHashSHA1 ch(cs);
if (!wxXmlHashNode(ch, document))
continue;
// We have the hash, we have the signature, we have the public key. Now verify.
if (!wxCryptoVerifySignature(ch, sig.data(), sig.size(), ck)) {
wxLogWarning(wxT("Repository catalogue signature does not match its content, or signature verification failed."));
continue;
}
// The signature is correct. Now parse the file.
wxLogStatus(wxT("Parsing repository catalogue..."));
// Start processing the XML file.
wxXmlNode *elRoot = doc.GetRoot();
const wxString &nameRoot = elRoot->GetName();
if (nameRoot != wxT("Packages")) {
wxLogWarning(wxT("Invalid root element in repository catalogue (actual: %s, expected %s)."), nameRoot.c_str(), wxT("Packages"));
continue;
}
// Iterate over packages.
wxUint32 versionMax = 0;
wxString versionStrMax;
wxString urlMax;
std::vector<BYTE> sigMax;
for (wxXmlNode *elPackage = elRoot->GetChildren(); elPackage; elPackage = elPackage->GetNext()) {
if (elPackage->GetType() == wxXML_ELEMENT_NODE && elPackage->GetName() == wxT("Package")) {
// Get package version.
wxUint32 version = 0;
wxString versionStr;
for (wxXmlNode *elVersion = elPackage->GetChildren(); elVersion; elVersion = elVersion->GetNext()) {
if (elVersion->GetType() == wxXML_ELEMENT_NODE && elVersion->GetName() == wxT("Version")) {
for (wxXmlNode *elVersionNote = elVersion->GetChildren(); elVersionNote; elVersionNote = elVersionNote->GetNext()) {
if (elVersionNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elVersionNote->GetName();
if (name == wxT("hex"))
version = _tcstoul(elVersionNote->GetNodeContent(), NULL, 16);
else if (name == wxT("desc"))
versionStr = elVersionNote->GetNodeContent();
}
}
}
}
if (version <= UPDATER_PRODUCT_VERSION || version < versionMax) {
// This package is older than currently installed product or the superseeded package found.
continue;
}
// Get package download URL for our platform and language.
wxString platformId;
#if defined(__WINDOWS__)
platformId += wxT("win");
#endif
#if defined(_WIN64)
platformId += wxT("-amd64");
#else
platformId += wxT("-x86");
#endif
wxString languageId(initializer.m_locale.GetCanonicalName());
wxString url;
std::vector<BYTE> sig;
for (wxXmlNode *elDownloads = elPackage->GetChildren(); elDownloads; elDownloads = elDownloads->GetNext()) {
if (elDownloads->GetType() == wxXML_ELEMENT_NODE && elDownloads->GetName() == wxT("Downloads")) {
for (wxXmlNode *elPlatform = elDownloads->GetChildren(); elPlatform; elPlatform = elPlatform->GetNext()) {
if (elPlatform->GetType() == wxXML_ELEMENT_NODE) {
if (elPlatform->GetName() == wxT("Platform") && elPlatform->GetAttribute(wxT("id")) == platformId) {
// Get language.
for (wxXmlNode *elLocale = elPlatform->GetChildren(); elLocale; elLocale = elLocale->GetNext()) {
if (elLocale->GetType() == wxXML_ELEMENT_NODE && elLocale->GetName() == wxT("Localization") && elLocale->GetAttribute(wxT("lang")) == languageId) {
for (wxXmlNode *elLocaleNote = elLocale->GetChildren(); elLocaleNote; elLocaleNote = elLocaleNote->GetNext()) {
if (elLocaleNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elLocaleNote->GetName();
if (name == wxT("url"))
url = elLocaleNote->GetNodeContent();
else if (name == wxT("signature")) {
// Read the signature.
wxString content(elLocaleNote->GetNodeContent());
sig.resize(wxBase64DecodedSize(content.length()));
size_t res = wxBase64Decode(sig.data(), sig.capacity(), content, wxBase64DecodeMode_SkipWS);
if (res != wxCONV_FAILED)
sig.resize(res);
else
sig.clear();
}
}
}
}
}
}
}
}
}
}
if (url.IsEmpty() || sig.empty()) {
// This package is for different architecture and/or language.
// ... or missing URL and/or signature.
continue;
}
versionMax = version;
versionStrMax = versionStr;
urlMax = url;
sigMax = sig;
}
}
if (versionMax) {
wxLogMessage(wxT("Update package found (version: %s, URL: %s)."), versionStrMax.c_str(), urlMax.c_str());
} else
wxLogStatus(wxT("Update check complete. Your package is up to date."));
// Save the last check date.
initializer.m_config.Write(wxT("LastChecked"), (long)wxDateTime::GetTimeNow());
return 0;
} }
// No success.
return 1;
} }

6
UpdCheck/pch.cpp Normal file
View File

@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"

21
UpdCheck/pch.h Normal file
View File

@ -0,0 +1,21 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#include <Updater/chkthread.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/app.h>
#include <wx/config.h>
#include <wx/dir.h>
#include <wx/ffile.h>
#include <wx/filename.h>
#include <wx/init.h>
#include <wx/scopedptr.h>
#pragma warning(pop)
#include <wxex/common.h>

View File

@ -1,20 +0,0 @@
/*
Copyright 2016 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"

View File

@ -1,40 +0,0 @@
/*
Copyright 2016 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../include/UpdaterCfg.h"
#include "UpdCheck.h"
#include "../include/Updater.h"
#include <wx/app.h>
#include <wx/base64.h>
#include <wx/config.h>
#include <wx/datetime.h>
#include <wx/filename.h>
#include <wx/protocol/http.h>
#include <wx/xml/xml.h>
#include <wxex/common.h>
#include <wxex/crypto.h>
#include <wxex/xml.h>
#include <algorithm>
#include <vector>

9
UpdPublish/UpdPublish.h Normal file
View File

@ -0,0 +1,9 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#if !defined(RC_INVOKED) && !defined(__midl)
#endif // !defined(RC_INVOKED) && !defined(__midl)

BIN
UpdPublish/UpdPublish.rc Normal file

Binary file not shown.

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C5829278-D55E-41EB-B866-1E7D814694D1}</ProjectGuid>
<RootNamespace>UpdPublish</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Platform)'=='ARM64'">
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\$(Platform).props" />
<Import Project="..\..\include\$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\lib\wxExtend\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="UpdPublish.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\lib\wxExtend\build\wxExtendLib.vcxproj">
<Project>{D3E29951-D9F5-486D-A167-20AE8E90B1FA}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UpdPublish.rc" />
</ItemGroup>
<ItemGroup>
<POCompile Include="locale\de_DE.po" />
<POCompile Include="locale\ru_RU.po" />
<POCompile Include="locale\sl_SI.po" />
</ItemGroup>
<ItemGroup>
<None Include="locale\UpdPublish.pot" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Resource Files\Localization">
<UniqueIdentifier>{e43059ae-37ac-4b28-84fb-18d1b3972b30}</UniqueIdentifier>
<Extensions>po;pot</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UpdPublish.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UpdPublish.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<POCompile Include="locale\de_DE.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\ru_RU.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
<ItemGroup>
<None Include="locale\UpdPublish.pot">
<Filter>Resource Files\Localization</Filter>
</None>
</ItemGroup>
</Project>

1
UpdPublish/locale/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/*.mo

View File

@ -0,0 +1,46 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: UpdPublish\n"
"POT-Creation-Date: 2022-02-17 13:29+0100\n"
"PO-Revision-Date: 2018-09-19 10:47+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: main.cpp:113
msgid "Show this help message"
msgstr ""
#: main.cpp:114
msgid "Package file to calculate hash from"
msgstr ""
#: main.cpp:115
msgid "<input repository file>"
msgstr ""
#: main.cpp:116
msgid "<output repository file>"
msgstr ""
#: main.cpp:117
msgid "<platform>"
msgstr ""
#: main.cpp:118
msgid "<language>"
msgstr ""
#: main.cpp:119
msgid "<download URL>"
msgstr ""

View File

@ -0,0 +1,47 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2018
msgid ""
msgstr ""
"Project-Id-Version: UpdPublish\n"
"POT-Creation-Date: 2018-09-19 10:47+0200\n"
"PO-Revision-Date: 2018-09-19 10:47+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: German (Germany) (https://www.transifex.com/amebis/teams/91597/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:127
msgid "Show this help message"
msgstr "Zeige diesen Hilfstext"
#: main.cpp:128
msgid "Package file to calculate SHA-1 hash from"
msgstr ""
#: main.cpp:129
msgid "input repository file"
msgstr ""
#: main.cpp:130
msgid "output repository file"
msgstr ""
#: main.cpp:131
msgid "platform"
msgstr ""
#: main.cpp:132
msgid "language"
msgstr ""
#: main.cpp:133
msgid "download URL"
msgstr ""

View File

@ -0,0 +1,45 @@
#
msgid ""
msgstr ""
"Project-Id-Version: UpdPublish\n"
"POT-Creation-Date: 2018-09-19 10:47+0200\n"
"PO-Revision-Date: 2018-09-19 10:47+0200\n"
"Language-Team: Russian (Russia) (https://www.transifex.com/amebis/teams/91597/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:127
msgid "Show this help message"
msgstr ""
#: main.cpp:128
msgid "Package file to calculate SHA-1 hash from"
msgstr ""
#: main.cpp:129
msgid "input repository file"
msgstr ""
#: main.cpp:130
msgid "output repository file"
msgstr ""
#: main.cpp:131
msgid "platform"
msgstr ""
#: main.cpp:132
msgid "language"
msgstr ""
#: main.cpp:133
msgid "download URL"
msgstr ""

View File

@ -0,0 +1,47 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2018
msgid ""
msgstr ""
"Project-Id-Version: UpdPublish\n"
"POT-Creation-Date: 2018-09-19 10:47+0200\n"
"PO-Revision-Date: 2018-09-19 10:47+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/amebis/teams/91597/sl_SI/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:127
msgid "Show this help message"
msgstr "Pokaži to sporočilo pomoči"
#: main.cpp:128
msgid "Package file to calculate SHA-1 hash from"
msgstr "Datoteka paketa, od katere izračunamo odtis SHA-1"
#: main.cpp:129
msgid "input repository file"
msgstr "vhodna datoteka repozitorija"
#: main.cpp:130
msgid "output repository file"
msgstr "izhodna datoteka repozitorija"
#: main.cpp:131
msgid "platform"
msgstr "platforma"
#: main.cpp:132
msgid "language"
msgstr "jezik"
#: main.cpp:133
msgid "download URL"
msgstr "URL za prenos"

291
UpdPublish/main.cpp Normal file
View File

@ -0,0 +1,291 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"
void UpdaterAddURL(wxXmlNode *elLocale, const wxString &url)
{
wxXmlNode *elUrl = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("url"));
elUrl->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, url));
elLocale->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elLocale->AddChild(elUrl);
elLocale->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t\t")));
}
void UpdaterAddHash(wxXmlNode *elLocale, const wxMemoryBuffer &hash)
{
wxXmlNode *elHash = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("hash"));
elHash->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxHexEncode(hash)));
elLocale->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elLocale->AddChild(elHash);
elLocale->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t\t")));
}
void UpdaterAddLocalization(wxXmlNode *elPlatform, const wxString &languageId, const wxString &url, const wxMemoryBuffer &hash)
{
wxXmlNode *elLocale = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Localization"));
elLocale->AddAttribute(new wxXmlAttribute(wxT("lang"), languageId));
elLocale->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t\t")));
UpdaterAddURL(elLocale, url);
if (!hash.IsEmpty())
UpdaterAddHash(elLocale, hash);
elPlatform->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elPlatform->AddChild(elLocale);
elPlatform->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t")));
}
void UpdaterAddPlatform(wxXmlNode *elDownloads, const wxString &platformId, const wxString &languageId, const wxString &url, const wxMemoryBuffer &hash)
{
wxXmlNode *elPlatform = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Platform"));
elPlatform->AddAttribute(new wxXmlAttribute(wxT("id"), platformId));
elPlatform->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t")));
UpdaterAddLocalization(elPlatform, languageId, url, hash);
elDownloads->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elDownloads->AddChild(elPlatform);
elDownloads->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t")));
}
void UpdaterAddDownloads(wxXmlNode *elPackage, const wxString &platformId, const wxString &languageId, const wxString &url, const wxMemoryBuffer &hash)
{
wxXmlNode *elDownloads = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Downloads"));
elDownloads->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t")));
UpdaterAddPlatform(elDownloads, platformId, languageId, url, hash);
elPackage->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elPackage->AddChild(elDownloads);
elPackage->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t")));
}
void UpdaterAddPackage(wxXmlNode *elPackages, const wxString &platformId, const wxString &languageId, const wxString &url, const wxMemoryBuffer &hash)
{
wxXmlNode *elHex = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("hex"));
elHex->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxString::Format(wxT("%08x"), PRODUCT_VERSION)));
wxXmlNode *elDesc = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("desc"));
elDesc->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT(PRODUCT_VERSION_STR)));
wxXmlNode *elVersion = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Version"));
elVersion->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t")));
elVersion->AddChild(elHex);
elVersion->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t\t")));
elVersion->AddChild(elDesc);
elVersion->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t")));
wxXmlNode *elPackage = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Package"));
elPackage->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t\t")));
elPackage->AddChild(elVersion);
elPackage->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n\t")));
UpdaterAddDownloads(elPackage, platformId, languageId, url, hash);
elPackages->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\t")));
elPackages->AddChild(elPackage);
elPackages->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, wxT("\n")));
}
///
/// Main function
///
int _tmain(int argc, _TCHAR *argv[])
{
wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");
// Initialize wxWidgets.
wxInitializer initializer;
if (!initializer.IsOk())
return -1;
// Parse command line.
static const wxCmdLineEntryDesc cmdLineDesc[] =
{
{ wxCMD_LINE_SWITCH, "h" , "help", _("Show this help message" ), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_OPTION, "f" , "file", _("Package file to calculate hash from"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<input repository file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<output repository file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<platform>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<language>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<download URL>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_NONE }
};
wxCmdLineParser parser(cmdLineDesc, argc, argv);
switch (parser.Parse()) {
case -1:
// Help was given, terminating.
return 0;
case 0:
// everything is ok; proceed
break;
default:
wxLogWarning(wxT("Syntax error detected, aborting."));
return -1;
}
// Load input XML document.
const wxString& filenameIn = parser.GetParam(0);
wxXmlDocument doc;
if (!doc.Load(filenameIn, "UTF-8", wxXMLDOC_KEEP_WHITESPACE_NODES))
return 1;
// Verify document type (root element).
wxXmlNode *elPackages = doc.GetRoot();
const wxString &nameRoot = elPackages->GetName();
if (nameRoot != wxT("Packages")) {
wxLogWarning(wxT("Invalid root element in repository catalogue (actual: %s, expected %s)."), nameRoot.c_str(), wxT("Packages"));
return 2;
}
// Get package file hash.
wxString filenamePckg;
wxMemoryBuffer hash;
if (parser.Found(wxT("f"), &filenamePckg)) {
// Create RSA AES cryptographic session.
wxCryptoSessionRSAAES cs;
wxCHECK(cs.IsOk(), -1);
// Calculate file hash.
wxUpdaterHashGen ch(cs);
wxCHECK(ch.HashFile(filenamePckg), 3);
ch.GetValue(hash);
}
// Iterate over packages.
bool url_present = false;
const wxString& platformId = parser.GetParam(2);
const wxString& language = parser.GetParam(3);
const wxString& url = parser.GetParam(4);
wxString languageId(language);
for (wxXmlNode *elPackage = elPackages->GetChildren(); elPackage; elPackage = elPackage->GetNext()) {
#pragma warning(suppress: 26812) // wxXmlNodeType is unscoped
if (elPackage->GetType() == wxXML_ELEMENT_NODE && elPackage->GetName() == wxT("Package")) {
// Get package version.
wxUint32 version = 0;
wxString versionStr;
for (wxXmlNode *elVersion = elPackage->GetChildren(); elVersion; elVersion = elVersion->GetNext()) {
if (elVersion->GetType() == wxXML_ELEMENT_NODE && elVersion->GetName() == wxT("Version")) {
for (wxXmlNode *elVersionNote = elVersion->GetChildren(); elVersionNote; elVersionNote = elVersionNote->GetNext()) {
if (elVersionNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elVersionNote->GetName();
if (name == wxT("hex"))
version = _tcstoul(elVersionNote->GetNodeContent(), NULL, 16);
else if (name == wxT("desc"))
versionStr = elVersionNote->GetNodeContent();
}
}
}
}
if (version != PRODUCT_VERSION) {
// This package is not our version. Skip.
continue;
}
// Set package download URL for given platform and language.
for (wxXmlNode *elDownloads = elPackage->GetChildren(); elDownloads; elDownloads = elDownloads->GetNext()) {
if (elDownloads->GetType() == wxXML_ELEMENT_NODE && elDownloads->GetName() == wxT("Downloads")) {
for (wxXmlNode *elPlatform = elDownloads->GetChildren(); elPlatform; elPlatform = elPlatform->GetNext()) {
if (elPlatform->GetType() == wxXML_ELEMENT_NODE) {
if (elPlatform->GetName() == wxT("Platform") && elPlatform->GetAttribute(wxT("id")) == platformId) {
// Get language.
for (wxXmlNode *elLocale = elPlatform->GetChildren(); elLocale; elLocale = elLocale->GetNext()) {
if (elLocale->GetType() == wxXML_ELEMENT_NODE && elLocale->GetName() == wxT("Localization") && elLocale->GetAttribute(wxT("lang")) == languageId) {
bool hash_present = false;
for (wxXmlNode *elLocaleNote = elLocale->GetChildren(); elLocaleNote; elLocaleNote = elLocaleNote->GetNext()) {
if (elLocaleNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elLocaleNote->GetName();
if (name == wxT("url")) {
if (elLocaleNote->GetNodeContent() == url)
url_present = true;
} else if (!hash.IsEmpty() && name == wxT("hash")) {
// Read the hash.
wxMemoryBuffer hashOrig;
wxString content(elLocaleNote->GetNodeContent());
size_t len = wxHexDecodedSize(content.length());
size_t res = wxHexDecode(hashOrig.GetWriteBuf(len), len, content, wxHexDecodeMode::SkipWS);
if (res != wxCONV_FAILED) {
hashOrig.SetDataLen(res);
if (hash.GetDataLen() == hashOrig.GetDataLen() &&
memcmp(hash.GetData(), hashOrig.GetData(), hash.GetDataLen()) == 0)
{
hash_present = true;
} else {
wxLogError(wxT("This update package is already in the database. However, its hash is different."));
return 3;
}
} else {
wxLogError(wxT("This update package is already in the database. However, its hash is corrupt."));
return 4;
}
}
}
}
if (!url_present) {
// Add URL.
UpdaterAddURL(elLocale, url);
url_present = true;
}
if (!hash_present && !hash.IsEmpty()) {
// Add hash.
UpdaterAddHash(elLocale, hash);
}
}
}
if (!url_present) {
// Add localization.
UpdaterAddLocalization(elPlatform, languageId, url, hash);
url_present = true;
}
}
}
}
if (!url_present) {
// Add platform.
UpdaterAddPlatform(elDownloads, platformId, languageId, url, hash);
url_present = true;
}
}
}
if (!url_present) {
// Add downloads.
UpdaterAddDownloads(elPackage, platformId, languageId, url, hash);
url_present = true;
}
}
}
if (!url_present) {
// Add package.
UpdaterAddPackage(elPackages, platformId, languageId, url, hash);
url_present = true;
}
// Write output XML document.
const wxString& filenameOut = parser.GetParam(1);
if (!doc.Save(filenameOut, wxXML_NO_INDENTATION)) {
wxLogError(wxT("%s: error USX0004: Error writing output file.\n"), filenameOut.fn_str());
// Remove the output file (if exists).
wxRemoveFile(filenameOut);
return 4;
}
return 0;
}

6
UpdPublish/pch.cpp Normal file
View File

@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"

22
UpdPublish/pch.h Normal file
View File

@ -0,0 +1,22 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#include "../Updater/include/Updater/common.h"
#include "UpdPublish.h"
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/app.h>
#include <wx/base64.h>
#include <wx/cmdline.h>
#include <wx/xml/xml.h>
#pragma warning(pop)
#include <wxex/crypto.h>
#include <wxex/hex.h>
#include <wxex/xml.h>

View File

@ -1,25 +1,11 @@
/* /*
Copyright 2016 Amebis SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#define IDR_KEY_PRIVATE 1 #define IDR_KEY_PRIVATE 1
#if !defined(RC_INVOKED) && !defined(MIDL_PASS) #if !defined(RC_INVOKED) && !defined(__midl)
#endif // !defined(RC_INVOKED) && !defined(MIDL_PASS) #endif // !defined(RC_INVOKED) && !defined(__midl)

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\lib\wxExtend\include;..\..\lib\stdex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -9,6 +13,10 @@
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
@ -23,85 +31,66 @@
<RootNamespace>UpdSignXML</RootNamespace> <RootNamespace>UpdSignXML</RootNamespace>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Label="Configuration" Condition="'$(Platform)'=='ARM64'">
<ConfigurationType>Application</ConfigurationType> <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings" />
</ImportGroup> <ImportGroup Label="PropertySheets">
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\Win32.props" /> <Import Project="..\..\include\$(Platform).props" />
<Import Project="..\..\include\Debug.props" /> <Import Project="..\..\include\$(Configuration).props" />
<Import Project="UpdSignXML.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\x64.props" />
<Import Project="..\..\include\Debug.props" />
<Import Project="UpdSignXML.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\Win32.props" />
<Import Project="..\..\include\Release.props" />
<Import Project="UpdSignXML.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\include\x64.props" />
<Import Project="..\..\include\Release.props" />
<Import Project="UpdSignXML.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\lib\wxExtend\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="UpdSignXML.h" /> <ClInclude Include="UpdSignXML.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\lib\wxExtend\build\wxExtend.vcxproj"> <ProjectReference Include="..\..\lib\wxExtend\build\wxExtendLib.vcxproj">
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project> <Project>{D3E29951-D9F5-486D-A167-20AE8E90B1FA}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="UpdSignXML.rc" /> <ResourceCompile Include="UpdSignXML.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<POCompile Include="locale\de_DE.po" />
<POCompile Include="locale\ru_RU.po" />
<POCompile Include="locale\sl_SI.po" /> <POCompile Include="locale\sl_SI.po" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="locale\UpdSignXML.pot" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets" />
</ImportGroup>
</Project> </Project>

View File

@ -19,7 +19,7 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="stdafx.cpp"> <ClCompile Include="pch.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
@ -27,7 +27,7 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h"> <ClInclude Include="pch.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="UpdSignXML.h"> <ClInclude Include="UpdSignXML.h">
@ -40,8 +40,19 @@
</ResourceCompile> </ResourceCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<POCompile Include="locale\de_DE.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\ru_RU.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="locale\sl_SI.po"> <POCompile Include="locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter> <Filter>Resource Files\Localization</Filter>
</POCompile> </POCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="locale\UpdSignXML.pot">
<Filter>Resource Files\Localization</Filter>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,30 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: UpdSignXML\n"
"POT-Creation-Date: 2022-02-17 13:29+0100\n"
"PO-Revision-Date: 2018-09-19 10:49+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: main.cpp:24
msgid "Show this help message"
msgstr ""
#: main.cpp:25
msgid "<input file>"
msgstr ""
#: main.cpp:26
msgid "<output file>"
msgstr ""

View File

@ -0,0 +1,31 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2018
msgid ""
msgstr ""
"Project-Id-Version: UpdSignXML\n"
"POT-Creation-Date: 2018-09-19 10:49+0200\n"
"PO-Revision-Date: 2018-09-19 10:49+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: German (Germany) (https://www.transifex.com/amebis/teams/91597/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:38
msgid "Show this help message"
msgstr "Zeige diesen Hilfstext"
#: main.cpp:39
msgid "input file"
msgstr ""
#: main.cpp:40
msgid "output file"
msgstr ""

View File

@ -0,0 +1,29 @@
#
msgid ""
msgstr ""
"Project-Id-Version: UpdSignXML\n"
"POT-Creation-Date: 2018-09-19 10:49+0200\n"
"PO-Revision-Date: 2018-09-19 10:49+0200\n"
"Language-Team: Russian (Russia) (https://www.transifex.com/amebis/teams/91597/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:38
msgid "Show this help message"
msgstr ""
#: main.cpp:39
msgid "input file"
msgstr ""
#: main.cpp:40
msgid "output file"
msgstr ""

View File

@ -1,45 +1,31 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2018
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: UpdSignXML\n" "Project-Id-Version: UpdSignXML\n"
"POT-Creation-Date: 2016-03-15 20:09+0100\n" "POT-Creation-Date: 2018-09-19 10:49+0200\n"
"PO-Revision-Date: 2016-03-15 20:10+0100\n" "PO-Revision-Date: 2018-09-19 10:49+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Slovenian (Slovenia) (https://www.transifex.com/amebis/teams/91597/sl_SI/)\n"
"Language: sl_SI\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n" "Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n" "X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n" "X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: main.cpp:138 #: main.cpp:38
msgid "Show this help message" msgid "Show this help message"
msgstr "Pokaži to sporočilo pomoči" msgstr "Pokaži to sporočilo pomoči"
#: main.cpp:139 #: main.cpp:39
msgid "Hexadecimal version of the product" msgid "input file"
msgstr "Verzija izdelka šesnajstiško" msgstr "vhodna datoteka"
#: main.cpp:140 #: main.cpp:40
msgid "String version of the product"
msgstr "Verzija izdelka opisno"
#: main.cpp:141
msgid "Package language"
msgstr "Jezik paketa"
#: main.cpp:142
msgid "Package download URL"
msgstr "URL za prenos paketa"
#: main.cpp:143
msgid "output file" msgid "output file"
msgstr "izhodna datoteka" msgstr "izhodna datoteka"
#~ msgid "Package URL in the form of platform;language;URL"
#~ msgstr "Naslov URL paketa oblike platforma;jezik;URL"

View File

@ -1,23 +1,9 @@
/* /*
Copyright 2016 Amebis SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "stdafx.h" #include "pch.h"
/// ///
@ -36,8 +22,8 @@ int _tmain(int argc, _TCHAR *argv[])
static const wxCmdLineEntryDesc cmdLineDesc[] = static const wxCmdLineEntryDesc cmdLineDesc[] =
{ {
{ wxCMD_LINE_SWITCH, "h" , "help", _("Show this help message"), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP }, { wxCMD_LINE_SWITCH, "h" , "help", _("Show this help message"), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_PARAM , NULL, NULL , _("input file" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY }, { wxCMD_LINE_PARAM , NULL, NULL , _("<input file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("output file" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY }, { wxCMD_LINE_PARAM , NULL, NULL , _("<output file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_NONE } { wxCMD_LINE_NONE }
}; };
@ -65,6 +51,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Examine prologue if the document is already signed and remove all signatures found. // Examine prologue if the document is already signed and remove all signatures found.
wxXmlNode *document = doc.GetDocumentNode(); wxXmlNode *document = doc.GetDocumentNode();
for (wxXmlNode *prolog = document->GetChildren(); prolog;) { for (wxXmlNode *prolog = document->GetChildren(); prolog;) {
#pragma warning(suppress: 26812) // wxXmlNodeType is unscoped
if (prolog->GetType() == wxXML_COMMENT_NODE) { if (prolog->GetType() == wxXML_COMMENT_NODE) {
wxString content = prolog->GetContent(); wxString content = prolog->GetContent();
if (content.length() >= _countof(wxS(UPDATER_SIGNATURE_MARK)) - 1 && if (content.length() >= _countof(wxS(UPDATER_SIGNATURE_MARK)) - 1 &&
@ -90,17 +77,25 @@ int _tmain(int argc, _TCHAR *argv[])
// Import the private key into the session from resources. // Import the private key into the session from resources.
{ {
HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(IDR_KEY_PRIVATE), RT_RCDATA); HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(IDR_KEY_PRIVATE), RT_RCDATA);
wxASSERT_MSG(res, wxT("private key not found")); if (!res) {
wxLogError(wxT("%s: error USX0005: Error locating private key.\n"));
return -1;
}
HGLOBAL res_handle = ::LoadResource(NULL, res); HGLOBAL res_handle = ::LoadResource(NULL, res);
wxASSERT_MSG(res_handle, wxT("loading resource failed")); if (!res_handle) {
wxLogError(wxT("%s: error USX0006: Error loading private key.\n"));
return -1;
}
wxCryptoKey ck; wxCryptoKey ck;
if (!ck.ImportPrivate(cs, ::LockResource(res_handle), ::SizeofResource(NULL, res))) if (!ck.ImportPrivate(cs, ::LockResource(res_handle), ::SizeofResource(NULL, res))) {
wxLogError(wxT("%s: error USX0007: Error importing private key.\n"));
return -1; return -1;
}
} }
// Hash the XML content. // Hash the XML content.
wxCryptoHashSHA1 ch(cs); wxUpdaterHashGen ch(cs);
if (!wxXmlHashNode(ch, document)) if (!wxXmlHashNode(ch, document))
return 2; return 2;

6
UpdSignXML/pch.cpp Normal file
View File

@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"

21
UpdSignXML/pch.h Normal file
View File

@ -0,0 +1,21 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#include "../Updater/include/Updater/common.h"
#include "UpdSignXML.h"
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/app.h>
#include <wx/base64.h>
#include <wx/cmdline.h>
#include <wx/xml/xml.h>
#pragma warning(pop)
#include <wxex/crypto.h>
#include <wxex/xml.h>

View File

@ -1,20 +0,0 @@
/*
Copyright 2016 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"

View File

@ -1,35 +0,0 @@
/*
Copyright 2016 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "UpdSignXML.h"
#include "../include/Updater.h"
#include <wx/app.h>
#include <wx/base64.h>
#include <wx/cmdline.h>
#include <wx/xml/xml.h>
#include <wxex/common.h>
#include <wxex/crypto.h>
#include <wxex/xml.h>
#include <algorithm>
#include <vector>

View File

@ -1,50 +0,0 @@
#
# Copyright 2016 Amebis
#
# This file is part of Updater.
#
# Updater is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Updater is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Updater. If not, see <http://www.gnu.org/licenses/>.
#
!IFNDEF UPDATER_CFG
UPDATER_CFG=HKLM\Software\Amebis\ZRCola\Updater
!ENDIF
!IFNDEF UPDATER_OUTPUT_DIR
UPDATER_OUTPUT_DIR=output\update
!ENDIF
!IF "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
UPDATER_REG_FLAGS=/f /reg:64
UPDATER_REG_FLAGS32=/f /reg:32
!ELSE
UPDATER_REG_FLAGS=/f
!ENDIF
######################################################################
# Main targets
######################################################################
UpdaterRegisterSettings ::
reg.exe add "$(UPDATER_CFG)" /v "CachePath" /t REG_SZ /d "$(MAKEDIR)\$(UPDATER_OUTPUT_DIR)" $(UPDATER_REG_FLAGS) > NUL
!IF "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
reg.exe add "$(UPDATER_CFG)" /v "CachePath" /t REG_SZ /d "$(MAKEDIR)\$(UPDATER_OUTPUT_DIR)" $(UPDATER_REG_FLAGS32) > NUL
!ENDIF
UpdaterUnregisterSettings ::
-reg.exe delete "$(UPDATER_CFG)" /v "CachePath" $(UPDATER_REG_FLAGS) > NUL
!IF "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
-reg.exe delete "$(UPDATER_CFG)" /v "CachePath" $(UPDATER_REG_FLAGS32) > NUL
!ENDIF

View File

@ -1,67 +1,104 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2010 # Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{A7D28E0C-BB96-444D-AAB0-F22A6483FE5F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{A7D28E0C-BB96-444D-AAB0-F22A6483FE5F}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECE3F336-FFD2-41EE-AD8F-17BD7472BDCB}"
ProjectSection(SolutionItems) = preProject
include\Updater.h = include\Updater.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UpdCheck", "UpdCheck\UpdCheck.vcxproj", "{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UpdCheck", "UpdCheck\UpdCheck.vcxproj", "{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "..\lib\wxExtend\build\wxExtend.vcxproj", "{A3A36689-AC35-4026-93DA-A3BA0C0E767C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "..\lib\wxExtend\build\wxExtendLib.vcxproj", "{D3E29951-D9F5-486D-A167-20AE8E90B1FA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stdex", "..\lib\stdex\build\stdex.vcxproj", "{518777CC-0A59-4415-A12A-82751ED75343}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UpdSignXML", "UpdSignXML\UpdSignXML.vcxproj", "{2A403460-7834-41B8-9823-199E8FE36FA8}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UpdSignXML", "UpdSignXML\UpdSignXML.vcxproj", "{2A403460-7834-41B8-9823-199E8FE36FA8}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UpdPublish", "UpdPublish\UpdPublish.vcxproj", "{C5829278-D55E-41EB-B866-1E7D814694D1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updater", "Updater\build\Updater.vcxproj", "{990D8CF9-4457-4DC0-AA18-4968EF434741}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{28F748D5-D691-4F00-9464-37AF062CF91F}"
ProjectSection(SolutionItems) = preProject
..\include\UpdaterCfg.h = ..\include\UpdaterCfg.h
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|ARM64.Build.0 = Debug|ARM64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|Win32.ActiveCfg = Debug|Win32 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|Win32.ActiveCfg = Debug|Win32
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|Win32.Build.0 = Debug|Win32 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|Win32.Build.0 = Debug|Win32
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|x64.ActiveCfg = Debug|x64 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|x64.ActiveCfg = Debug|x64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|x64.Build.0 = Debug|x64 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Debug|x64.Build.0 = Debug|x64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|ARM64.ActiveCfg = Release|ARM64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|ARM64.Build.0 = Release|ARM64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|Win32.ActiveCfg = Release|Win32 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|Win32.ActiveCfg = Release|Win32
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|Win32.Build.0 = Release|Win32 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|Win32.Build.0 = Release|Win32
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|x64.ActiveCfg = Release|x64 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|x64.ActiveCfg = Release|x64
{0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|x64.Build.0 = Release|x64 {0B2B7A10-3FA0-46CD-AD89-6D02DA2C5FC3}.Release|x64.Build.0 = Release|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|Win32.ActiveCfg = Debug|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|Win32.Build.0 = Debug|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|ARM64.Build.0 = Debug|ARM64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|x64.ActiveCfg = Debug|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|Win32.ActiveCfg = Debug|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|x64.Build.0 = Debug|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|Win32.Build.0 = Debug|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|Win32.ActiveCfg = Release|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|x64.ActiveCfg = Debug|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|Win32.Build.0 = Release|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|x64.Build.0 = Debug|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|x64.ActiveCfg = Release|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|ARM64.ActiveCfg = Release|ARM64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|x64.Build.0 = Release|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|ARM64.Build.0 = Release|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|Win32.ActiveCfg = Debug|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.ActiveCfg = Release|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|Win32.Build.0 = Debug|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.Build.0 = Release|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|x64.ActiveCfg = Debug|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.ActiveCfg = Release|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|x64.Build.0 = Debug|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.Build.0 = Release|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|Win32.ActiveCfg = Release|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|Win32.Build.0 = Release|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|ARM64.Build.0 = Debug|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|x64.ActiveCfg = Release|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|x64.Build.0 = Release|x64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|Win32.ActiveCfg = Debug|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|Win32.ActiveCfg = Debug|Win32
{2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|Win32.Build.0 = Debug|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|Win32.Build.0 = Debug|Win32
{2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|x64.ActiveCfg = Debug|x64 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|x64.ActiveCfg = Debug|x64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|x64.Build.0 = Debug|x64 {2A403460-7834-41B8-9823-199E8FE36FA8}.Debug|x64.Build.0 = Debug|x64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|ARM64.ActiveCfg = Release|ARM64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|ARM64.Build.0 = Release|ARM64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|Win32.ActiveCfg = Release|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Release|Win32.ActiveCfg = Release|Win32
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|Win32.Build.0 = Release|Win32 {2A403460-7834-41B8-9823-199E8FE36FA8}.Release|Win32.Build.0 = Release|Win32
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|x64.ActiveCfg = Release|x64 {2A403460-7834-41B8-9823-199E8FE36FA8}.Release|x64.ActiveCfg = Release|x64
{2A403460-7834-41B8-9823-199E8FE36FA8}.Release|x64.Build.0 = Release|x64 {2A403460-7834-41B8-9823-199E8FE36FA8}.Release|x64.Build.0 = Release|x64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|ARM64.Build.0 = Debug|ARM64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|Win32.ActiveCfg = Debug|Win32
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|Win32.Build.0 = Debug|Win32
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|x64.ActiveCfg = Debug|x64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Debug|x64.Build.0 = Debug|x64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|ARM64.ActiveCfg = Release|ARM64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|ARM64.Build.0 = Release|ARM64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|Win32.ActiveCfg = Release|Win32
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|Win32.Build.0 = Release|Win32
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|x64.ActiveCfg = Release|x64
{C5829278-D55E-41EB-B866-1E7D814694D1}.Release|x64.Build.0 = Release|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|ARM64.ActiveCfg = Debug|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|ARM64.Build.0 = Debug|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|Win32.ActiveCfg = Debug|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|Win32.Build.0 = Debug|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|x64.ActiveCfg = Debug|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|x64.Build.0 = Debug|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|ARM64.ActiveCfg = Release|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|ARM64.Build.0 = Release|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|Win32.ActiveCfg = Release|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|Win32.Build.0 = Release|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|x64.ActiveCfg = Release|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{A3A36689-AC35-4026-93DA-A3BA0C0E767C} = {A7D28E0C-BB96-444D-AAB0-F22A6483FE5F} {D3E29951-D9F5-486D-A167-20AE8E90B1FA} = {A7D28E0C-BB96-444D-AAB0-F22A6483FE5F}
{518777CC-0A59-4415-A12A-82751ED75343} = {A7D28E0C-BB96-444D-AAB0-F22A6483FE5F} {990D8CF9-4457-4DC0-AA18-4968EF434741} = {A7D28E0C-BB96-444D-AAB0-F22A6483FE5F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E86510CB-829C-41C4-8E19-CBB300B80B81}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

9
Updater/MSIBuild/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
/*-1.idt
/*-2.idt
/*-2.idtx
/*.Binary-1
/*.Binary-2
/*.Icon-1
/*.Icon-2
/*.lst
/*.msm

71
Updater/MSIBuild/Makefile Normal file
View File

@ -0,0 +1,71 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright © 1991-2022 Amebis
!INCLUDE "..\..\..\include\MSIBuildCfg.mak"
!IFNDEF MSIBUILD_LANGID
!ERROR Parameter MSIBUILD_LANGID is undefined.
!ENDIF
!IFNDEF MSIBUILD_LANG_GUID
!ERROR Parameter MSIBUILD_LANG_GUID is undefined.
!ENDIF
!IFNDEF UPDATER_LOC_DIR
!ERROR Parameter UPDATER_LOC_DIR is undefined.
!ENDIF
######################################################################
# Component
All :: "$(LANG).$(PLAT).$(CFG).Component-1.idt"
"$(LANG).$(PLAT).$(CFG).Component-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
move /y << $@ > NUL
Component ComponentId Directory_ Attributes Condition KeyPath
s$(MSIBUILD_LENGTH_ID) S38 s$(MSIBUILD_LENGTH_ID) i2 S255 S$(MSIBUILD_LENGTH_ID)
Component Component
!IF "$(LANG)" != "en_US"
Updater.mo.$(LANG) {5F141A03-07EE-4AC4-$(MSIBUILD_LANG_GUID)-CFB1833C1A04} UPDATERLOC$(MSIBUILD_LANG_GUID)DIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) Updater.mo.$(LANG)
!ENDIF
<<NOKEEP
######################################################################
# Directory
All :: "$(LANG).$(PLAT).$(CFG).Directory-1.idt"
"$(LANG).$(PLAT).$(CFG).Directory-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
move /y << $@ > NUL
Directory Directory_Parent DefaultDir
s$(MSIBUILD_LENGTH_ID) S$(MSIBUILD_LENGTH_ID) l255
Directory Directory
!IF "$(LANG)" != "en_US"
UPDATERLOC$(MSIBUILD_LANG_GUID)DIR $(UPDATER_LOC_DIR) $(LANG)
!ENDIF
<<NOKEEP
######################################################################
# File
All :: "$(LANG).$(PLAT).$(CFG).File-1.idt"
"$(LANG).$(PLAT).$(CFG).File-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
move /y << $@ > NUL
File Component_ FileName FileSize Version Language Attributes Sequence
s$(MSIBUILD_LENGTH_ID) s$(MSIBUILD_LENGTH_ID) l255 i4 S$(MSIBUILD_LENGTH_ID) S20 I2 i2
File File
!IF "$(LANG)" != "en_US"
Updater.mo.$(LANG) Updater.mo.$(LANG) UPDATE~1.MO|Updater$(UPDATER_VERSION).mo 0 $(MSIBUILD_LANGID) 0 1
!ENDIF
<<NOKEEP
######################################################################
# Build MSM module!
######################################################################
!INCLUDE "..\..\..\MSI\MSIBuild\MSM.mak"

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{990D8CF9-4457-4DC0-AA18-4968EF434741}</ProjectGuid>
<RootNamespace>Updater</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Platform)'=='ARM64'">
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\$(Platform).props" />
<Import Project="..\..\..\include\$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\..\..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>UPDATER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\lib\wxExtend\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<POCompile>
<OutputFile>$(OutDir)..\locale\%(Filename)\$(ProjectName)$(UpdaterVersion).mo</OutputFile>
</POCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\main.cpp" />
<ClCompile Include="..\src\pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\src\chkthread.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\updater\chkthread.h" />
<ClInclude Include="..\include\Updater\common.h" />
<ClInclude Include="..\src\pch.h" />
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\de_DE.po" />
<POCompile Include="..\locale\ru_RU.po" />
<POCompile Include="..\locale\sl_SI.po" />
</ItemGroup>
<ItemGroup>
<None Include="..\locale\Updater.pot" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\res\Updater.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\include\xgettext.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Resource Files\Localization">
<UniqueIdentifier>{e43059ae-37ac-4b28-84fb-18d1b3972b30}</UniqueIdentifier>
<Extensions>po;pot</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\chkthread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\Updater\common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\updater\chkthread.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\locale\Updater.pot">
<Filter>Resource Files\Localization</Filter>
</None>
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="..\locale\de_DE.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
<POCompile Include="..\locale\ru_RU.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\res\Updater.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,159 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#include "common.h"
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/arrstr.h>
#include <wx/config.h>
#include <wx/event.h>
#include <wx/string.h>
#include <wx/thread.h>
#include <wx/xml/xml.h>
#pragma warning(pop)
#include <wxex/crypto.h>
///
/// wxEVT_UPDATER_CHECK_COMPLETE event
///
wxDECLARE_EVENT(wxEVT_UPDATER_CHECK_COMPLETE, wxThreadEvent);
///
/// Update check thread
///
class wxUpdCheckThread : public wxThread
{
public:
///
/// Thread exit codes
///
enum class wxResult {
Uninitialized = -1, ///< Initialization failed
Aborted = -2, ///< Thread aborted
RepoUnavailable = -3, ///< No update package information available
PkgUnavailable = -4, ///< Update package not available
UpdateAvailable = 0, ///< Update downloaded, verified and prepared to install
UpToDate, ///< Product is up-to-date
};
wxUpdCheckThread(const wxString &langId, wxEvtHandler *parent = NULL);
~wxUpdCheckThread();
///
/// Checks for updates and safely downloads update package when available.
///
inline wxResult CheckForUpdate()
{
return DoCheckForUpdate();
}
///
/// Aborts current update check
///
inline void Abort() noexcept
{
m_abort = true;
}
protected:
///
/// Thread's body
///
/// \returns Exit code
///
ExitCode Entry() override;
///
/// Overrriden method to allow custom termination when Updater is launched in the main thread.
///
bool TestDestroy() override;
///
/// Checks for updates and safely downloads update package when available.
///
wxResult DoCheckForUpdate();
///
/// Downloads repository database (with integrity check).
///
/// \returns Repository database. Use wxDELETE after use.
///
wxXmlDocument* GetCatalogue();
///
/// Parses repository database.
///
/// \returns
/// - true if parsing succeeded
/// - false otherwise
///
bool ParseCatalogue(const wxXmlDocument &doc);
///
/// Stores update package meta-information to cache.
///
/// \returns
/// - true if writing succeeded
/// - false otherwise
///
bool WriteUpdatePackageMeta();
///
/// Retrieves update package meta-information from cache.
///
/// \returns
/// - true if reading succeeded
/// - false otherwise
///
bool ReadUpdatePackageMeta();
///
/// Downloads update package.
///
/// \returns
/// - true if downloading succeeded
/// - false otherwise
///
bool DownloadUpdatePackage();
public:
///
/// Launches update.
///
/// \param[in] hParent Handle of parent window
/// \param[in] headless Launch silent install
///
/// \returns
/// - true if launch succeeded
/// - false otherwise
///
bool LaunchUpdate(WXHWND hParent = NULL, bool headless = false);
protected:
wxEvtHandler *m_parent; ///< Parent to notify
bool m_ok; ///< Is class initialized correctly?
volatile bool m_abort; ///< Should Update check abort?
wxString m_langId; ///< Language identifier
wxConfig m_config; ///< Application configuration
wxString m_path; ///< Working directory (downloaded files, etc.)
wxCryptoSession *m_cs; ///< Cryptographics session
wxCryptoKey *m_ck; ///< Public key for update database integrity validation
wxUint32 m_version; ///< Latest product version available (numerical)
wxString m_versionStr; ///< Latest product version available (string)
wxArrayString m_urls; ///< List of update package file downloads
wxMemoryBuffer m_hash; ///< Update package hash
wxString m_fileName; ///< Downloaded package file name
};

View File

@ -0,0 +1,26 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#if !defined(__UPDATER_common_h__)
#define __UPDATER_common_h__
#include "../../../../include/UpdaterCfg.h"
//
// Resource IDs
//
#define UPDATER_IDR_KEY_PUBLIC 1
#if !defined(RC_INVOKED) && !defined(__midl)
#include <codeanalysis\warnings.h>
#ifndef WXWIDGETS_CODE_ANALYSIS_WARNINGS
#define WXWIDGETS_CODE_ANALYSIS_WARNINGS ALL_CODE_ANALYSIS_WARNINGS 26812 26814
#endif
#define UPDATER_SIGNATURE_MARK "SIGNATURE:"
#endif // !defined(RC_INVOKED) && !defined(__midl)
#endif // !defined(__UPDATER_common_h__)

1
Updater/locale/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/*.mo

130
Updater/locale/Updater.pot Normal file
View File

@ -0,0 +1,130 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Updater\n"
"POT-Creation-Date: 2022-02-17 13:30+0100\n"
"PO-Revision-Date: 2016-02-06 09:04+0100\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: src\n"
"X-Poedit-SearchPath-1: include\n"
#: src/chkthread.cpp:98 src/chkthread.cpp:112
msgid "Update check complete. Your product is up to date."
msgstr ""
#: src/chkthread.cpp:132
msgid "Downloading repository catalogue..."
msgstr ""
#: src/chkthread.cpp:140
#, c-format
msgid "Contacting repository at %s..."
msgstr ""
#: src/chkthread.cpp:148
#, c-format
msgid "Error resolving %s server name."
msgstr ""
#: src/chkthread.cpp:154
msgid "Repository did not change since the last time."
msgstr ""
#: src/chkthread.cpp:157
#, c-format
msgid "%u status received from server %s (port %u) requesting %s."
msgstr ""
#: src/chkthread.cpp:160
#, c-format
msgid "Error response received from server %s (port %u) requesting %s."
msgstr ""
#: src/chkthread.cpp:171 src/chkthread.cpp:444
#, c-format
msgid "Can not open/create %s file for writing."
msgstr ""
#: src/chkthread.cpp:184 src/chkthread.cpp:483
#, c-format
msgid "Can not write to %s file."
msgstr ""
#: src/chkthread.cpp:193
msgid "Error loading repository catalogue."
msgstr ""
#: src/chkthread.cpp:199
msgid "Verifying repository catalogue signature..."
msgstr ""
#: src/chkthread.cpp:231
msgid "Signature not found in the repository catalogue."
msgstr ""
#: src/chkthread.cpp:244
msgid "Repository catalogue signature does not match its content, or signature verification failed."
msgstr ""
#: src/chkthread.cpp:251
#, c-format
msgid "Invalid root element in repository catalogue (actual: %s, expected: %s)."
msgstr ""
#: src/chkthread.cpp:268
msgid "Parsing repository catalogue..."
msgstr ""
#: src/chkthread.cpp:355
#, c-format
msgid "Update package found (version: %s)."
msgstr ""
#: src/chkthread.cpp:413
msgid "Reading update package meta-information from cache failed or incomplete."
msgstr ""
#: src/chkthread.cpp:436
msgid "Update package file already downloaded and ready to install."
msgstr ""
#: src/chkthread.cpp:464
#, c-format
msgid "Downloading update package %s..."
msgstr ""
#: src/chkthread.cpp:467
msgid "Error response received."
msgstr ""
#: src/chkthread.cpp:494
msgid "Update package downloaded and ready to install."
msgstr ""
#: src/chkthread.cpp:497
msgid "Update package file corrupt."
msgstr ""
#: src/chkthread.cpp:506
msgid "Launching update..."
msgstr ""
#: src/chkthread.cpp:525
#, c-format
msgid "msiexec.exe launch succeeded. For detailed information, see %s file."
msgstr ""
#: src/chkthread.cpp:528
#, c-format
msgid "msiexec.exe launch failed. ShellExecute returned %i."
msgstr ""

134
Updater/locale/de_DE.po Normal file
View File

@ -0,0 +1,134 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Updater\n"
"POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-02-06 09:04+0100\n"
"Language-Team: German (Germany) (https://www.transifex.com/amebis/teams/91597/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: src\n"
"X-Poedit-SearchPath-1: include\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: src/chkthread.cpp:111 src/chkthread.cpp:125
msgid "Update check complete. Your product is up to date."
msgstr ""
#: src/chkthread.cpp:145
msgid "Downloading repository catalogue..."
msgstr ""
#: src/chkthread.cpp:153
#, c-format
msgid "Contacting repository at %s..."
msgstr ""
#: src/chkthread.cpp:161
#, c-format
msgid "Error resolving %s server name."
msgstr ""
#: src/chkthread.cpp:167
msgid "Repository did not change since the last time."
msgstr ""
#: src/chkthread.cpp:170
#, c-format
msgid "%u status received from server %s (port %u) requesting %s."
msgstr ""
#: src/chkthread.cpp:173
#, c-format
msgid "Error response received from server %s (port %u) requesting %s."
msgstr ""
#: src/chkthread.cpp:184 src/chkthread.cpp:454
#, c-format
msgid "Can not open/create %s file for writing."
msgstr ""
#: src/chkthread.cpp:197 src/chkthread.cpp:493
#, c-format
msgid "Can not write to %s file."
msgstr ""
#: src/chkthread.cpp:206
msgid "Error loading repository catalogue."
msgstr ""
#: src/chkthread.cpp:212
msgid "Verifying repository catalogue signature..."
msgstr ""
#: src/chkthread.cpp:243
msgid "Signature not found in the repository catalogue."
msgstr ""
#: src/chkthread.cpp:256
msgid ""
"Repository catalogue signature does not match its content, or signature "
"verification failed."
msgstr ""
#: src/chkthread.cpp:263
#, c-format
msgid ""
"Invalid root element in repository catalogue (actual: %s, expected: %s)."
msgstr ""
#: src/chkthread.cpp:280
msgid "Parsing repository catalogue..."
msgstr ""
#: src/chkthread.cpp:365
#, c-format
msgid "Update package found (version: %s)."
msgstr ""
#: src/chkthread.cpp:423
msgid ""
"Reading update package meta-information from cache failed or incomplete."
msgstr ""
#: src/chkthread.cpp:446
msgid "Update package file already downloaded and ready to install."
msgstr ""
#: src/chkthread.cpp:474
#, c-format
msgid "Downloading update package %s..."
msgstr ""
#: src/chkthread.cpp:477
msgid "Error response received."
msgstr ""
#: src/chkthread.cpp:504
msgid "Update package downloaded and ready to install."
msgstr ""
#: src/chkthread.cpp:507
msgid "Update package file corrupt."
msgstr ""
#: src/chkthread.cpp:516
msgid "Launching update..."
msgstr ""
#: src/chkthread.cpp:535
#, c-format
msgid "msiexec.exe launch succeeded. For detailed information, see %s file."
msgstr ""
#: src/chkthread.cpp:538
#, c-format
msgid "msiexec.exe launch failed. ShellExecute returned %i."
msgstr ""

144
Updater/locale/ru_RU.po Normal file
View File

@ -0,0 +1,144 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Updater\n"
"POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-02-06 09:04+0100\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Russian (Russia) (https://www.transifex.com/amebis/teams/91597/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: src\n"
"X-Poedit-SearchPath-1: include\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: src/chkthread.cpp:111 src/chkthread.cpp:125
msgid "Update check complete. Your product is up to date."
msgstr ""
"Проверка на наличие обновлений завершена. У вас последняя версия программы."
#: src/chkthread.cpp:145
msgid "Downloading repository catalogue..."
msgstr "Загрузка каталога репозитория ..."
#: src/chkthread.cpp:153
#, c-format
msgid "Contacting repository at %s..."
msgstr "Контактирование репозитория при %s ..."
#: src/chkthread.cpp:161
#, c-format
msgid "Error resolving %s server name."
msgstr "Ошибка при разрешении имени сервера %s."
#: src/chkthread.cpp:167
msgid "Repository did not change since the last time."
msgstr "Репозиторий не от последней проверки изменился."
#: src/chkthread.cpp:170
#, c-format
msgid "%u status received from server %s (port %u) requesting %s."
msgstr ""
#: src/chkthread.cpp:173
#, c-format
msgid "Error response received from server %s (port %u) requesting %s."
msgstr "От сервера %s (порт %u) получен ошибочный ответ при запросе %s."
#: src/chkthread.cpp:184 src/chkthread.cpp:454
#, c-format
msgid "Can not open/create %s file for writing."
msgstr "Открытие/создание файла %s для записи невозможно."
#: src/chkthread.cpp:197 src/chkthread.cpp:493
#, c-format
msgid "Can not write to %s file."
msgstr "Запись в файл %s невозможен."
#: src/chkthread.cpp:206
msgid "Error loading repository catalogue."
msgstr "Ошибка при загрузке каталога репозитория."
#: src/chkthread.cpp:212
msgid "Verifying repository catalogue signature..."
msgstr "Проверка подписи каталога репозитория ..."
#: src/chkthread.cpp:243
msgid "Signature not found in the repository catalogue."
msgstr "Подпись в каталоге репозитория не найдена."
#: src/chkthread.cpp:256
msgid ""
"Repository catalogue signature does not match its content, or signature "
"verification failed."
msgstr ""
"Подпись каталога репозитория, или не соответствует его содержанию или "
"проверка подписи завершилась ошибкой."
#: src/chkthread.cpp:263
#, c-format
msgid ""
"Invalid root element in repository catalogue (actual: %s, expected: %s)."
msgstr ""
"Недействительный корневой элемент в каталоге репозитория (фактический: %s, "
"ожидаемый: %s)."
#: src/chkthread.cpp:280
msgid "Parsing repository catalogue..."
msgstr "Анализ каталога репозитория ..."
#: src/chkthread.cpp:365
#, c-format
msgid "Update package found (version: %s)."
msgstr "Найден пакет обновления (версия: %s)."
#: src/chkthread.cpp:423
msgid ""
"Reading update package meta-information from cache failed or incomplete."
msgstr ""
"Чтение метаданных пакета обновления в кэше завершилась ошибкой, или чтение "
"не завершилось."
#: src/chkthread.cpp:446
msgid "Update package file already downloaded and ready to install."
msgstr "Файл пакета обновления уже загружен и готов к установке."
#: src/chkthread.cpp:474
#, c-format
msgid "Downloading update package %s..."
msgstr "Загрузка пакета обновления %s ..."
#: src/chkthread.cpp:477
msgid "Error response received."
msgstr "Получен ошибочный ответ."
#: src/chkthread.cpp:504
msgid "Update package downloaded and ready to install."
msgstr "Пакет обновления загружен и готов к установке."
#: src/chkthread.cpp:507
msgid "Update package file corrupt."
msgstr "Файл пакета обновления испорчен."
#: src/chkthread.cpp:516
msgid "Launching update..."
msgstr "Запуск обновления ..."
#: src/chkthread.cpp:535
#, c-format
msgid "msiexec.exe launch succeeded. For detailed information, see %s file."
msgstr ""
"Запуск msiexec.exe успешно выполнен. Для получения подробной информации см. "
"файл %s."
#: src/chkthread.cpp:538
#, c-format
msgid "msiexec.exe launch failed. ShellExecute returned %i."
msgstr "Запуск msiexec.exe завершился ошибкой. ShellExecute возвратил %i."

142
Updater/locale/sl_SI.po Normal file
View File

@ -0,0 +1,142 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Updater\n"
"POT-Creation-Date: 2018-09-19 08:59+0200\n"
"PO-Revision-Date: 2016-02-06 09:04+0100\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2018\n"
"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/amebis/teams/91597/sl_SI/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: src\n"
"X-Poedit-SearchPath-1: include\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: src/chkthread.cpp:111 src/chkthread.cpp:125
msgid "Update check complete. Your product is up to date."
msgstr "Preverjanje posodobitev končano. Nameščena je najnovejša različica."
#: src/chkthread.cpp:145
msgid "Downloading repository catalogue..."
msgstr "Prenos repozitorijevega kataloga ..."
#: src/chkthread.cpp:153
#, c-format
msgid "Contacting repository at %s..."
msgstr "Dostop do repozitorija na %s ..."
#: src/chkthread.cpp:161
#, c-format
msgid "Error resolving %s server name."
msgstr "Napaka pri ugotavljanju naslova strežnika %s."
#: src/chkthread.cpp:167
msgid "Repository did not change since the last time."
msgstr "Repozitorij se od zadnjič ni spremenil."
#: src/chkthread.cpp:170
#, c-format
msgid "%u status received from server %s (port %u) requesting %s."
msgstr "Prejet status %u s strežnika %s (vrata %u) pri zahtevi za %s."
#: src/chkthread.cpp:173
#, c-format
msgid "Error response received from server %s (port %u) requesting %s."
msgstr "Prejet odgovor o napaki s strežnika %s (vrata %u) pri zahtevi za %s."
#: src/chkthread.cpp:184 src/chkthread.cpp:454
#, c-format
msgid "Can not open/create %s file for writing."
msgstr "Ne morem odpreti/ustvariti datoteke %s za pisanje."
#: src/chkthread.cpp:197 src/chkthread.cpp:493
#, c-format
msgid "Can not write to %s file."
msgstr "Ne morem pisati v datoteko %s."
#: src/chkthread.cpp:206
msgid "Error loading repository catalogue."
msgstr "Napaka pri nalaganju repozitorijevega kataloga."
#: src/chkthread.cpp:212
msgid "Verifying repository catalogue signature..."
msgstr "Preverjanje podpisa repozitorijevega kataloga ..."
#: src/chkthread.cpp:243
msgid "Signature not found in the repository catalogue."
msgstr "V repozitorijevem katalogu ni podpisa."
#: src/chkthread.cpp:256
msgid ""
"Repository catalogue signature does not match its content, or signature "
"verification failed."
msgstr ""
"Podpis repozitorijevega kataloga ne ustreza njegovi vsebini, oziroma "
"preverjanje podpisa ni uspelo."
#: src/chkthread.cpp:263
#, c-format
msgid ""
"Invalid root element in repository catalogue (actual: %s, expected: %s)."
msgstr ""
"Napačen korenski element v repozitorijevem katalogu (dejanski: %s, "
"pričakovan: %s)."
#: src/chkthread.cpp:280
msgid "Parsing repository catalogue..."
msgstr "Razčlemba repozitorijevega kataloga ..."
#: src/chkthread.cpp:365
#, c-format
msgid "Update package found (version: %s)."
msgstr "Posodobitveni paket najden (verzija: %s)."
#: src/chkthread.cpp:423
msgid ""
"Reading update package meta-information from cache failed or incomplete."
msgstr ""
"Branje meta-informacij posodobitvenega paketa iz predpomnilnika ni uspelo "
"ali ni bilo celotno."
#: src/chkthread.cpp:446
msgid "Update package file already downloaded and ready to install."
msgstr "Posodobitveni paket je že prenesen in pripravljen na namestitev."
#: src/chkthread.cpp:474
#, c-format
msgid "Downloading update package %s..."
msgstr "Prenos posodobitvenega paketa %s ..."
#: src/chkthread.cpp:477
msgid "Error response received."
msgstr "Prejet odgovor o napaki."
#: src/chkthread.cpp:504
msgid "Update package downloaded and ready to install."
msgstr "Posodobitveni paket je prenesen in pripravljen na namestitev."
#: src/chkthread.cpp:507
msgid "Update package file corrupt."
msgstr "Posodobitveni paket je pokvarjen."
#: src/chkthread.cpp:516
msgid "Launching update..."
msgstr "Zagon posodobitve ..."
#: src/chkthread.cpp:535
#, c-format
msgid "msiexec.exe launch succeeded. For detailed information, see %s file."
msgstr ""
"Zagon msiexec.exe je uspel. Za podrobnejše informacije glejte datoteko %s."
#: src/chkthread.cpp:538
#, c-format
msgid "msiexec.exe launch failed. ShellExecute returned %i."
msgstr "Zagon msiexec.exe ni uspel. ShellExecute je vrnil %i."

BIN
Updater/res/Updater.rc Normal file

Binary file not shown.

531
Updater/src/chkthread.cpp Normal file
View File

@ -0,0 +1,531 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
// wxEVT_UPDATER_CHECK_COMPLETE
//////////////////////////////////////////////////////////////////////////
wxDEFINE_EVENT(wxEVT_UPDATER_CHECK_COMPLETE, wxThreadEvent);
//////////////////////////////////////////////////////////////////////////
// wxUpdCheckThread
//////////////////////////////////////////////////////////////////////////
wxUpdCheckThread::wxUpdCheckThread(const wxString &langId, wxEvtHandler *parent) :
m_parent(parent),
m_ok(true),
m_abort(false),
m_langId(langId),
m_config(wxT(PRODUCT_CFG_APPLICATION) wxT("\\Updater"), wxT(PRODUCT_CFG_VENDOR)),
m_cs(NULL),
m_ck(NULL),
m_version(0),
wxThread(wxTHREAD_JOINABLE)
{
m_path = wxFileName::GetTempDir();
if (!wxEndsWithPathSeparator(m_path))
m_path += wxFILE_SEP_PATH;
if (!wxDirExists(m_path))
wxMkdir(m_path);
m_cs = new wxCryptoSessionRSAAES();
wxCHECK2_MSG(m_cs, { m_ok = false; return; }, wxT("wxCryptoSessionRSAAES creation failed"));
// Import public key.
HRSRC res = ::FindResource(g_hInstance, MAKEINTRESOURCE(UPDATER_IDR_KEY_PUBLIC), RT_RCDATA);
wxCHECK2_MSG(res, { m_ok = false; return; }, wxT("public key not found"));
HGLOBAL res_handle = ::LoadResource(g_hInstance, res);
wxCHECK2_MSG(res_handle, { m_ok = false; return; }, wxT("loading resource failed"));
m_ck = new wxCryptoKey();
wxCHECK2_MSG(m_ck, { m_ok = false; return; }, wxT("wxCryptoKey creation failed"));
wxCHECK2(m_ck->ImportPublic(*m_cs, ::LockResource(res_handle), ::SizeofResource(g_hInstance, res)), { m_ok = false; return; });
}
wxUpdCheckThread::~wxUpdCheckThread()
{
if (m_ck) delete m_ck;
if (m_cs) delete m_cs;
}
wxThread::ExitCode wxUpdCheckThread::Entry()
{
wxResult result = DoCheckForUpdate();
if (m_parent) {
// Signal the event handler that this thread is going to be destroyed.
// NOTE: here we assume that using the m_parent pointer is safe,
// (in this case this is assured by the wxZRColaCharSelect destructor)
wxThreadEvent *e = new wxThreadEvent(wxEVT_UPDATER_CHECK_COMPLETE);
e->SetInt(static_cast<int>(result));
wxQueueEvent(m_parent, e);
}
return reinterpret_cast<wxThread::ExitCode>(static_cast<intptr_t>(result) & 0xffffffff);
}
bool wxUpdCheckThread::TestDestroy()
{
return m_abort || wxThread::TestDestroy();
}
wxUpdCheckThread::wxResult wxUpdCheckThread::DoCheckForUpdate()
{
if (!m_ok)
return wxResult::Uninitialized;
// Download update catalogue.
if (TestDestroy()) return wxResult::Aborted;
wxScopedPtr<wxXmlDocument> doc(GetCatalogue());
if (doc) {
// Parse the update catalogue to check for an update package availability.
if (TestDestroy()) return wxResult::Aborted;
if (ParseCatalogue(*doc)) {
// Save update package meta-information for the next time.
if (TestDestroy()) return wxResult::Aborted;
WriteUpdatePackageMeta();
} else {
wxLogStatus(_("Update check complete. Your product is up to date."));
WriteUpdatePackageMeta();
return wxResult::UpToDate;
}
} else {
// Update download catalogue failed, or repository database didn't change. Read a cached version of update package meta-information?
if (TestDestroy()) return wxResult::Aborted;
if (!ReadUpdatePackageMeta()) {
// Reset CatalogueLastModified to force update catalogue download next time.
m_config.DeleteEntry(wxT("CatalogueLastModified"), false);
return wxResult::RepoUnavailable;
}
if (m_version <= PRODUCT_VERSION) {
wxLogStatus(_("Update check complete. Your product is up to date."));
return wxResult::UpToDate;
}
}
m_fileName = m_path;
m_fileName += wxT("Updater-") wxT(PRODUCT_CFG_APPLICATION) wxT("-");
m_fileName += m_versionStr;
m_fileName += wxT(".msi");
if (TestDestroy()) return wxResult::Aborted;
if (!DownloadUpdatePackage())
return wxResult::PkgUnavailable;
return wxResult::UpdateAvailable;
}
wxXmlDocument* wxUpdCheckThread::GetCatalogue()
{
wxLogStatus(_("Downloading repository catalogue..."));
wxString lastModified;
m_config.Read(wxT("CatalogueLastModified"), &lastModified, wxEmptyString);
for (const wxChar *server = wxT(UPDATER_HTTP_SERVER); server[0]; server += wcslen(server) + 1) {
if (TestDestroy()) return NULL;
wxLogStatus(_("Contacting repository at %s..."), server);
// Load repository database.
wxHTTP http;
http.SetHeader(wxS("User-Agent"), wxS("Updater-") wxT(PRODUCT_CFG_APPLICATION) wxS("/") wxS(PRODUCT_VERSION_STR));
if (!lastModified.IsEmpty())
http.SetHeader(wxS("If-Modified-Since"), lastModified);
if (!http.Connect(server, UPDATER_HTTP_PORT)) {
wxLogWarning(_("Error resolving %s server name."), server);
continue;
}
wxScopedPtr<wxInputStream> httpStream(http.GetInputStream(wxS(UPDATER_HTTP_PATH)));
const int status = http.GetResponse();
if (status == 304) {
wxLogStatus(_("Repository did not change since the last time."));
return NULL;
} else if (status != 200) {
wxLogWarning(_("%u status received from server %s (port %u) requesting %s."), status, server, UPDATER_HTTP_PORT, UPDATER_HTTP_PATH);
continue;
} else if (!httpStream) {
wxLogWarning(_("Error response received from server %s (port %u) requesting %s."), server, UPDATER_HTTP_PORT, UPDATER_HTTP_PATH);
continue;
} else if (TestDestroy())
return NULL;
// wxXmlDocument::Load() fails reading from wxInputStream directly (in non-main threads).
// Therefore, save the repository catalog to temporary file first.
wxString fileName(m_path);
fileName += wxT("Updater-catalog.xml");
wxFFile file(fileName, wxT("wb"));
if (!file.IsOpened()) {
wxLogError(_("Can not open/create %s file for writing."), fileName.c_str());
return NULL;
}
wxMemoryBuffer buf(4*1024);
char *data = static_cast<char*>(buf.GetData());
const size_t nBlock = buf.GetBufSize();
do {
if (TestDestroy()) return NULL;
httpStream->Read(data, nBlock);
const size_t nRead = httpStream->LastRead();
file.Write(data, nRead);
if (file.Error()) {
wxLogError(_("Can not write to %s file."), fileName.c_str());
return NULL;
}
} while (httpStream->IsOk());
file.Close();
// Read the repository catalog.
wxScopedPtr<wxXmlDocument> doc(new wxXmlDocument());
if (!doc->Load(fileName, "UTF-8", wxXMLDOC_KEEP_WHITESPACE_NODES)) {
wxLogWarning(_("Error loading repository catalogue."));
continue;
}
m_config.Write(wxT("CatalogueLastModified"), http.GetHeader(wxT("Last-Modified")));
wxRemoveFile(fileName);
wxLogStatus(_("Verifying repository catalogue signature..."));
// Find the (first) signature.
if (TestDestroy()) return NULL;
wxXmlNode *document = doc->GetDocumentNode();
wxMemoryBuffer sig;
for (wxXmlNode *prolog = document->GetChildren(); prolog; prolog = prolog->GetNext()) {
#pragma warning(suppress: 26812) // wxXmlNodeType is unscoped.
if (prolog->GetType() == wxXML_COMMENT_NODE) {
wxString content = prolog->GetContent();
const size_t content_len = content.length();
if (content_len >= _countof(wxS(UPDATER_SIGNATURE_MARK)) - 1 &&
memcmp((const wxStringCharType*)content, wxS(UPDATER_SIGNATURE_MARK), sizeof(wxStringCharType)*(_countof(wxS(UPDATER_SIGNATURE_MARK)) - 1)) == 0)
{
// Read the signature.
const size_t signature_len = content_len - (_countof(wxS(UPDATER_SIGNATURE_MARK)) - 1);
const size_t len = wxBase64DecodedSize(signature_len);
const size_t res = wxBase64Decode(sig.GetWriteBuf(len), len, content.Right(signature_len), wxBase64DecodeMode_SkipWS);
if (res != wxCONV_FAILED) {
sig.SetDataLen(res);
// Remove the signature as it is not a part of the validation check.
document->RemoveChild(prolog);
wxDELETE(prolog);
break;
} else
sig.Clear();
}
}
}
if (sig.IsEmpty()) {
wxLogWarning(_("Signature not found in the repository catalogue."));
continue;
}
// Hash the content.
if (TestDestroy()) return NULL;
wxUpdaterHashChk ch(*m_cs);
if (!wxXmlHashNode(ch, document))
continue;
// We have the hash, we have the signature, we have the public key. Now verify.
if (TestDestroy()) return NULL;
if (!wxCryptoVerifySignature(ch, sig, *m_ck)) {
wxLogWarning(_("Repository catalogue signature does not match its content, or signature verification failed."));
continue;
}
// Verify document type (root element).
const wxString &nameRoot = doc->GetRoot()->GetName();
if (nameRoot != wxT("Packages")) {
wxLogWarning(_("Invalid root element in repository catalogue (actual: %s, expected: %s)."), nameRoot.c_str(), wxT("Packages"));
continue;
}
// The downloaded repository database passed all checks.
return doc.release();
}
// No repository database downloaded successfully.
return NULL;
}
bool wxUpdCheckThread::ParseCatalogue(const wxXmlDocument &doc)
{
bool found = false;
wxLogStatus(_("Parsing repository catalogue..."));
// Iterate over packages.
for (wxXmlNode *elPackage = doc.GetRoot()->GetChildren(); elPackage; elPackage = elPackage->GetNext()) {
if (TestDestroy()) return false;
if (elPackage->GetType() == wxXML_ELEMENT_NODE && elPackage->GetName() == wxT("Package")) {
// Get package version.
wxUint32 version = 0;
wxString versionStr;
for (wxXmlNode *elVersion = elPackage->GetChildren(); elVersion; elVersion = elVersion->GetNext()) {
if (elVersion->GetType() == wxXML_ELEMENT_NODE && elVersion->GetName() == wxT("Version")) {
for (wxXmlNode *elVersionNote = elVersion->GetChildren(); elVersionNote; elVersionNote = elVersionNote->GetNext()) {
if (elVersionNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elVersionNote->GetName();
if (name == wxT("hex"))
version = _tcstoul(elVersionNote->GetNodeContent(), NULL, 16);
else if (name == wxT("desc"))
versionStr = elVersionNote->GetNodeContent();
}
}
}
}
if (version <= PRODUCT_VERSION || version < m_version) {
// This package is older than currently installed product or the superseeded package found already.
continue;
}
// Get package download URL for our platform and language.
wxString platformId;
#if defined(__WINDOWS__)
platformId += wxT("win");
#endif
#if defined(_M_AMD64)
platformId += wxT("-amd64");
#elif defined(_M_ARM64)
platformId += wxT("-arm64");
#else
platformId += wxT("-x86");
#endif
wxArrayString urls;
wxMemoryBuffer hash;
for (wxXmlNode *elDownloads = elPackage->GetChildren(); elDownloads; elDownloads = elDownloads->GetNext()) {
if (elDownloads->GetType() == wxXML_ELEMENT_NODE && elDownloads->GetName() == wxT("Downloads")) {
for (wxXmlNode *elPlatform = elDownloads->GetChildren(); elPlatform; elPlatform = elPlatform->GetNext()) {
if (elPlatform->GetType() == wxXML_ELEMENT_NODE) {
if (elPlatform->GetName() == wxT("Platform") && elPlatform->GetAttribute(wxT("id")) == platformId) {
// Get language.
for (wxXmlNode *elLocale = elPlatform->GetChildren(); elLocale; elLocale = elLocale->GetNext()) {
if (elLocale->GetType() == wxXML_ELEMENT_NODE && elLocale->GetName() == wxT("Localization") && elLocale->GetAttribute(wxT("lang")) == m_langId) {
for (wxXmlNode *elLocaleNote = elLocale->GetChildren(); elLocaleNote; elLocaleNote = elLocaleNote->GetNext()) {
if (elLocaleNote->GetType() == wxXML_ELEMENT_NODE) {
const wxString &name = elLocaleNote->GetName();
if (name == wxT("url"))
urls.Add(elLocaleNote->GetNodeContent());
else if (name == wxT("hash")) {
// Read the hash.
wxString content(elLocaleNote->GetNodeContent());
const size_t len = wxHexDecodedSize(content.length());
const size_t res = wxHexDecode(hash.GetWriteBuf(len), len, content, wxHexDecodeMode::SkipWS);
if (res != wxCONV_FAILED)
hash.SetDataLen(res);
else
hash.Clear();
}
}
}
}
}
}
}
}
}
}
if (urls.empty() || hash.IsEmpty()) {
// This package is for different architecture and/or language.
// ... or missing URL and/or hash.
continue;
}
// Save found package info.
m_version = version;
m_versionStr = versionStr;
m_urls = urls;
m_hash = hash;
found = true;
wxLogMessage(_("Update package found (version: %s)."), m_versionStr.c_str());
}
}
return found;
}
bool wxUpdCheckThread::WriteUpdatePackageMeta()
{
// Concatenate URLs.
wxString urls;
for (size_t i = 0, n = m_urls.GetCount(); i < n; i++) {
if (i) urls += wxT('\n');
urls += m_urls[i];
}
bool result = true;
if (!m_config.Write(wxT("PackageVersion" ), m_version )) result = false;
if (!m_config.Write(wxT("PackageVersionDesc"), m_versionStr )) result = false;
if (!m_config.Write(wxT("PackageURLs" ), urls )) result = false;
if (!m_config.Write(wxT("PackageHash" ), wxHexEncode(m_hash))) result = false;
return result;
}
bool wxUpdCheckThread::ReadUpdatePackageMeta()
{
long lng;
if (m_config.Read(wxT("PackageVersion"), &lng)) {
m_version = lng;
if (m_config.Read(wxT("PackageVersionDesc"), &m_versionStr)) {
wxString str;
if (m_config.Read(wxT("PackageURLs"), &str)) {
// Split URLs
m_urls.Clear();
const wxStringCharType *buf = str;
for (size_t i = 0, j = 0, n = str.Length(); i < n;) {
for (; j < n && buf[j] != wxT('\n'); j++);
m_urls.Add(str.SubString(i, j - 1));
i = ++j;
}
if (m_config.Read(wxT("PackageHash"), &str)) {
// Convert to binary.
const size_t len = wxHexDecodedSize(str.length());
const size_t res = wxHexDecode(m_hash.GetWriteBuf(len), len, str, wxHexDecodeMode::SkipWS);
if (res != wxCONV_FAILED) {
m_hash.SetDataLen(res);
return true;
} else
m_hash.Clear();
}
}
}
}
wxLogWarning(_("Reading update package meta-information from cache failed or incomplete."));
m_version = 0;
m_versionStr.Clear();
m_urls.Clear();
m_hash.Clear();
return false;
}
bool wxUpdCheckThread::DownloadUpdatePackage()
{
if (wxFileExists(m_fileName)) {
// Calculate file hash.
wxUpdaterHashChk ch(*m_cs);
if (ch.HashFile(m_fileName)) {
wxMemoryBuffer buf;
ch.GetValue(buf);
if (buf.GetDataLen() == m_hash.GetDataLen() &&
memcmp(buf.GetData(), m_hash.GetData(), buf.GetDataLen()) == 0)
{
// Update package file exists and its hash is correct.
wxLogStatus(_("Update package file already downloaded and ready to install."));
return true;
}
}
}
wxFFile file(m_fileName, wxT("wb"));
if (!file.IsOpened()) {
wxLogError(_("Can not open/create %s file for writing."), m_fileName.c_str());
return false;
}
// Download update package file.
for (size_t i = 0, n = m_urls.GetCount(); i < n; i++) {
if (TestDestroy()) return false;
wxURL url(m_urls[i]);
if (!url.IsOk())
continue;
if (url.HasScheme()) {
const wxString scheme = url.GetScheme();
if (scheme == wxT("http") || scheme == wxT("https")) {
wxHTTP &http = (wxHTTP&)url.GetProtocol();
http.SetHeader(wxS("User-Agent"), wxS("Updater-") wxT(PRODUCT_CFG_APPLICATION) wxS("/") wxS(PRODUCT_VERSION_STR));
}
}
wxLogStatus(_("Downloading update package %s..."), m_urls[i].c_str());
wxScopedPtr<wxInputStream> stream(url.GetInputStream());
if (!stream) {
wxLogWarning(_("Error response received."));
continue;
}
// Save update package to file, and calculate hash.
wxUpdaterHashChk ch(*m_cs);
wxMemoryBuffer buf(4*1024);
char *data = static_cast<char*>(buf.GetData());
const size_t nBlock = buf.GetBufSize();
do {
if (TestDestroy()) return false;
stream->Read(data, nBlock);
const size_t nRead = stream->LastRead();
file.Write(data, nRead);
if (file.Error()) {
wxLogError(_("Can not write to %s file."), m_fileName.c_str());
return false;
}
ch.Hash(data, nRead);
} while (stream->IsOk());
ch.GetValue(buf);
if (buf.GetDataLen() == m_hash.GetDataLen() &&
memcmp(buf.GetData(), m_hash.GetData(), buf.GetDataLen()) == 0)
{
// Update package file downloaded and its hash is correct.
wxLogStatus(_("Update package downloaded and ready to install."));
return true;
} else
wxLogWarning(_("Update package file corrupt."));
}
return false;
}
bool wxUpdCheckThread::LaunchUpdate(WXHWND hParent, bool headless)
{
wxLogStatus(_("Launching update..."));
wxString param(headless ? wxT("/qn /norestart ") : wxEmptyString);
// Package
param += wxT("/i \"");
param += m_fileName;
param += wxT("\"");
// Logging
wxString fileNameLog(m_path);
fileNameLog += wxT("Updater-") wxT(PRODUCT_CFG_APPLICATION) wxT("-msiexec.log");
param += wxT(" /l* \"");
param += fileNameLog;
param += wxT("\"");
const intptr_t result = reinterpret_cast<intptr_t>(::ShellExecute(hParent, NULL, wxT("msiexec.exe"), param, NULL, SW_SHOWNORMAL));
if (result > 32) {
wxLogStatus(_("msiexec.exe launch succeeded. For detailed information, see %s file."), fileNameLog.c_str());
return true;
} else {
wxLogError(_("msiexec.exe launch failed. ShellExecute returned %i."), result);
return false;
}
}

26
Updater/src/main.cpp Normal file
View File

@ -0,0 +1,26 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"
///
/// Module instance
///
HINSTANCE g_hInstance = NULL;
///
/// Main function
///
BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) noexcept
{
UNREFERENCED_PARAMETER(lpvReserved);
if (fdwReason == DLL_PROCESS_ATTACH)
g_hInstance = hinstDLL;
return TRUE;
}

6
Updater/src/pch.cpp Normal file
View File

@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#include "pch.h"

26
Updater/src/pch.h Normal file
View File

@ -0,0 +1,26 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2016-2022 Amebis
*/
#pragma once
#include "../include/Updater/chkthread.h"
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/base64.h>
#include <wx/buffer.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/protocol/http.h>
#include <wx/url.h>
#pragma warning(pop)
#include <wxex/hex.h>
#include <wxex/xml.h>
//
// Private data declaration
//
extern HINSTANCE g_hInstance;

View File

@ -1,50 +0,0 @@
/*
Copyright 2016 Amebis
This file is part of Updater.
Updater is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
//
// Product version as a single DWORD
// Note: Used for version comparison within C/C++ code.
//
#define UPDATER_VERSION 0x01000000
//
// Product version by components
// Note: Resource Compiler has limited preprocessing capability,
// thus we need to specify major, minor and other version components
// separately.
//
#define UPDATER_VERSION_MAJ 1
#define UPDATER_VERSION_MIN 0
#define UPDATER_VERSION_REV 0
#define UPDATER_VERSION_BUILD 0
//
// Human readable product version and build year for UI
//
#define UPDATER_VERSION_STR "1.0"
#define UPDATER_BUILD_YEAR_STR "2016"
#if !defined(RC_INVOKED) && !defined(MIDL_PASS)
#define UPDATER_SIGNATURE_MARK "SHA1SIGN:"
#endif // !defined(RC_INVOKED) && !defined(MIDL_PASS)