New upstream version 21.1.2+dfsg1
This commit is contained in:
parent
baafb6325b
commit
665f64a933
152 changed files with 3957 additions and 356 deletions
|
|
@ -1,7 +1,3 @@
|
|||
if(NOT ENABLE_WIN_UPDATER)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(DISABLE_UPDATE_MODULE)
|
||||
return()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "updater.hpp"
|
||||
|
||||
#include <util/windows/WinHandle.hpp>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Updater.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "updater.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include <lzma.h>
|
||||
#ifdef _MSC_VER
|
||||
# define restrict __restrict
|
||||
# include <lzma.h>
|
||||
# undef restrict
|
||||
#else
|
||||
# include <lzma.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -234,7 +256,7 @@ try {
|
|||
|
||||
vector<uint8_t> newData;
|
||||
try {
|
||||
newData.resize(newsize);
|
||||
newData.resize((size_t)newsize);
|
||||
} catch (...) {
|
||||
throw int(-1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
/******************************************************************************
|
||||
Copyright (C) 2017 Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "updater.hpp"
|
||||
|
||||
|
|
@ -59,50 +57,48 @@ void FreeWinHttpHandle(HINTERNET handle)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
// http://www.codeproject.com/Articles/320748/Haephrati-Elevating-during-runtime
|
||||
static bool IsAppRunningAsAdminMode()
|
||||
static inline bool is_64bit_windows(void);
|
||||
|
||||
static inline bool HasVS2017Redist2()
|
||||
{
|
||||
BOOL fIsRunAsAdmin = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
PSID pAdministratorsGroup = nullptr;
|
||||
wchar_t base[MAX_PATH];
|
||||
wchar_t path[MAX_PATH];
|
||||
WIN32_FIND_DATAW wfd;
|
||||
HANDLE handle;
|
||||
int folder = (is32bit && is_64bit_windows())
|
||||
? CSIDL_SYSTEMX86
|
||||
: CSIDL_SYSTEM;
|
||||
|
||||
/* Allocate and initialize a SID of the administrators group. */
|
||||
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||||
if (!AllocateAndInitializeSid(&NtAuthority,
|
||||
2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&pAdministratorsGroup)) {
|
||||
dwError = GetLastError();
|
||||
goto Cleanup;
|
||||
}
|
||||
SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, base);
|
||||
|
||||
/* Determine whether the SID of administrators group is enabled in the
|
||||
* primary access token of the process. */
|
||||
if (!CheckTokenMembership(nullptr, pAdministratorsGroup,
|
||||
&fIsRunAsAdmin)) {
|
||||
dwError = GetLastError();
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
/* Centralized cleanup for all allocated resources. */
|
||||
if (pAdministratorsGroup) {
|
||||
FreeSid(pAdministratorsGroup);
|
||||
pAdministratorsGroup = nullptr;
|
||||
}
|
||||
|
||||
/* Throw the error if something failed in the function. */
|
||||
if (ERROR_SUCCESS != dwError)
|
||||
StringCbCopyW(path, sizeof(path), base);
|
||||
StringCbCatW(path, sizeof(path), L"\\msvcp140.dll");
|
||||
handle = FindFirstFileW(path, &wfd);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
} else {
|
||||
FindClose(handle);
|
||||
}
|
||||
|
||||
return !!fIsRunAsAdmin;
|
||||
StringCbCopyW(path, sizeof(path), base);
|
||||
StringCbCatW(path, sizeof(path), L"\\vcruntime140.dll");
|
||||
handle = FindFirstFileW(path, &wfd);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
} else {
|
||||
FindClose(handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HasVS2017Redist()
|
||||
{
|
||||
PVOID old = nullptr;
|
||||
bool redirect = !!Wow64DisableWow64FsRedirection(&old);
|
||||
bool success = HasVS2017Redist2();
|
||||
if (redirect) Wow64RevertWow64FsRedirection(old);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void Status(const wchar_t *fmt, ...)
|
||||
|
|
@ -608,6 +604,11 @@ static inline bool is_64bit_file(const char *file)
|
|||
strstr(file, "64.exe") != nullptr;
|
||||
}
|
||||
|
||||
static inline bool has_str(const char *file, const char *str)
|
||||
{
|
||||
return (file && str) ? (strstr(file, str) != nullptr) : false;
|
||||
}
|
||||
|
||||
#define UTF8ToWideBuf(wide, utf8) UTF8ToWide(wide, _countof(wide), utf8)
|
||||
#define WideToUTF8Buf(utf8, wide) WideToUTF8(utf8, _countof(utf8), wide)
|
||||
|
||||
|
|
@ -661,6 +662,12 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx,
|
|||
if (!isWin64 && is_64bit_file(fileUTF8))
|
||||
continue;
|
||||
|
||||
/* ignore update files of opposite arch to reduce download */
|
||||
|
||||
if (( is32bit && has_str(fileUTF8, "/64bit/")) ||
|
||||
(!is32bit && has_str(fileUTF8, "/32bit/")))
|
||||
continue;
|
||||
|
||||
/* convert strings to wide */
|
||||
|
||||
wchar_t sourceURL[1024];
|
||||
|
|
@ -930,6 +937,156 @@ static wchar_t tempPath[MAX_PATH] = {};
|
|||
#define HASH_NULL \
|
||||
L"0000000000000000000000000000000000000000"
|
||||
|
||||
static bool UpdateVS2017Redists(json_t *root)
|
||||
{
|
||||
/* ------------------------------------------ *
|
||||
* Initialize session */
|
||||
|
||||
const DWORD tlsProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
|
||||
|
||||
HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
|
||||
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME,
|
||||
WINHTTP_NO_PROXY_BYPASS,
|
||||
0);
|
||||
if (!hSession) {
|
||||
Status(L"Update failed: Couldn't open obsproject.com");
|
||||
return false;
|
||||
}
|
||||
|
||||
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
|
||||
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
|
||||
|
||||
HttpHandle hConnect = WinHttpConnect(hSession, L"obsproject.com",
|
||||
INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hConnect) {
|
||||
Status(L"Update failed: Couldn't connect to obsproject.com");
|
||||
return false;
|
||||
}
|
||||
|
||||
int responseCode;
|
||||
|
||||
DWORD waitResult = WaitForSingleObject(cancelRequested, 0);
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* Download redist */
|
||||
|
||||
Status(L"Downloading %s", L"Visual C++ 2017 Redistributable");
|
||||
|
||||
const wchar_t *file = (is32bit)
|
||||
? L"vc2017redist_x86.exe"
|
||||
: L"vc2017redist_x64.exe";
|
||||
|
||||
wstring sourceURL;
|
||||
sourceURL += L"https://obsproject.com/downloads/";
|
||||
sourceURL += file;
|
||||
|
||||
wstring destPath;
|
||||
destPath += tempPath;
|
||||
destPath += L"\\";
|
||||
destPath += file;
|
||||
|
||||
if (!HTTPGetFile(hConnect,
|
||||
sourceURL.c_str(),
|
||||
destPath.c_str(),
|
||||
L"Accept-Encoding: gzip",
|
||||
&responseCode)) {
|
||||
|
||||
DeleteFile(destPath.c_str());
|
||||
Status(L"Update failed: Could not download "
|
||||
L"%s (error code %d)",
|
||||
L"Visual C++ 2017 Redistributable",
|
||||
responseCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* Get expected hash */
|
||||
|
||||
json_t *redistJson = json_object_get(root, is32bit
|
||||
? "vc2017_redist_x86"
|
||||
: "vc2017_redist_x64");
|
||||
if (!redistJson) {
|
||||
Status(L"Update failed: Could not parse VC2017 redist json");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *expectedHashUTF8 = json_string_value(redistJson);
|
||||
wchar_t expectedHashWide[BLAKE2_HASH_STR_LENGTH];
|
||||
BYTE expectedHash[BLAKE2_HASH_LENGTH];
|
||||
|
||||
if (!UTF8ToWideBuf(expectedHashWide, expectedHashUTF8)) {
|
||||
DeleteFile(destPath.c_str());
|
||||
Status(L"Update failed: Couldn't convert Json for redist hash");
|
||||
return false;
|
||||
}
|
||||
|
||||
StringToHash(expectedHashWide, expectedHash);
|
||||
|
||||
wchar_t downloadHashWide[BLAKE2_HASH_STR_LENGTH];
|
||||
BYTE downloadHash[BLAKE2_HASH_LENGTH];
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* Get download hash */
|
||||
|
||||
if (!CalculateFileHash(destPath.c_str(), downloadHash)) {
|
||||
DeleteFile(destPath.c_str());
|
||||
Status(L"Update failed: Couldn't verify integrity of %s",
|
||||
L"Visual C++ 2017 Redistributable");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* If hashes do not match, integrity failed */
|
||||
|
||||
HashToString(downloadHash, downloadHashWide);
|
||||
if (wcscmp(expectedHashWide, downloadHashWide) != 0) {
|
||||
DeleteFile(destPath.c_str());
|
||||
Status(L"Update failed: Couldn't verify integrity of %s",
|
||||
L"Visual C++ 2017 Redistributable");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ *
|
||||
* If hashes match, install redist */
|
||||
|
||||
wchar_t commandline[MAX_PATH + MAX_PATH];
|
||||
StringCbPrintf(commandline, sizeof(commandline),
|
||||
L"%s /install /quiet /norestart", destPath.c_str());
|
||||
|
||||
PROCESS_INFORMATION pi = {};
|
||||
STARTUPINFO si = {};
|
||||
si.cb = sizeof(si);
|
||||
|
||||
bool success = !!CreateProcessW(destPath.c_str(), commandline,
|
||||
nullptr, nullptr, false, CREATE_NO_WINDOW,
|
||||
nullptr, nullptr, &si, &pi);
|
||||
if (success) {
|
||||
Status(L"Installing %s...", L"Visual C++ 2017 Redistributable");
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
} else {
|
||||
Status(L"Update failed: Could not execute "
|
||||
L"%s (error code %d)",
|
||||
L"Visual C++ 2017 Redistributable",
|
||||
(int)GetLastError());
|
||||
}
|
||||
|
||||
DeleteFile(destPath.c_str());
|
||||
|
||||
waitResult = WaitForSingleObject(cancelRequested, 0);
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool Update(wchar_t *cmdLine)
|
||||
{
|
||||
/* ------------------------------------- *
|
||||
|
|
@ -1091,6 +1248,15 @@ static bool Update(wchar_t *cmdLine)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Check for VS2017 redistributables */
|
||||
|
||||
if (!HasVS2017Redist()) {
|
||||
if (!UpdateVS2017Redists(root)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Generate file hash json */
|
||||
|
||||
|
|
@ -1219,7 +1385,7 @@ static bool Update(wchar_t *cmdLine)
|
|||
if (!RunDownloadWorkers(2))
|
||||
return false;
|
||||
|
||||
if (completedUpdates != updates.size()) {
|
||||
if ((size_t)completedUpdates != updates.size()) {
|
||||
Status(L"Update failed to download all files.");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1431,11 +1597,28 @@ static void RestartAsAdmin(LPWSTR lpCmdLine)
|
|||
}
|
||||
}
|
||||
|
||||
static bool HasElevation()
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
|
||||
PSID sid = nullptr;
|
||||
BOOL elevated = false;
|
||||
BOOL success;
|
||||
|
||||
success = AllocateAndInitializeSid(&sia, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid);
|
||||
if (success && sid) {
|
||||
CheckTokenMembership(nullptr, sid, &elevated);
|
||||
FreeSid(sid);
|
||||
}
|
||||
|
||||
return elevated;
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
||||
{
|
||||
INITCOMMONCONTROLSEX icce;
|
||||
|
||||
if (!IsAppRunningAsAdminMode()) {
|
||||
if (!HasElevation()) {
|
||||
HANDLE hLowMutex = CreateMutexW(nullptr, true,
|
||||
L"OBSUpdaterRunningAsNonAdminUser");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define WINVER 0x0600
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue