summaryrefslogtreecommitdiff
path: root/onlineupdate
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-01-06 05:42:34 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-05-19 03:43:28 +0200
commitc3d264b52d2516e00f641ed2f7bb71f367a6400b (patch)
tree0330ade14a1884063ba86b776abca78848a515bb /onlineupdate
parente88f080bacabe9d7196813aa6d17132a389c330b (diff)
use a more libreoffice like formatting
This formatting has been done by an astyle script. The idea is that with a consistent formatting it is much easier to bring in changes from Mozilla. Updating the code with the new version, running the astyle script and then looking through the diff seems like the most sensible option.
Diffstat (limited to 'onlineupdate')
-rw-r--r--onlineupdate/source/libmar/sign/nss_secutil.h18
-rw-r--r--onlineupdate/source/libmar/verify/cryptox.h12
-rw-r--r--onlineupdate/source/service/certificatecheck.cxx382
-rw-r--r--onlineupdate/source/service/certificatecheck.hxx8
-rw-r--r--onlineupdate/source/service/maintenanceservice.cxx517
-rw-r--r--onlineupdate/source/service/maintenanceservice.hxx4
-rw-r--r--onlineupdate/source/service/registrycertificates.cxx214
-rw-r--r--onlineupdate/source/service/resource.hxx2
-rw-r--r--onlineupdate/source/service/servicebase.cxx114
-rw-r--r--onlineupdate/source/service/servicebase.hxx2
-rw-r--r--onlineupdate/source/service/serviceinstall.cxx1232
-rw-r--r--onlineupdate/source/service/serviceinstall.hxx4
-rw-r--r--onlineupdate/source/service/workmonitor.cxx1062
-rw-r--r--onlineupdate/source/update/common/pathhash.cxx177
-rw-r--r--onlineupdate/source/update/common/readstrings.cxx315
-rw-r--r--onlineupdate/source/update/common/readstrings.h8
-rw-r--r--onlineupdate/source/update/common/uachelper.cxx261
-rw-r--r--onlineupdate/source/update/common/uachelper.h16
-rw-r--r--onlineupdate/source/update/common/updatedefines.h14
-rw-r--r--onlineupdate/source/update/common/updatehelper.cxx986
-rw-r--r--onlineupdate/source/update/common/updatelogging.cxx71
-rw-r--r--onlineupdate/source/update/common/updatelogging.h40
-rw-r--r--onlineupdate/source/update/common/win_dirent.h18
-rw-r--r--onlineupdate/source/update/updater/archivereader.cxx368
-rw-r--r--onlineupdate/source/update/updater/archivereader.h29
-rw-r--r--onlineupdate/source/update/updater/bspatch.cxx230
-rw-r--r--onlineupdate/source/update/updater/bspatch.h46
-rw-r--r--onlineupdate/source/update/updater/loaddlls.cxx169
-rw-r--r--onlineupdate/source/update/updater/primaryCert.h3
-rw-r--r--onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx37
-rw-r--r--onlineupdate/source/update/updater/progressui.h18
-rw-r--r--onlineupdate/source/update/updater/progressui_gtk.cxx114
-rw-r--r--onlineupdate/source/update/updater/progressui_null.cxx4
-rw-r--r--onlineupdate/source/update/updater/progressui_win.cxx401
-rw-r--r--onlineupdate/source/update/updater/secondaryCert.h3
-rw-r--r--onlineupdate/source/update/updater/updater.cxx1761
-rw-r--r--onlineupdate/source/update/updater/win_dirent.cxx78
-rw-r--r--onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx513
-rw-r--r--onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h210
-rw-r--r--onlineupdate/source/winhelper/windowsStart.cxx341
40 files changed, 5373 insertions, 4429 deletions
diff --git a/onlineupdate/source/libmar/sign/nss_secutil.h b/onlineupdate/source/libmar/sign/nss_secutil.h
index 363c64918068..f599fcce573d 100644
--- a/onlineupdate/source/libmar/sign/nss_secutil.h
+++ b/onlineupdate/source/libmar/sign/nss_secutil.h
@@ -16,14 +16,16 @@
#include "key.h"
#include <stdint.h>
-typedef struct {
- enum {
- PW_NONE = 0,
- PW_FROMFILE = 1,
- PW_PLAINTEXT = 2,
- PW_EXTERNAL = 3
- } source;
- char *data;
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
} secuPWData;
#if( defined(_WINDOWS) && !defined(_WIN32_WCE))
diff --git a/onlineupdate/source/libmar/verify/cryptox.h b/onlineupdate/source/libmar/verify/cryptox.h
index d08ef159a83c..eb8548fa7a4f 100644
--- a/onlineupdate/source/libmar/verify/cryptox.h
+++ b/onlineupdate/source/libmar/verify/cryptox.h
@@ -77,9 +77,9 @@ CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData,
unsigned int aDataSize,
CryptoX_PublicKey* aPublicKey);
CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
- CryptoX_PublicKey* aPublicKey,
- const unsigned char* aSignature,
- unsigned int aSignatureLen);
+ CryptoX_PublicKey* aPublicKey,
+ const unsigned char* aSignature,
+ unsigned int aSignatureLen);
void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData);
void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey);
#ifdef __cplusplus
@@ -118,9 +118,9 @@ CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash);
CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH* hash,
BYTE *buf, DWORD len);
CryptoX_Result CyprtoAPI_VerifySignature(HCRYPTHASH *hash,
- HCRYPTKEY *pubKey,
- const BYTE *signature,
- DWORD signatureLen);
+ HCRYPTKEY *pubKey,
+ const BYTE *signature,
+ DWORD signatureLen);
#define CryptoX_InvalidHandleValue ((ULONG_PTR)NULL)
#define CryptoX_ProviderHandle HCRYPTPROV
diff --git a/onlineupdate/source/service/certificatecheck.cxx b/onlineupdate/source/service/certificatecheck.cxx
index 3a9eba020ccb..58d70162f40c 100644
--- a/onlineupdate/source/service/certificatecheck.cxx
+++ b/onlineupdate/source/service/certificatecheck.cxx
@@ -28,87 +28,97 @@ DWORD
CheckCertificateForPEFile(LPCWSTR filePath,
CertificateCheckInfo &infoToMatch)
{
- HCERTSTORE certStore = nullptr;
- HCRYPTMSG cryptMsg = nullptr;
- PCCERT_CONTEXT certContext = nullptr;
- PCMSG_SIGNER_INFO signerInfo = nullptr;
- DWORD lastError = ERROR_SUCCESS;
+ HCERTSTORE certStore = nullptr;
+ HCRYPTMSG cryptMsg = nullptr;
+ PCCERT_CONTEXT certContext = nullptr;
+ PCMSG_SIGNER_INFO signerInfo = nullptr;
+ DWORD lastError = ERROR_SUCCESS;
- // Get the HCERTSTORE and HCRYPTMSG from the signed file.
- DWORD encoding, contentType, formatType;
- BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
- filePath,
- CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
- CERT_QUERY_CONTENT_FLAG_ALL,
- 0, &encoding, &contentType,
- &formatType, &certStore, &cryptMsg, nullptr);
- if (!result) {
- lastError = GetLastError();
- LOG_WARN(("CryptQueryObject failed. (%d)", lastError));
- goto cleanup;
- }
+ // Get the HCERTSTORE and HCRYPTMSG from the signed file.
+ DWORD encoding, contentType, formatType;
+ BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
+ filePath,
+ CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
+ CERT_QUERY_CONTENT_FLAG_ALL,
+ 0, &encoding, &contentType,
+ &formatType, &certStore, &cryptMsg, nullptr);
+ if (!result)
+ {
+ lastError = GetLastError();
+ LOG_WARN(("CryptQueryObject failed. (%d)", lastError));
+ goto cleanup;
+ }
- // Pass in nullptr to get the needed signer information size.
- DWORD signerInfoSize;
- result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
- nullptr, &signerInfoSize);
- if (!result) {
- lastError = GetLastError();
- LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
- goto cleanup;
- }
+ // Pass in nullptr to get the needed signer information size.
+ DWORD signerInfoSize;
+ result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
+ nullptr, &signerInfoSize);
+ if (!result)
+ {
+ lastError = GetLastError();
+ LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
+ goto cleanup;
+ }
- // Allocate the needed size for the signer information.
- signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signerInfoSize);
- if (!signerInfo) {
- lastError = GetLastError();
- LOG_WARN(("Unable to allocate memory for Signer Info. (%d)", lastError));
- goto cleanup;
- }
+ // Allocate the needed size for the signer information.
+ signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signerInfoSize);
+ if (!signerInfo)
+ {
+ lastError = GetLastError();
+ LOG_WARN(("Unable to allocate memory for Signer Info. (%d)", lastError));
+ goto cleanup;
+ }
- // Get the signer information (PCMSG_SIGNER_INFO).
- // In particular we want the issuer and serial number.
- result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
- (PVOID)signerInfo, &signerInfoSize);
- if (!result) {
- lastError = GetLastError();
- LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
- goto cleanup;
- }
+ // Get the signer information (PCMSG_SIGNER_INFO).
+ // In particular we want the issuer and serial number.
+ result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
+ (PVOID)signerInfo, &signerInfoSize);
+ if (!result)
+ {
+ lastError = GetLastError();
+ LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
+ goto cleanup;
+ }
- // Search for the signer certificate in the certificate store.
- CERT_INFO certInfo;
- certInfo.Issuer = signerInfo->Issuer;
- certInfo.SerialNumber = signerInfo->SerialNumber;
- certContext = CertFindCertificateInStore(certStore, ENCODING, 0,
- CERT_FIND_SUBJECT_CERT,
- (PVOID)&certInfo, nullptr);
- if (!certContext) {
- lastError = GetLastError();
- LOG_WARN(("CertFindCertificateInStore failed. (%d)", lastError));
- goto cleanup;
- }
+ // Search for the signer certificate in the certificate store.
+ CERT_INFO certInfo;
+ certInfo.Issuer = signerInfo->Issuer;
+ certInfo.SerialNumber = signerInfo->SerialNumber;
+ certContext = CertFindCertificateInStore(certStore, ENCODING, 0,
+ CERT_FIND_SUBJECT_CERT,
+ (PVOID)&certInfo, nullptr);
+ if (!certContext)
+ {
+ lastError = GetLastError();
+ LOG_WARN(("CertFindCertificateInStore failed. (%d)", lastError));
+ goto cleanup;
+ }
- if (!DoCertificateAttributesMatch(certContext, infoToMatch)) {
- lastError = ERROR_NOT_FOUND;
- LOG_WARN(("Certificate did not match issuer or name. (%d)", lastError));
- goto cleanup;
- }
+ if (!DoCertificateAttributesMatch(certContext, infoToMatch))
+ {
+ lastError = ERROR_NOT_FOUND;
+ LOG_WARN(("Certificate did not match issuer or name. (%d)", lastError));
+ goto cleanup;
+ }
cleanup:
- if (signerInfo) {
- LocalFree(signerInfo);
- }
- if (certContext) {
- CertFreeCertificateContext(certContext);
- }
- if (certStore) {
- CertCloseStore(certStore, 0);
- }
- if (cryptMsg) {
- CryptMsgClose(cryptMsg);
- }
- return lastError;
+ if (signerInfo)
+ {
+ LocalFree(signerInfo);
+ }
+ if (certContext)
+ {
+ CertFreeCertificateContext(certContext);
+ }
+ if (certStore)
+ {
+ CertCloseStore(certStore, 0);
+ }
+ if (cryptMsg)
+ {
+ CryptMsgClose(cryptMsg);
+ }
+ return lastError;
}
/**
@@ -122,86 +132,96 @@ BOOL
DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
CertificateCheckInfo &infoToMatch)
{
- DWORD dwData;
- LPTSTR szName = nullptr;
+ DWORD dwData;
+ LPTSTR szName = nullptr;
- if (infoToMatch.issuer) {
- // Pass in nullptr to get the needed size of the issuer buffer.
- dwData = CertGetNameString(certContext,
- CERT_NAME_SIMPLE_DISPLAY_TYPE,
- CERT_NAME_ISSUER_FLAG, nullptr,
- nullptr, 0);
+ if (infoToMatch.issuer)
+ {
+ // Pass in nullptr to get the needed size of the issuer buffer.
+ dwData = CertGetNameString(certContext,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, nullptr,
+ nullptr, 0);
- if (!dwData) {
- LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
- return FALSE;
- }
+ if (!dwData)
+ {
+ LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
+ return FALSE;
+ }
- // Allocate memory for Issuer name buffer.
- LPTSTR szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
- if (!szName) {
- LOG_WARN(("Unable to allocate memory for issuer name. (%d)",
- GetLastError()));
- return FALSE;
- }
+ // Allocate memory for Issuer name buffer.
+ LPTSTR szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
+ if (!szName)
+ {
+ LOG_WARN(("Unable to allocate memory for issuer name. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
- // Get Issuer name.
- if (!CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
- CERT_NAME_ISSUER_FLAG, nullptr, szName, dwData)) {
- LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
- LocalFree(szName);
- return FALSE;
- }
+ // Get Issuer name.
+ if (!CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, nullptr, szName, dwData))
+ {
+ LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
+ LocalFree(szName);
+ return FALSE;
+ }
- // If the issuer does not match, return a failure.
- if (!infoToMatch.issuer ||
- wcscmp(szName, infoToMatch.issuer)) {
- LocalFree(szName);
- return FALSE;
+ // If the issuer does not match, return a failure.
+ if (!infoToMatch.issuer ||
+ wcscmp(szName, infoToMatch.issuer))
+ {
+ LocalFree(szName);
+ return FALSE;
+ }
+
+ LocalFree(szName);
+ szName = nullptr;
}
- LocalFree(szName);
- szName = nullptr;
- }
+ if (infoToMatch.name)
+ {
+ // Pass in nullptr to get the needed size of the name buffer.
+ dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ 0, nullptr, nullptr, 0);
+ if (!dwData)
+ {
+ LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
+ return FALSE;
+ }
- if (infoToMatch.name) {
- // Pass in nullptr to get the needed size of the name buffer.
- dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
- 0, nullptr, nullptr, 0);
- if (!dwData) {
- LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
- return FALSE;
- }
+ // Allocate memory for the name buffer.
+ szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
+ if (!szName)
+ {
+ LOG_WARN(("Unable to allocate memory for subject name. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
- // Allocate memory for the name buffer.
- szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
- if (!szName) {
- LOG_WARN(("Unable to allocate memory for subject name. (%d)",
- GetLastError()));
- return FALSE;
- }
+ // Obtain the name.
+ if (!(CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
+ nullptr, szName, dwData)))
+ {
+ LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
+ LocalFree(szName);
+ return FALSE;
+ }
- // Obtain the name.
- if (!(CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
- nullptr, szName, dwData))) {
- LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
- LocalFree(szName);
- return FALSE;
- }
+ // If the issuer does not match, return a failure.
+ if (!infoToMatch.name ||
+ wcscmp(szName, infoToMatch.name))
+ {
+ LocalFree(szName);
+ return FALSE;
+ }
- // If the issuer does not match, return a failure.
- if (!infoToMatch.name ||
- wcscmp(szName, infoToMatch.name)) {
- LocalFree(szName);
- return FALSE;
+ // We have a match!
+ LocalFree(szName);
}
- // We have a match!
- LocalFree(szName);
- }
-
- // If there were any errors we would have aborted by now.
- return TRUE;
+ // If there were any errors we would have aborted by now.
+ return TRUE;
}
/**
@@ -213,12 +233,13 @@ DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
LPWSTR
AllocateAndCopyWideString(LPCWSTR inputString)
{
- LPWSTR outputString =
- (LPWSTR)LocalAlloc(LPTR, (wcslen(inputString) + 1) * sizeof(WCHAR));
- if (outputString) {
- lstrcpyW(outputString, inputString);
- }
- return outputString;
+ LPWSTR outputString =
+ (LPWSTR)LocalAlloc(LPTR, (wcslen(inputString) + 1) * sizeof(WCHAR));
+ if (outputString)
+ {
+ lstrcpyW(outputString, inputString);
+ }
+ return outputString;
}
/**
@@ -230,41 +251,42 @@ AllocateAndCopyWideString(LPCWSTR inputString)
DWORD
VerifyCertificateTrustForFile(LPCWSTR filePath)
{
- // Setup the file to check.
- WINTRUST_FILE_INFO fileToCheck;
- ZeroMemory(&fileToCheck, sizeof(fileToCheck));
- fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
- fileToCheck.pcwszFilePath = filePath;
+ // Setup the file to check.
+ WINTRUST_FILE_INFO fileToCheck;
+ ZeroMemory(&fileToCheck, sizeof(fileToCheck));
+ fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
+ fileToCheck.pcwszFilePath = filePath;
- // Setup what to check, we want to check it is signed and trusted.
- WINTRUST_DATA trustData;
- ZeroMemory(&trustData, sizeof(trustData));
- trustData.cbStruct = sizeof(trustData);
- trustData.pPolicyCallbackData = nullptr;
- trustData.pSIPClientData = nullptr;
- trustData.dwUIChoice = WTD_UI_NONE;
- trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
- trustData.dwUnionChoice = WTD_CHOICE_FILE;
- trustData.dwStateAction = 0;
- trustData.hWVTStateData = nullptr;
- trustData.pwszURLReference = nullptr;
- // no UI
- trustData.dwUIContext = 0;
- trustData.pFile = &fileToCheck;
+ // Setup what to check, we want to check it is signed and trusted.
+ WINTRUST_DATA trustData;
+ ZeroMemory(&trustData, sizeof(trustData));
+ trustData.cbStruct = sizeof(trustData);
+ trustData.pPolicyCallbackData = nullptr;
+ trustData.pSIPClientData = nullptr;
+ trustData.dwUIChoice = WTD_UI_NONE;
+ trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
+ trustData.dwUnionChoice = WTD_CHOICE_FILE;
+ trustData.dwStateAction = 0;
+ trustData.hWVTStateData = nullptr;
+ trustData.pwszURLReference = nullptr;
+ // no UI
+ trustData.dwUIContext = 0;
+ trustData.pFile = &fileToCheck;
- GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
- // Check if the file is signed by something that is trusted.
- LONG ret = WinVerifyTrust(nullptr, &policyGUID, &trustData);
- if (ERROR_SUCCESS == ret) {
- // The hash that represents the subject is trusted and there were no
- // verification errors. No publisher nor time stamp chain errors.
- LOG(("The file \"%ls\" is signed and the signature was verified.",
- filePath));
- return ERROR_SUCCESS;
- }
+ GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ // Check if the file is signed by something that is trusted.
+ LONG ret = WinVerifyTrust(nullptr, &policyGUID, &trustData);
+ if (ERROR_SUCCESS == ret)
+ {
+ // The hash that represents the subject is trusted and there were no
+ // verification errors. No publisher nor time stamp chain errors.
+ LOG(("The file \"%ls\" is signed and the signature was verified.",
+ filePath));
+ return ERROR_SUCCESS;
+ }
- DWORD lastError = GetLastError();
- LOG_WARN(("There was an error validating trust of the certificate for file"
- " \"%ls\". Returned: %d. (%d)", filePath, ret, lastError));
- return ret;
+ DWORD lastError = GetLastError();
+ LOG_WARN(("There was an error validating trust of the certificate for file"
+ " \"%ls\". Returned: %d. (%d)", filePath, ret, lastError));
+ return ret;
}
diff --git a/onlineupdate/source/service/certificatecheck.hxx b/onlineupdate/source/service/certificatecheck.hxx
index 43a7c85b6b77..1efbcb153a65 100644
--- a/onlineupdate/source/service/certificatecheck.hxx
+++ b/onlineupdate/source/service/certificatecheck.hxx
@@ -9,14 +9,14 @@
struct CertificateCheckInfo
{
- LPCWSTR name;
- LPCWSTR issuer;
+ LPCWSTR name;
+ LPCWSTR issuer;
};
-BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT pCertContext,
+BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT pCertContext,
CertificateCheckInfo &infoToMatch);
DWORD VerifyCertificateTrustForFile(LPCWSTR filePath);
-DWORD CheckCertificateForPEFile(LPCWSTR filePath,
+DWORD CheckCertificateForPEFile(LPCWSTR filePath,
CertificateCheckInfo &infoToMatch);
#endif
diff --git a/onlineupdate/source/service/maintenanceservice.cxx b/onlineupdate/source/service/maintenanceservice.cxx
index 8471bdbd56c5..036bfe25192f 100644
--- a/onlineupdate/source/service/maintenanceservice.cxx
+++ b/onlineupdate/source/service/maintenanceservice.cxx
@@ -33,92 +33,106 @@ BOOL GetLogDirectoryPath(WCHAR *path);
int
wmain(int argc, WCHAR **argv)
{
- if (argc < 2)
- {
- LOG_WARN(("missing mandatory command line argument"));
- return 1;
- }
- // If command-line parameter is "install", install the service
- // or upgrade if already installed
- // If command line parameter is "forceinstall", install the service
- // even if it is older than what is already installed.
- // If command-line parameter is "upgrade", upgrade the service
- // but do not install it if it is not already installed.
- // If command line parameter is "uninstall", uninstall the service.
- // Otherwise, the service is probably being started by the SCM.
- bool forceInstall = !lstrcmpi(argv[1], L"forceinstall");
- if (!lstrcmpi(argv[1], L"install") || forceInstall) {
- WCHAR updatePath[MAX_PATH + 1];
- if (GetLogDirectoryPath(updatePath)) {
- LogInit(updatePath, L"maintenanceservice-install.log");
+ if (argc < 2)
+ {
+ LOG_WARN(("missing mandatory command line argument"));
+ return 1;
}
-
- SvcInstallAction action = InstallSvc;
- if (forceInstall) {
- action = ForceInstallSvc;
- LOG(("Installing service with force specified..."));
- } else {
- LOG(("Installing service..."));
+ // If command-line parameter is "install", install the service
+ // or upgrade if already installed
+ // If command line parameter is "forceinstall", install the service
+ // even if it is older than what is already installed.
+ // If command-line parameter is "upgrade", upgrade the service
+ // but do not install it if it is not already installed.
+ // If command line parameter is "uninstall", uninstall the service.
+ // Otherwise, the service is probably being started by the SCM.
+ bool forceInstall = !lstrcmpi(argv[1], L"forceinstall");
+ if (!lstrcmpi(argv[1], L"install") || forceInstall)
+ {
+ WCHAR updatePath[MAX_PATH + 1];
+ if (GetLogDirectoryPath(updatePath))
+ {
+ LogInit(updatePath, L"maintenanceservice-install.log");
+ }
+
+ SvcInstallAction action = InstallSvc;
+ if (forceInstall)
+ {
+ action = ForceInstallSvc;
+ LOG(("Installing service with force specified..."));
+ }
+ else
+ {
+ LOG(("Installing service..."));
+ }
+
+ bool ret = SvcInstall(action);
+ if (!ret)
+ {
+ LOG_WARN(("Could not install service. (%d)", GetLastError()));
+ LogFinish();
+ return 1;
+ }
+
+ LOG(("The service was installed successfully"));
+ LogFinish();
+ return 0;
}
- bool ret = SvcInstall(action);
- if (!ret) {
- LOG_WARN(("Could not install service. (%d)", GetLastError()));
- LogFinish();
- return 1;
+ if (!lstrcmpi(argv[1], L"upgrade"))
+ {
+ WCHAR updatePath[MAX_PATH + 1];
+ if (GetLogDirectoryPath(updatePath))
+ {
+ LogInit(updatePath, L"maintenanceservice-install.log");
+ }
+
+ LOG(("Upgrading service if installed..."));
+ if (!SvcInstall(UpgradeSvc))
+ {
+ LOG_WARN(("Could not upgrade service. (%d)", GetLastError()));
+ LogFinish();
+ return 1;
+ }
+
+ LOG(("The service was upgraded successfully"));
+ LogFinish();
+ return 0;
}
- LOG(("The service was installed successfully"));
- LogFinish();
- return 0;
- }
-
- if (!lstrcmpi(argv[1], L"upgrade")) {
- WCHAR updatePath[MAX_PATH + 1];
- if (GetLogDirectoryPath(updatePath)) {
- LogInit(updatePath, L"maintenanceservice-install.log");
+ if (!lstrcmpi(argv[1], L"uninstall"))
+ {
+ WCHAR updatePath[MAX_PATH + 1];
+ if (GetLogDirectoryPath(updatePath))
+ {
+ LogInit(updatePath, L"maintenanceservice-uninstall.log");
+ }
+ LOG(("Uninstalling service..."));
+ if (!SvcUninstall())
+ {
+ LOG_WARN(("Could not uninstall service. (%d)", GetLastError()));
+ LogFinish();
+ return 1;
+ }
+ LOG(("The service was uninstalled successfully"));
+ LogFinish();
+ return 0;
}
- LOG(("Upgrading service if installed..."));
- if (!SvcInstall(UpgradeSvc)) {
- LOG_WARN(("Could not upgrade service. (%d)", GetLastError()));
- LogFinish();
- return 1;
+ SERVICE_TABLE_ENTRYW DispatchTable[] =
+ {
+ { SVC_NAME, (LPSERVICE_MAIN_FUNCTIONW) SvcMain },
+ { nullptr, nullptr }
+ };
+
+ // This call returns when the service has stopped.
+ // The process should simply terminate when the call returns.
+ if (!StartServiceCtrlDispatcherW(DispatchTable))
+ {
+ LOG_WARN(("StartServiceCtrlDispatcher failed. (%d)", GetLastError()));
}
- LOG(("The service was upgraded successfully"));
- LogFinish();
return 0;
- }
-
- if (!lstrcmpi(argv[1], L"uninstall")) {
- WCHAR updatePath[MAX_PATH + 1];
- if (GetLogDirectoryPath(updatePath)) {
- LogInit(updatePath, L"maintenanceservice-uninstall.log");
- }
- LOG(("Uninstalling service..."));
- if (!SvcUninstall()) {
- LOG_WARN(("Could not uninstall service. (%d)", GetLastError()));
- LogFinish();
- return 1;
- }
- LOG(("The service was uninstalled successfully"));
- LogFinish();
- return 0;
- }
-
- SERVICE_TABLE_ENTRYW DispatchTable[] = {
- { SVC_NAME, (LPSERVICE_MAIN_FUNCTIONW) SvcMain },
- { nullptr, nullptr }
- };
-
- // This call returns when the service has stopped.
- // The process should simply terminate when the call returns.
- if (!StartServiceCtrlDispatcherW(DispatchTable)) {
- LOG_WARN(("StartServiceCtrlDispatcher failed. (%d)", GetLastError()));
- }
-
- return 0;
}
/**
@@ -130,24 +144,27 @@ wmain(int argc, WCHAR **argv)
BOOL
GetLogDirectoryPath(WCHAR *path)
{
- HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr,
- SHGFP_TYPE_CURRENT, path);
- if (FAILED(hr)) {
- return FALSE;
- }
-
- if (!PathAppendSafe(path, L"Mozilla")) {
- return FALSE;
- }
- // The directory should already be created from the installer, but
- // just to be safe in case someone deletes.
- CreateDirectoryW(path, nullptr);
-
- if (!PathAppendSafe(path, L"logs")) {
- return FALSE;
- }
- CreateDirectoryW(path, nullptr);
- return TRUE;
+ HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr,
+ SHGFP_TYPE_CURRENT, path);
+ if (FAILED(hr))
+ {
+ return FALSE;
+ }
+
+ if (!PathAppendSafe(path, L"Mozilla"))
+ {
+ return FALSE;
+ }
+ // The directory should already be created from the installer, but
+ // just to be safe in case someone deletes.
+ CreateDirectoryW(path, nullptr);
+
+ if (!PathAppendSafe(path, L"logs"))
+ {
+ return FALSE;
+ }
+ CreateDirectoryW(path, nullptr);
+ return TRUE;
}
/**
@@ -161,16 +178,19 @@ GetLogDirectoryPath(WCHAR *path)
BOOL
GetBackupLogPath(LPWSTR path, LPCWSTR basePath, int logNumber)
{
- WCHAR logName[64] = { L'\0' };
- wcsncpy(path, basePath, sizeof(logName) / sizeof(logName[0]) - 1);
- if (logNumber <= 0) {
- swprintf(logName, sizeof(logName) / sizeof(logName[0]),
- L"maintenanceservice.log");
- } else {
- swprintf(logName, sizeof(logName) / sizeof(logName[0]),
- L"maintenanceservice-%d.log", logNumber);
- }
- return PathAppendSafe(path, logName);
+ WCHAR logName[64] = { L'\0' };
+ wcsncpy(path, basePath, sizeof(logName) / sizeof(logName[0]) - 1);
+ if (logNumber <= 0)
+ {
+ swprintf(logName, sizeof(logName) / sizeof(logName[0]),
+ L"maintenanceservice.log");
+ }
+ else
+ {
+ swprintf(logName, sizeof(logName) / sizeof(logName[0]),
+ L"maintenanceservice-%d.log", logNumber);
+ }
+ return PathAppendSafe(path, logName);
}
/**
@@ -187,21 +207,25 @@ GetBackupLogPath(LPWSTR path, LPCWSTR basePath, int logNumber)
void
BackupOldLogs(LPCWSTR basePath, int numLogsToKeep)
{
- WCHAR oldPath[MAX_PATH + 1];
- WCHAR newPath[MAX_PATH + 1];
- for (int i = numLogsToKeep; i >= 1; i--) {
- if (!GetBackupLogPath(oldPath, basePath, i -1)) {
- continue;
- }
-
- if (!GetBackupLogPath(newPath, basePath, i)) {
- continue;
+ WCHAR oldPath[MAX_PATH + 1];
+ WCHAR newPath[MAX_PATH + 1];
+ for (int i = numLogsToKeep; i >= 1; i--)
+ {
+ if (!GetBackupLogPath(oldPath, basePath, i -1))
+ {
+ continue;
+ }
+
+ if (!GetBackupLogPath(newPath, basePath, i))
+ {
+ continue;
+ }
+
+ if (!MoveFileExW(oldPath, newPath, MOVEFILE_REPLACE_EXISTING))
+ {
+ continue;
+ }
}
-
- if (!MoveFileExW(oldPath, newPath, MOVEFILE_REPLACE_EXISTING)) {
- continue;
- }
- }
}
/**
@@ -221,20 +245,21 @@ BackupOldLogs(LPCWSTR basePath, int numLogsToKeep)
DWORD WINAPI
EnsureProcessTerminatedThread(LPVOID)
{
- Sleep(5000);
- exit(0);
+ Sleep(5000);
+ exit(0);
}
void
StartTerminationThread()
{
- // If the process does not self terminate like it should, this thread
- // will terminate the process after 5 seconds.
- HANDLE thread = CreateThread(nullptr, 0, EnsureProcessTerminatedThread,
- nullptr, 0, nullptr);
- if (thread) {
- CloseHandle(thread);
- }
+ // If the process does not self terminate like it should, this thread
+ // will terminate the process after 5 seconds.
+ HANDLE thread = CreateThread(nullptr, 0, EnsureProcessTerminatedThread,
+ nullptr, 0, nullptr);
+ if (thread)
+ {
+ CloseHandle(thread);
+ }
}
/**
@@ -243,61 +268,65 @@ StartTerminationThread()
void WINAPI
SvcMain(DWORD argc, LPWSTR *argv)
{
- // Setup logging, and backup the old logs
- WCHAR updatePath[MAX_PATH + 1];
- if (GetLogDirectoryPath(updatePath)) {
- BackupOldLogs(updatePath, LOGS_TO_KEEP);
- LogInit(updatePath, L"maintenanceservice.log");
- }
-
- // Disable every privilege we don't need. Processes started using
- // CreateProcess will use the same token as this process.
- UACHelper::DisablePrivileges(nullptr);
-
- // Register the handler function for the service
- gSvcStatusHandle = RegisterServiceCtrlHandlerW(SVC_NAME, SvcCtrlHandler);
- if (!gSvcStatusHandle) {
- LOG_WARN(("RegisterServiceCtrlHandler failed. (%d)", GetLastError()));
- ExecuteServiceCommand(argc, argv);
- LogFinish();
- exit(1);
- }
-
- // These values will be re-used later in calls involving gSvcStatus
- gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- gSvcStatus.dwServiceSpecificExitCode = 0;
+ // Setup logging, and backup the old logs
+ WCHAR updatePath[MAX_PATH + 1];
+ if (GetLogDirectoryPath(updatePath))
+ {
+ BackupOldLogs(updatePath, LOGS_TO_KEEP);
+ LogInit(updatePath, L"maintenanceservice.log");
+ }
- // Report initial status to the SCM
- ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
+ // Disable every privilege we don't need. Processes started using
+ // CreateProcess will use the same token as this process.
+ UACHelper::DisablePrivileges(nullptr);
+
+ // Register the handler function for the service
+ gSvcStatusHandle = RegisterServiceCtrlHandlerW(SVC_NAME, SvcCtrlHandler);
+ if (!gSvcStatusHandle)
+ {
+ LOG_WARN(("RegisterServiceCtrlHandler failed. (%d)", GetLastError()));
+ ExecuteServiceCommand(argc, argv);
+ LogFinish();
+ exit(1);
+ }
- // This event will be used to tell the SvcCtrlHandler when the work is
- // done for when a stop comamnd is manually issued.
- gWorkDoneEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
- if (!gWorkDoneEvent) {
- ReportSvcStatus(SERVICE_STOPPED, 1, 0);
- StartTerminationThread();
- return;
- }
+ // These values will be re-used later in calls involving gSvcStatus
+ gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ gSvcStatus.dwServiceSpecificExitCode = 0;
+
+ // Report initial status to the SCM
+ ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
+
+ // This event will be used to tell the SvcCtrlHandler when the work is
+ // done for when a stop comamnd is manually issued.
+ gWorkDoneEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ if (!gWorkDoneEvent)
+ {
+ ReportSvcStatus(SERVICE_STOPPED, 1, 0);
+ StartTerminationThread();
+ return;
+ }
- // Initialization complete and we're about to start working on
- // the actual command. Report the service state as running to the SCM.
- ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
+ // Initialization complete and we're about to start working on
+ // the actual command. Report the service state as running to the SCM.
+ ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
- // The service command was executed, stop logging and set an event
- // to indicate the work is done in case someone is waiting on a
- // service stop operation.
- ExecuteServiceCommand(argc, argv);
- LogFinish();
+ // The service command was executed, stop logging and set an event
+ // to indicate the work is done in case someone is waiting on a
+ // service stop operation.
+ ExecuteServiceCommand(argc, argv);
+ LogFinish();
- SetEvent(gWorkDoneEvent);
+ SetEvent(gWorkDoneEvent);
- // If we aren't already in a stopping state then tell the SCM we're stopped
- // now. If we are already in a stopping state then the SERVICE_STOPPED state
- // will be set by the SvcCtrlHandler.
- if (!gServiceControlStopping) {
- ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
- StartTerminationThread();
- }
+ // If we aren't already in a stopping state then tell the SCM we're stopped
+ // now. If we are already in a stopping state then the SERVICE_STOPPED state
+ // will be set by the SvcCtrlHandler.
+ if (!gServiceControlStopping)
+ {
+ ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
+ StartTerminationThread();
+ }
}
/**
@@ -312,29 +341,35 @@ ReportSvcStatus(DWORD currentState,
DWORD exitCode,
DWORD waitHint)
{
- static DWORD dwCheckPoint = 1;
-
- gSvcStatus.dwCurrentState = currentState;
- gSvcStatus.dwWin32ExitCode = exitCode;
- gSvcStatus.dwWaitHint = waitHint;
-
- if (SERVICE_START_PENDING == currentState ||
- SERVICE_STOP_PENDING == currentState) {
- gSvcStatus.dwControlsAccepted = 0;
- } else {
- gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
- SERVICE_ACCEPT_SHUTDOWN;
- }
-
- if ((SERVICE_RUNNING == currentState) ||
- (SERVICE_STOPPED == currentState)) {
- gSvcStatus.dwCheckPoint = 0;
- } else {
- gSvcStatus.dwCheckPoint = dwCheckPoint++;
- }
-
- // Report the status of the service to the SCM.
- SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
+ static DWORD dwCheckPoint = 1;
+
+ gSvcStatus.dwCurrentState = currentState;
+ gSvcStatus.dwWin32ExitCode = exitCode;
+ gSvcStatus.dwWaitHint = waitHint;
+
+ if (SERVICE_START_PENDING == currentState ||
+ SERVICE_STOP_PENDING == currentState)
+ {
+ gSvcStatus.dwControlsAccepted = 0;
+ }
+ else
+ {
+ gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_SHUTDOWN;
+ }
+
+ if ((SERVICE_RUNNING == currentState) ||
+ (SERVICE_STOPPED == currentState))
+ {
+ gSvcStatus.dwCheckPoint = 0;
+ }
+ else
+ {
+ gSvcStatus.dwCheckPoint = dwCheckPoint++;
+ }
+
+ // Report the status of the service to the SCM.
+ SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}
/**
@@ -344,14 +379,16 @@ ReportSvcStatus(DWORD currentState,
DWORD WINAPI
StopServiceAndWaitForCommandThread(LPVOID)
{
- do {
- ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 1000);
- } while(WaitForSingleObject(gWorkDoneEvent, 100) == WAIT_TIMEOUT);
- CloseHandle(gWorkDoneEvent);
- gWorkDoneEvent = nullptr;
- ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
- StartTerminationThread();
- return 0;
+ do
+ {
+ ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 1000);
+ }
+ while (WaitForSingleObject(gWorkDoneEvent, 100) == WAIT_TIMEOUT);
+ CloseHandle(gWorkDoneEvent);
+ gWorkDoneEvent = nullptr;
+ ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
+ StartTerminationThread();
+ return 0;
}
/**
@@ -361,35 +398,41 @@ StopServiceAndWaitForCommandThread(LPVOID)
void WINAPI
SvcCtrlHandler(DWORD dwCtrl)
{
- // After a SERVICE_CONTROL_STOP there should be no more commands sent to
- // the SvcCtrlHandler.
- if (gServiceControlStopping) {
- return;
- }
-
- // Handle the requested control code.
- switch(dwCtrl) {
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP: {
- gServiceControlStopping = true;
- ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 1000);
-
- // The SvcCtrlHandler thread should not spend more than 30 seconds in
- // shutdown so we spawn a new thread for stopping the service
- HANDLE thread = CreateThread(nullptr, 0,
- StopServiceAndWaitForCommandThread,
- nullptr, 0, nullptr);
- if (thread) {
- CloseHandle(thread);
- } else {
- // Couldn't start the thread so just call the stop ourselves.
- // If it happens to take longer than 30 seconds the caller will
- // get an error.
- StopServiceAndWaitForCommandThread(nullptr);
- }
+ // After a SERVICE_CONTROL_STOP there should be no more commands sent to
+ // the SvcCtrlHandler.
+ if (gServiceControlStopping)
+ {
+ return;
+ }
+
+ // Handle the requested control code.
+ switch (dwCtrl)
+ {
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ {
+ gServiceControlStopping = true;
+ ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 1000);
+
+ // The SvcCtrlHandler thread should not spend more than 30 seconds in
+ // shutdown so we spawn a new thread for stopping the service
+ HANDLE thread = CreateThread(nullptr, 0,
+ StopServiceAndWaitForCommandThread,
+ nullptr, 0, nullptr);
+ if (thread)
+ {
+ CloseHandle(thread);
+ }
+ else
+ {
+ // Couldn't start the thread so just call the stop ourselves.
+ // If it happens to take longer than 30 seconds the caller will
+ // get an error.
+ StopServiceAndWaitForCommandThread(nullptr);
+ }
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
}
diff --git a/onlineupdate/source/service/maintenanceservice.hxx b/onlineupdate/source/service/maintenanceservice.hxx
index 9e02914a0e7b..af5db9e29dae 100644
--- a/onlineupdate/source/service/maintenanceservice.hxx
+++ b/onlineupdate/source/service/maintenanceservice.hxx
@@ -5,6 +5,6 @@
void WINAPI SvcMain(DWORD dwArgc, LPWSTR *lpszArgv);
void SvcInit(DWORD dwArgc, LPWSTR *lpszArgv);
void WINAPI SvcCtrlHandler(DWORD dwCtrl);
-void ReportSvcStatus(DWORD dwCurrentState,
- DWORD dwWin32ExitCode,
+void ReportSvcStatus(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode,
DWORD dwWaitHint);
diff --git a/onlineupdate/source/service/registrycertificates.cxx b/onlineupdate/source/service/registrycertificates.cxx
index f44fb3427d00..ea0905cea888 100644
--- a/onlineupdate/source/service/registrycertificates.cxx
+++ b/onlineupdate/source/service/registrycertificates.cxx
@@ -55,115 +55,127 @@ struct AutoRegKey
BOOL
DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath)
{
- WCHAR maintenanceServiceKey[MAX_PATH + 1];
- if (!CalculateRegistryPathFromFilePath(basePathForUpdate,
- maintenanceServiceKey)) {
- return FALSE;
- }
-
- // We use KEY_WOW64_64KEY to always force 64-bit view.
- // The user may have both x86 and x64 applications installed
- // which each register information. We need a consistent place
- // to put those certificate attributes in and hence why we always
- // force the non redirected registry under Wow6432Node.
- // This flag is ignored on 32bit systems.
- HKEY baseKeyRaw;
- LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- maintenanceServiceKey, 0,
- KEY_READ | KEY_WOW64_64KEY, &baseKeyRaw);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not open key. (%d)", retCode));
- // Our tests run with a different apply directory for each test.
- // We use this registry key on our test slaves to store the
- // allowed name/issuers.
- retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- TEST_ONLY_FALLBACK_KEY_PATH, 0,
- KEY_READ | KEY_WOW64_64KEY, &baseKeyRaw);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not open fallback key. (%d)", retCode));
- return FALSE;
- }
- }
- AutoRegKey baseKey(baseKeyRaw);
-
- // Get the number of subkeys.
- DWORD subkeyCount = 0;
- retCode = RegQueryInfoKeyW(baseKey.get(), nullptr, nullptr, nullptr, &subkeyCount,
- nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not query info key. (%d)", retCode));
- return FALSE;
- }
-
- // Enumerate the subkeys, each subkey represents an allowed certificate.
- for (DWORD i = 0; i < subkeyCount; i++) {
- WCHAR subkeyBuffer[MAX_KEY_LENGTH];
- DWORD subkeyBufferCount = MAX_KEY_LENGTH;
- retCode = RegEnumKeyExW(baseKey.get(), i, subkeyBuffer,
- &subkeyBufferCount, nullptr,
- nullptr, nullptr, nullptr);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not enum certs. (%d)", retCode));
- return FALSE;
+ WCHAR maintenanceServiceKey[MAX_PATH + 1];
+ if (!CalculateRegistryPathFromFilePath(basePathForUpdate,
+ maintenanceServiceKey))
+ {
+ return FALSE;
}
- // Open the subkey for the current certificate
- HKEY subKeyRaw;
- retCode = RegOpenKeyExW(baseKey.get(),
- subkeyBuffer,
- 0,
- KEY_READ | KEY_WOW64_64KEY,
- &subKeyRaw);
- AutoRegKey subKey(subKeyRaw);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not open subkey. (%d)", retCode));
- continue; // Try the next subkey
+ // We use KEY_WOW64_64KEY to always force 64-bit view.
+ // The user may have both x86 and x64 applications installed
+ // which each register information. We need a consistent place
+ // to put those certificate attributes in and hence why we always
+ // force the non redirected registry under Wow6432Node.
+ // This flag is ignored on 32bit systems.
+ HKEY baseKeyRaw;
+ LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ maintenanceServiceKey, 0,
+ KEY_READ | KEY_WOW64_64KEY, &baseKeyRaw);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not open key. (%d)", retCode));
+ // Our tests run with a different apply directory for each test.
+ // We use this registry key on our test slaves to store the
+ // allowed name/issuers.
+ retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ TEST_ONLY_FALLBACK_KEY_PATH, 0,
+ KEY_READ | KEY_WOW64_64KEY, &baseKeyRaw);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not open fallback key. (%d)", retCode));
+ return FALSE;
+ }
}
-
- const int MAX_CHAR_COUNT = 256;
- DWORD valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
- WCHAR name[MAX_CHAR_COUNT] = { L'\0' };
- WCHAR issuer[MAX_CHAR_COUNT] = { L'\0' };
-
- // Get the name from the registry
- retCode = RegQueryValueExW(subKey.get(), L"name", 0, nullptr,
- (LPBYTE)name, &valueBufSize);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not obtain name from registry. (%d)", retCode));
- continue; // Try the next subkey
+ AutoRegKey baseKey(baseKeyRaw);
+
+ // Get the number of subkeys.
+ DWORD subkeyCount = 0;
+ retCode = RegQueryInfoKeyW(baseKey.get(), nullptr, nullptr, nullptr, &subkeyCount,
+ nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not query info key. (%d)", retCode));
+ return FALSE;
}
- // Get the issuer from the registry
- valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
- retCode = RegQueryValueExW(subKey.get(), L"issuer", 0, nullptr,
- (LPBYTE)issuer, &valueBufSize);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Could not obtain issuer from registry. (%d)", retCode));
- continue; // Try the next subkey
- }
+ // Enumerate the subkeys, each subkey represents an allowed certificate.
+ for (DWORD i = 0; i < subkeyCount; i++)
+ {
+ WCHAR subkeyBuffer[MAX_KEY_LENGTH];
+ DWORD subkeyBufferCount = MAX_KEY_LENGTH;
+ retCode = RegEnumKeyExW(baseKey.get(), i, subkeyBuffer,
+ &subkeyBufferCount, nullptr,
+ nullptr, nullptr, nullptr);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not enum certs. (%d)", retCode));
+ return FALSE;
+ }
- CertificateCheckInfo allowedCertificate = {
- name,
- issuer,
- };
+ // Open the subkey for the current certificate
+ HKEY subKeyRaw;
+ retCode = RegOpenKeyExW(baseKey.get(),
+ subkeyBuffer,
+ 0,
+ KEY_READ | KEY_WOW64_64KEY,
+ &subKeyRaw);
+ AutoRegKey subKey(subKeyRaw);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not open subkey. (%d)", retCode));
+ continue; // Try the next subkey
+ }
- retCode = CheckCertificateForPEFile(filePath, allowedCertificate);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Error on certificate check. (%d)", retCode));
- continue; // Try the next subkey
- }
+ const int MAX_CHAR_COUNT = 256;
+ DWORD valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
+ WCHAR name[MAX_CHAR_COUNT] = { L'\0' };
+ WCHAR issuer[MAX_CHAR_COUNT] = { L'\0' };
- retCode = VerifyCertificateTrustForFile(filePath);
- if (retCode != ERROR_SUCCESS) {
- LOG_WARN(("Error on certificate trust check. (%d)", retCode));
- continue; // Try the next subkey
- }
+ // Get the name from the registry
+ retCode = RegQueryValueExW(subKey.get(), L"name", 0, nullptr,
+ (LPBYTE)name, &valueBufSize);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not obtain name from registry. (%d)", retCode));
+ continue; // Try the next subkey
+ }
+
+ // Get the issuer from the registry
+ valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
+ retCode = RegQueryValueExW(subKey.get(), L"issuer", 0, nullptr,
+ (LPBYTE)issuer, &valueBufSize);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Could not obtain issuer from registry. (%d)", retCode));
+ continue; // Try the next subkey
+ }
+
+ CertificateCheckInfo allowedCertificate =
+ {
+ name,
+ issuer,
+ };
- // Raise the roof, we found a match!
- return TRUE;
- }
+ retCode = CheckCertificateForPEFile(filePath, allowedCertificate);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Error on certificate check. (%d)", retCode));
+ continue; // Try the next subkey
+ }
+
+ retCode = VerifyCertificateTrustForFile(filePath);
+ if (retCode != ERROR_SUCCESS)
+ {
+ LOG_WARN(("Error on certificate trust check. (%d)", retCode));
+ continue; // Try the next subkey
+ }
+
+ // Raise the roof, we found a match!
+ return TRUE;
+ }
- // No certificates match, :'(
- return FALSE;
+ // No certificates match, :'(
+ return FALSE;
}
diff --git a/onlineupdate/source/service/resource.hxx b/onlineupdate/source/service/resource.hxx
index 45619457c9aa..f1a1c383665d 100644
--- a/onlineupdate/source/service/resource.hxx
+++ b/onlineupdate/source/service/resource.hxx
@@ -9,7 +9,7 @@
#define IDI_DIALOG 1003
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
diff --git a/onlineupdate/source/service/servicebase.cxx b/onlineupdate/source/service/servicebase.cxx
index 1b4f406f431e..4fb632878cec 100644
--- a/onlineupdate/source/service/servicebase.cxx
+++ b/onlineupdate/source/service/servicebase.cxx
@@ -18,68 +18,80 @@
BOOL
VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent)
{
- sameContent = FALSE;
- AutoHandle file1(CreateFileW(file1Path, GENERIC_READ, FILE_SHARE_READ,
+ sameContent = FALSE;
+ AutoHandle file1(CreateFileW(file1Path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr));
- if (file1 == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
- AutoHandle file2(CreateFileW(file2Path, GENERIC_READ, FILE_SHARE_READ,
+ if (file1 == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+ AutoHandle file2(CreateFileW(file2Path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr));
- if (file2 == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
-
- DWORD fileSize1 = GetFileSize(file1.get(), nullptr);
- DWORD fileSize2 = GetFileSize(file2.get(), nullptr);
- if (INVALID_FILE_SIZE == fileSize1 || INVALID_FILE_SIZE == fileSize2) {
- return FALSE;
- }
-
- if (fileSize1 != fileSize2) {
- // sameContent is already set to FALSE
- return TRUE;
- }
-
- char buf1[COMPARE_BLOCKSIZE];
- char buf2[COMPARE_BLOCKSIZE];
- DWORD numBlocks = fileSize1 / COMPARE_BLOCKSIZE;
- DWORD leftOver = fileSize1 % COMPARE_BLOCKSIZE;
- DWORD readAmount;
- for (DWORD i = 0; i < numBlocks; i++) {
- if (!ReadFile(file1.get(), buf1, COMPARE_BLOCKSIZE, &readAmount, nullptr) ||
- readAmount != COMPARE_BLOCKSIZE) {
- return FALSE;
+ if (file2 == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
}
- if (!ReadFile(file2.get(), buf2, COMPARE_BLOCKSIZE, &readAmount, nullptr) ||
- readAmount != COMPARE_BLOCKSIZE) {
- return FALSE;
+ DWORD fileSize1 = GetFileSize(file1.get(), nullptr);
+ DWORD fileSize2 = GetFileSize(file2.get(), nullptr);
+ if (INVALID_FILE_SIZE == fileSize1 || INVALID_FILE_SIZE == fileSize2)
+ {
+ return FALSE;
}
- if (memcmp(buf1, buf2, COMPARE_BLOCKSIZE)) {
- // sameContent is already set to FALSE
- return TRUE;
+ if (fileSize1 != fileSize2)
+ {
+ // sameContent is already set to FALSE
+ return TRUE;
}
- }
- if (leftOver) {
- if (!ReadFile(file1.get(), buf1, leftOver, &readAmount, nullptr) ||
- readAmount != leftOver) {
- return FALSE;
- }
+ char buf1[COMPARE_BLOCKSIZE];
+ char buf2[COMPARE_BLOCKSIZE];
+ DWORD numBlocks = fileSize1 / COMPARE_BLOCKSIZE;
+ DWORD leftOver = fileSize1 % COMPARE_BLOCKSIZE;
+ DWORD readAmount;
+ for (DWORD i = 0; i < numBlocks; i++)
+ {
+ if (!ReadFile(file1.get(), buf1, COMPARE_BLOCKSIZE, &readAmount, nullptr) ||
+ readAmount != COMPARE_BLOCKSIZE)
+ {
+ return FALSE;
+ }
+
+ if (!ReadFile(file2.get(), buf2, COMPARE_BLOCKSIZE, &readAmount, nullptr) ||
+ readAmount != COMPARE_BLOCKSIZE)
+ {
+ return FALSE;
+ }
- if (!ReadFile(file2.get(), buf2, leftOver, &readAmount, nullptr) ||
- readAmount != leftOver) {
- return FALSE;
+ if (memcmp(buf1, buf2, COMPARE_BLOCKSIZE))
+ {
+ // sameContent is already set to FALSE
+ return TRUE;
+ }
}
- if (memcmp(buf1, buf2, leftOver)) {
- // sameContent is already set to FALSE
- return TRUE;
+ if (leftOver)
+ {
+ if (!ReadFile(file1.get(), buf1, leftOver, &readAmount, nullptr) ||
+ readAmount != leftOver)
+ {
+ return FALSE;
+ }
+
+ if (!ReadFile(file2.get(), buf2, leftOver, &readAmount, nullptr) ||
+ readAmount != leftOver)
+ {
+ return FALSE;
+ }
+
+ if (memcmp(buf1, buf2, leftOver))
+ {
+ // sameContent is already set to FALSE
+ return TRUE;
+ }
}
- }
- sameContent = TRUE;
- return TRUE;
+ sameContent = TRUE;
+ return TRUE;
}
diff --git a/onlineupdate/source/service/servicebase.hxx b/onlineupdate/source/service/servicebase.hxx
index abf88a122a1d..c47f966ad551 100644
--- a/onlineupdate/source/service/servicebase.hxx
+++ b/onlineupdate/source/service/servicebase.hxx
@@ -14,7 +14,7 @@ BOOL VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent);
#define COMPARE_BLOCKSIZE 32768
// The following string resource value is used to uniquely identify the signed
-// Mozilla application as an updater. Before the maintenance service will
+// Mozilla application as an updater. Before the maintenance service will
// execute the updater it must have this updater identity string in its string
// table. No other signed Mozilla product will have this string table value.
#define UPDATER_IDENTITY_STRING \
diff --git a/onlineupdate/source/service/serviceinstall.cxx b/onlineupdate/source/service/serviceinstall.cxx
index cf7fef354186..a225e9445544 100644
--- a/onlineupdate/source/service/serviceinstall.cxx
+++ b/onlineupdate/source/service/serviceinstall.cxx
@@ -73,19 +73,20 @@ static int
ReadMaintenanceServiceStrings(LPCWSTR path,
MaintenanceServiceStringTable *results)
{
- // Read in the maintenance service description string if specified.
- const unsigned int kNumStrings = 1;
- const char *kServiceKeys = "MozillaMaintenanceDescription\0";
- char serviceStrings[kNumStrings][MAX_TEXT_LEN];
- int result = ReadStrings(path, kServiceKeys,
- kNumStrings, serviceStrings);
- if (result != OK) {
- serviceStrings[0][0] = '\0';
- }
- strncpy(results->serviceDescription,
- serviceStrings[0], MAX_TEXT_LEN - 1);
- results->serviceDescription[MAX_TEXT_LEN - 1] = '\0';
- return result;
+ // Read in the maintenance service description string if specified.
+ const unsigned int kNumStrings = 1;
+ const char *kServiceKeys = "MozillaMaintenanceDescription\0";
+ char serviceStrings[kNumStrings][MAX_TEXT_LEN];
+ int result = ReadStrings(path, kServiceKeys,
+ kNumStrings, serviceStrings);
+ if (result != OK)
+ {
+ serviceStrings[0][0] = '\0';
+ }
+ strncpy(results->serviceDescription,
+ serviceStrings[0], MAX_TEXT_LEN - 1);
+ results->serviceDescription[MAX_TEXT_LEN - 1] = '\0';
+ return result;
}
/**
@@ -103,30 +104,32 @@ static BOOL
GetVersionNumberFromPath(LPWSTR path, DWORD &A, DWORD &B,
DWORD &C, DWORD &D)
{
- DWORD fileVersionInfoSize = GetFileVersionInfoSizeW(path, 0);
- std::unique_ptr<char[]> fileVersionInfo(new char[fileVersionInfoSize]);
- if (!GetFileVersionInfoW(path, 0, fileVersionInfoSize,
- fileVersionInfo.get())) {
- LOG_WARN(("Could not obtain file info of old service. (%d)",
- GetLastError()));
- return FALSE;
- }
-
- VS_FIXEDFILEINFO *fixedFileInfo =
- reinterpret_cast<VS_FIXEDFILEINFO *>(fileVersionInfo.get());
- UINT size;
- if (!VerQueryValueW(fileVersionInfo.get(), L"\\",
- reinterpret_cast<LPVOID*>(&fixedFileInfo), &size)) {
- LOG_WARN(("Could not query file version info of old service. (%d)",
- GetLastError()));
- return FALSE;
- }
-
- A = HIWORD(fixedFileInfo->dwFileVersionMS);
- B = LOWORD(fixedFileInfo->dwFileVersionMS);
- C = HIWORD(fixedFileInfo->dwFileVersionLS);
- D = LOWORD(fixedFileInfo->dwFileVersionLS);
- return TRUE;
+ DWORD fileVersionInfoSize = GetFileVersionInfoSizeW(path, 0);
+ std::unique_ptr<char[]> fileVersionInfo(new char[fileVersionInfoSize]);
+ if (!GetFileVersionInfoW(path, 0, fileVersionInfoSize,
+ fileVersionInfo.get()))
+ {
+ LOG_WARN(("Could not obtain file info of old service. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
+
+ VS_FIXEDFILEINFO *fixedFileInfo =
+ reinterpret_cast<VS_FIXEDFILEINFO *>(fileVersionInfo.get());
+ UINT size;
+ if (!VerQueryValueW(fileVersionInfo.get(), L"\\",
+ reinterpret_cast<LPVOID*>(&fixedFileInfo), &size))
+ {
+ LOG_WARN(("Could not query file version info of old service. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
+
+ A = HIWORD(fixedFileInfo->dwFileVersionMS);
+ B = LOWORD(fixedFileInfo->dwFileVersionMS);
+ C = HIWORD(fixedFileInfo->dwFileVersionLS);
+ D = LOWORD(fixedFileInfo->dwFileVersionLS);
+ return TRUE;
}
/**
@@ -140,63 +143,70 @@ GetVersionNumberFromPath(LPWSTR path, DWORD &A, DWORD &B,
BOOL
UpdateServiceDescription(SC_HANDLE serviceHandle)
{
- WCHAR updaterINIPath[MAX_PATH + 1];
- if (!GetModuleFileNameW(nullptr, updaterINIPath,
- sizeof(updaterINIPath) /
- sizeof(updaterINIPath[0]))) {
- LOG_WARN(("Could not obtain module filename when attempting to "
- "modify service description. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (!PathRemoveFileSpecW(updaterINIPath)) {
- LOG_WARN(("Could not remove file spec when attempting to "
- "modify service description. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (!PathAppendSafe(updaterINIPath, L"updater.ini")) {
- LOG_WARN(("Could not append updater.ini filename when attempting to "
- "modify service description. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (GetFileAttributesW(updaterINIPath) == INVALID_FILE_ATTRIBUTES) {
- LOG_WARN(("updater.ini file does not exist, will not modify "
- "service description. (%d)", GetLastError()));
- return FALSE;
- }
-
- MaintenanceServiceStringTable serviceStrings;
- int rv = ReadMaintenanceServiceStrings(updaterINIPath, &serviceStrings);
- if (rv != OK || !strlen(serviceStrings.serviceDescription)) {
- LOG_WARN(("updater.ini file does not contain a maintenance "
- "service description."));
- return FALSE;
- }
-
- WCHAR serviceDescription[MAX_TEXT_LEN];
- if (!MultiByteToWideChar(CP_UTF8, 0,
- serviceStrings.serviceDescription, -1,
- serviceDescription,
- sizeof(serviceDescription) /
- sizeof(serviceDescription[0]))) {
- LOG_WARN(("Could not convert description to wide string format. (%d)",
- GetLastError()));
- return FALSE;
- }
-
- SERVICE_DESCRIPTIONW descriptionConfig;
- descriptionConfig.lpDescription = serviceDescription;
- if (!ChangeServiceConfig2W(serviceHandle,
- SERVICE_CONFIG_DESCRIPTION,
- &descriptionConfig)) {
- LOG_WARN(("Could not change service config. (%d)", GetLastError()));
- return FALSE;
- }
-
- LOG(("The service description was updated successfully."));
- return TRUE;
+ WCHAR updaterINIPath[MAX_PATH + 1];
+ if (!GetModuleFileNameW(nullptr, updaterINIPath,
+ sizeof(updaterINIPath) /
+ sizeof(updaterINIPath[0])))
+ {
+ LOG_WARN(("Could not obtain module filename when attempting to "
+ "modify service description. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (!PathRemoveFileSpecW(updaterINIPath))
+ {
+ LOG_WARN(("Could not remove file spec when attempting to "
+ "modify service description. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (!PathAppendSafe(updaterINIPath, L"updater.ini"))
+ {
+ LOG_WARN(("Could not append updater.ini filename when attempting to "
+ "modify service description. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (GetFileAttributesW(updaterINIPath) == INVALID_FILE_ATTRIBUTES)
+ {
+ LOG_WARN(("updater.ini file does not exist, will not modify "
+ "service description. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ MaintenanceServiceStringTable serviceStrings;
+ int rv = ReadMaintenanceServiceStrings(updaterINIPath, &serviceStrings);
+ if (rv != OK || !strlen(serviceStrings.serviceDescription))
+ {
+ LOG_WARN(("updater.ini file does not contain a maintenance "
+ "service description."));
+ return FALSE;
+ }
+
+ WCHAR serviceDescription[MAX_TEXT_LEN];
+ if (!MultiByteToWideChar(CP_UTF8, 0,
+ serviceStrings.serviceDescription, -1,
+ serviceDescription,
+ sizeof(serviceDescription) /
+ sizeof(serviceDescription[0])))
+ {
+ LOG_WARN(("Could not convert description to wide string format. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
+
+ SERVICE_DESCRIPTIONW descriptionConfig;
+ descriptionConfig.lpDescription = serviceDescription;
+ if (!ChangeServiceConfig2W(serviceHandle,
+ SERVICE_CONFIG_DESCRIPTION,
+ &descriptionConfig))
+ {
+ LOG_WARN(("Could not change service config. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ LOG(("The service description was updated successfully."));
+ return TRUE;
}
/**
@@ -213,54 +223,58 @@ FixServicePath(SC_HANDLE service,
LPCWSTR currentServicePath,
BOOL &servicePathWasWrong)
{
- // When we originally upgraded the MozillaMaintenance service we
- // would uninstall the service on each upgrade. This had an
- // intermittent error which could cause the service to use the file
- // maintenanceservice_tmp.exe as the install path. Only a small number
- // of Nightly users would be affected by this, but we check for this
- // state here and fix the user if they are affected.
- //
- // We also fix the path in the case of the path not being quoted.
- size_t currentServicePathLen = wcslen(currentServicePath);
- bool doesServiceHaveCorrectPath =
- currentServicePathLen > 2 &&
- !wcsstr(currentServicePath, L"maintenanceservice_tmp.exe") &&
- currentServicePath[0] == L'\"' &&
- currentServicePath[currentServicePathLen - 1] == L'\"';
-
- if (doesServiceHaveCorrectPath) {
- LOG(("The MozillaMaintenance service path is correct."));
- servicePathWasWrong = FALSE;
+ // When we originally upgraded the MozillaMaintenance service we
+ // would uninstall the service on each upgrade. This had an
+ // intermittent error which could cause the service to use the file
+ // maintenanceservice_tmp.exe as the install path. Only a small number
+ // of Nightly users would be affected by this, but we check for this
+ // state here and fix the user if they are affected.
+ //
+ // We also fix the path in the case of the path not being quoted.
+ size_t currentServicePathLen = wcslen(currentServicePath);
+ bool doesServiceHaveCorrectPath =
+ currentServicePathLen > 2 &&
+ !wcsstr(currentServicePath, L"maintenanceservice_tmp.exe") &&
+ currentServicePath[0] == L'\"' &&
+ currentServicePath[currentServicePathLen - 1] == L'\"';
+
+ if (doesServiceHaveCorrectPath)
+ {
+ LOG(("The MozillaMaintenance service path is correct."));
+ servicePathWasWrong = FALSE;
+ return TRUE;
+ }
+ // This is a recoverable situation so not logging as a warning
+ LOG(("The MozillaMaintenance path is NOT correct. It was: %ls",
+ currentServicePath));
+
+ servicePathWasWrong = TRUE;
+ WCHAR fixedPath[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(fixedPath, currentServicePath, MAX_PATH);
+ PathUnquoteSpacesW(fixedPath);
+ if (!PathRemoveFileSpecW(fixedPath))
+ {
+ LOG_WARN(("Couldn't remove file spec. (%d)", GetLastError()));
+ return FALSE;
+ }
+ if (!PathAppendSafe(fixedPath, L"maintenanceservice.exe"))
+ {
+ LOG_WARN(("Couldn't append file spec. (%d)", GetLastError()));
+ return FALSE;
+ }
+ PathQuoteSpacesW(fixedPath);
+
+
+ if (!ChangeServiceConfigW(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
+ SERVICE_NO_CHANGE, fixedPath, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr))
+ {
+ LOG_WARN(("Could not fix service path. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ LOG(("Fixed service path to: %ls.", fixedPath));
return TRUE;
- }
- // This is a recoverable situation so not logging as a warning
- LOG(("The MozillaMaintenance path is NOT correct. It was: %ls",
- currentServicePath));
-
- servicePathWasWrong = TRUE;
- WCHAR fixedPath[MAX_PATH + 1] = { L'\0' };
- wcsncpy(fixedPath, currentServicePath, MAX_PATH);
- PathUnquoteSpacesW(fixedPath);
- if (!PathRemoveFileSpecW(fixedPath)) {
- LOG_WARN(("Couldn't remove file spec. (%d)", GetLastError()));
- return FALSE;
- }
- if (!PathAppendSafe(fixedPath, L"maintenanceservice.exe")) {
- LOG_WARN(("Couldn't append file spec. (%d)", GetLastError()));
- return FALSE;
- }
- PathQuoteSpacesW(fixedPath);
-
-
- if (!ChangeServiceConfigW(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
- SERVICE_NO_CHANGE, fixedPath, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr)) {
- LOG_WARN(("Could not fix service path. (%d)", GetLastError()));
- return FALSE;
- }
-
- LOG(("Fixed service path to: %ls.", fixedPath));
- return TRUE;
}
/**
@@ -274,263 +288,299 @@ FixServicePath(SC_HANDLE service,
BOOL
SvcInstall(SvcInstallAction action)
{
- // Get a handle to the local computer SCM database with full access rights.
- AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
- SC_MANAGER_ALL_ACCESS));
- if (!schSCManager) {
- LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
- return FALSE;
- }
-
- WCHAR newServiceBinaryPath[MAX_PATH + 1];
- if (!GetModuleFileNameW(nullptr, newServiceBinaryPath,
- sizeof(newServiceBinaryPath) /
- sizeof(newServiceBinaryPath[0]))) {
- LOG_WARN(("Could not obtain module filename when attempting to "
- "install service. (%d)",
- GetLastError()));
- return FALSE;
- }
-
- // Check if we already have the service installed.
- AutoServiceHandle schService(OpenServiceW(schSCManager.get(),
- SVC_NAME,
- SERVICE_ALL_ACCESS));
- DWORD lastError = GetLastError();
- if (!schService && ERROR_SERVICE_DOES_NOT_EXIST != lastError) {
- // The service exists but we couldn't open it
- LOG_WARN(("Could not open service. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (schService) {
- // The service exists but it may not have the correct permissions.
- // This could happen if the permissions were not set correctly originally
- // or have been changed after the installation. This will reset the
- // permissions back to allow limited user accounts.
- if (!SetUserAccessServiceDACL(schService.get())) {
- LOG_WARN(("Could not reset security ACE on service handle. It might not be "
- "possible to start the service. This error should never "
- "happen. (%d)", GetLastError()));
- }
-
- // The service exists and we opened it
- DWORD bytesNeeded;
- if (!QueryServiceConfigW(schService.get(), nullptr, 0, &bytesNeeded) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- LOG_WARN(("Could not determine buffer size for query service config. (%d)",
- GetLastError()));
- return FALSE;
- }
-
- // Get the service config information, in particular we want the binary
- // path of the service.
- std::unique_ptr<char[]> serviceConfigBuffer(new char[bytesNeeded]);
- if (!QueryServiceConfigW(schService.get(),
- reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()),
- bytesNeeded, &bytesNeeded)) {
- LOG_WARN(("Could open service but could not query service config. (%d)",
- GetLastError()));
- return FALSE;
- }
- QUERY_SERVICE_CONFIGW &serviceConfig =
- *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());
-
- // Check if we need to fix the service path
- BOOL servicePathWasWrong;
- static BOOL alreadyCheckedFixServicePath = FALSE;
- if (!alreadyCheckedFixServicePath) {
- if (!FixServicePath(schService.get(), serviceConfig.lpBinaryPathName,
- servicePathWasWrong)) {
- LOG_WARN(("Could not fix service path. This should never happen. (%d)",
+ // Get a handle to the local computer SCM database with full access rights.
+ AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_ALL_ACCESS));
+ if (!schSCManager)
+ {
+ LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ WCHAR newServiceBinaryPath[MAX_PATH + 1];
+ if (!GetModuleFileNameW(nullptr, newServiceBinaryPath,
+ sizeof(newServiceBinaryPath) /
+ sizeof(newServiceBinaryPath[0])))
+ {
+ LOG_WARN(("Could not obtain module filename when attempting to "
+ "install service. (%d)",
GetLastError()));
- // True is returned because the service is pointing to
- // maintenanceservice_tmp.exe so it actually was upgraded to the
- // newest installed service.
- return TRUE;
- } else if (servicePathWasWrong) {
- // Now that the path is fixed we should re-attempt the install.
- // This current process' image path is maintenanceservice_tmp.exe.
- // The service used to point to maintenanceservice_tmp.exe.
- // The service was just fixed to point to maintenanceservice.exe.
- // Re-attempting an install from scratch will work as normal.
- alreadyCheckedFixServicePath = TRUE;
- LOG(("Restarting install action: %d", action));
- return SvcInstall(action);
- }
- }
-
- // Ensure the service path is not quoted. We own this memory and know it to
- // be large enough for the quoted path, so it is large enough for the
- // unquoted path. This function cannot fail.
- PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);
-
- // Obtain the existing maintenanceservice file's version number and
- // the new file's version number. Versions are in the format of
- // A.B.C.D.
- DWORD existingA, existingB, existingC, existingD;
- DWORD newA, newB, newC, newD;
- BOOL obtainedExistingVersionInfo =
- GetVersionNumberFromPath(serviceConfig.lpBinaryPathName,
- existingA, existingB,
- existingC, existingD);
- if (!GetVersionNumberFromPath(newServiceBinaryPath, newA,
- newB, newC, newD)) {
- LOG_WARN(("Could not obtain version number from new path"));
- return FALSE;
- }
-
- // Check if we need to replace the old binary with the new one
- // If we couldn't get the old version info then we assume we should
- // replace it.
- if (ForceInstallSvc == action ||
- !obtainedExistingVersionInfo ||
- (existingA < newA) ||
- (existingA == newA && existingB < newB) ||
- (existingA == newA && existingB == newB &&
- existingC < newC) ||
- (existingA == newA && existingB == newB &&
- existingC == newC && existingD < newD)) {
-
- // We have a newer updater, so update the description from the INI file.
- UpdateServiceDescription(schService.get());
-
- schService.reset();
- if (!StopService()) {
return FALSE;
- }
+ }
- if (!wcscmp(newServiceBinaryPath, serviceConfig.lpBinaryPathName)) {
- LOG(("File is already in the correct location, no action needed for "
- "upgrade. The path is: \"%ls\"", newServiceBinaryPath));
- return TRUE;
- }
-
- BOOL result = TRUE;
-
- // Attempt to copy the new binary over top the existing binary.
- // If there is an error we try to move it out of the way and then
- // copy it in. First try the safest / easiest way to overwrite the file.
- if (!CopyFileW(newServiceBinaryPath,
- serviceConfig.lpBinaryPathName, FALSE)) {
- LOG_WARN(("Could not overwrite old service binary file. "
- "This should never happen, but if it does the next "
- "upgrade will fix it, the service is not a critical "
- "component that needs to be installed for upgrades "
- "to work. (%d)", GetLastError()));
-
- // We rename the last 3 filename chars in an unsafe way. Manually
- // verify there are more than 3 chars for safe failure in MoveFileExW.
- const size_t len = wcslen(serviceConfig.lpBinaryPathName);
- if (len > 3) {
- // Calculate the temp file path that we're moving the file to. This
- // is the same as the proper service path but with a .old extension.
- LPWSTR oldServiceBinaryTempPath =
- new WCHAR[len + 1];
- memset(oldServiceBinaryTempPath, 0, (len + 1) * sizeof (WCHAR));
- wcsncpy(oldServiceBinaryTempPath, serviceConfig.lpBinaryPathName, len);
- // Rename the last 3 chars to 'old'
- wcsncpy(oldServiceBinaryTempPath + len - 3, L"old", 3);
-
- // Move the current (old) service file to the temp path.
- if (MoveFileExW(serviceConfig.lpBinaryPathName,
- oldServiceBinaryTempPath,
- MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
- // The old binary is moved out of the way, copy in the new one.
+ // Check if we already have the service installed.
+ AutoServiceHandle schService(OpenServiceW(schSCManager.get(),
+ SVC_NAME,
+ SERVICE_ALL_ACCESS));
+ DWORD lastError = GetLastError();
+ if (!schService && ERROR_SERVICE_DOES_NOT_EXIST != lastError)
+ {
+ // The service exists but we couldn't open it
+ LOG_WARN(("Could not open service. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (schService)
+ {
+ // The service exists but it may not have the correct permissions.
+ // This could happen if the permissions were not set correctly originally
+ // or have been changed after the installation. This will reset the
+ // permissions back to allow limited user accounts.
+ if (!SetUserAccessServiceDACL(schService.get()))
+ {
+ LOG_WARN(("Could not reset security ACE on service handle. It might not be "
+ "possible to start the service. This error should never "
+ "happen. (%d)", GetLastError()));
+ }
+
+ // The service exists and we opened it
+ DWORD bytesNeeded;
+ if (!QueryServiceConfigW(schService.get(), nullptr, 0, &bytesNeeded) &&
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ LOG_WARN(("Could not determine buffer size for query service config. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
+
+ // Get the service config information, in particular we want the binary
+ // path of the service.
+ std::unique_ptr<char[]> serviceConfigBuffer(new char[bytesNeeded]);
+ if (!QueryServiceConfigW(schService.get(),
+ reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()),
+ bytesNeeded, &bytesNeeded))
+ {
+ LOG_WARN(("Could open service but could not query service config. (%d)",
+ GetLastError()));
+ return FALSE;
+ }
+ QUERY_SERVICE_CONFIGW &serviceConfig =
+ *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());
+
+ // Check if we need to fix the service path
+ BOOL servicePathWasWrong;
+ static BOOL alreadyCheckedFixServicePath = FALSE;
+ if (!alreadyCheckedFixServicePath)
+ {
+ if (!FixServicePath(schService.get(), serviceConfig.lpBinaryPathName,
+ servicePathWasWrong))
+ {
+ LOG_WARN(("Could not fix service path. This should never happen. (%d)",
+ GetLastError()));
+ // True is returned because the service is pointing to
+ // maintenanceservice_tmp.exe so it actually was upgraded to the
+ // newest installed service.
+ return TRUE;
+ }
+ else if (servicePathWasWrong)
+ {
+ // Now that the path is fixed we should re-attempt the install.
+ // This current process' image path is maintenanceservice_tmp.exe.
+ // The service used to point to maintenanceservice_tmp.exe.
+ // The service was just fixed to point to maintenanceservice.exe.
+ // Re-attempting an install from scratch will work as normal.
+ alreadyCheckedFixServicePath = TRUE;
+ LOG(("Restarting install action: %d", action));
+ return SvcInstall(action);
+ }
+ }
+
+ // Ensure the service path is not quoted. We own this memory and know it to
+ // be large enough for the quoted path, so it is large enough for the
+ // unquoted path. This function cannot fail.
+ PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);
+
+ // Obtain the existing maintenanceservice file's version number and
+ // the new file's version number. Versions are in the format of
+ // A.B.C.D.
+ DWORD existingA, existingB, existingC, existingD;
+ DWORD newA, newB, newC, newD;
+ BOOL obtainedExistingVersionInfo =
+ GetVersionNumberFromPath(serviceConfig.lpBinaryPathName,
+ existingA, existingB,
+ existingC, existingD);
+ if (!GetVersionNumberFromPath(newServiceBinaryPath, newA,
+ newB, newC, newD))
+ {
+ LOG_WARN(("Could not obtain version number from new path"));
+ return FALSE;
+ }
+
+ // Check if we need to replace the old binary with the new one
+ // If we couldn't get the old version info then we assume we should
+ // replace it.
+ if (ForceInstallSvc == action ||
+ !obtainedExistingVersionInfo ||
+ (existingA < newA) ||
+ (existingA == newA && existingB < newB) ||
+ (existingA == newA && existingB == newB &&
+ existingC < newC) ||
+ (existingA == newA && existingB == newB &&
+ existingC == newC && existingD < newD))
+ {
+
+ // We have a newer updater, so update the description from the INI file.
+ UpdateServiceDescription(schService.get());
+
+ schService.reset();
+ if (!StopService())
+ {
+ return FALSE;
+ }
+
+ if (!wcscmp(newServiceBinaryPath, serviceConfig.lpBinaryPathName))
+ {
+ LOG(("File is already in the correct location, no action needed for "
+ "upgrade. The path is: \"%ls\"", newServiceBinaryPath));
+ return TRUE;
+ }
+
+ BOOL result = TRUE;
+
+ // Attempt to copy the new binary over top the existing binary.
+ // If there is an error we try to move it out of the way and then
+ // copy it in. First try the safest / easiest way to overwrite the file.
if (!CopyFileW(newServiceBinaryPath,
- serviceConfig.lpBinaryPathName, FALSE)) {
- // It is best to leave the old service binary in this condition.
- LOG_WARN(("The new service binary could not be copied in."
- " The service will not be upgraded."));
- result = FALSE;
- } else {
- LOG(("The new service binary was copied in by first moving the"
- " old one out of the way."));
+ serviceConfig.lpBinaryPathName, FALSE))
+ {
+ LOG_WARN(("Could not overwrite old service binary file. "
+ "This should never happen, but if it does the next "
+ "upgrade will fix it, the service is not a critical "
+ "component that needs to be installed for upgrades "
+ "to work. (%d)", GetLastError()));
+
+ // We rename the last 3 filename chars in an unsafe way. Manually
+ // verify there are more than 3 chars for safe failure in MoveFileExW.
+ const size_t len = wcslen(serviceConfig.lpBinaryPathName);
+ if (len > 3)
+ {
+ // Calculate the temp file path that we're moving the file to. This
+ // is the same as the proper service path but with a .old extension.
+ LPWSTR oldServiceBinaryTempPath =
+ new WCHAR[len + 1];
+ memset(oldServiceBinaryTempPath, 0, (len + 1) * sizeof (WCHAR));
+ wcsncpy(oldServiceBinaryTempPath, serviceConfig.lpBinaryPathName, len);
+ // Rename the last 3 chars to 'old'
+ wcsncpy(oldServiceBinaryTempPath + len - 3, L"old", 3);
+
+ // Move the current (old) service file to the temp path.
+ if (MoveFileExW(serviceConfig.lpBinaryPathName,
+ oldServiceBinaryTempPath,
+ MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
+ {
+ // The old binary is moved out of the way, copy in the new one.
+ if (!CopyFileW(newServiceBinaryPath,
+ serviceConfig.lpBinaryPathName, FALSE))
+ {
+ // It is best to leave the old service binary in this condition.
+ LOG_WARN(("The new service binary could not be copied in."
+ " The service will not be upgraded."));
+ result = FALSE;
+ }
+ else
+ {
+ LOG(("The new service binary was copied in by first moving the"
+ " old one out of the way."));
+ }
+
+ // Attempt to get rid of the old service temp path.
+ if (DeleteFileW(oldServiceBinaryTempPath))
+ {
+ LOG(("The old temp service path was deleted: %ls.",
+ oldServiceBinaryTempPath));
+ }
+ else
+ {
+ // The old temp path could not be removed. It will be removed
+ // the next time the user can't copy the binary in or on uninstall.
+ LOG_WARN(("The old temp service path was not deleted."));
+ }
+ }
+ else
+ {
+ // It is best to leave the old service binary in this condition.
+ LOG_WARN(("Could not move old service file out of the way from:"
+ " \"%ls\" to \"%ls\". Service will not be upgraded. (%d)",
+ serviceConfig.lpBinaryPathName,
+ oldServiceBinaryTempPath, GetLastError()));
+ result = FALSE;
+ }
+ delete[] oldServiceBinaryTempPath;
+ }
+ else
+ {
+ // It is best to leave the old service binary in this condition.
+ LOG_WARN(("Service binary path was less than 3, service will"
+ " not be updated. This should never happen."));
+ result = FALSE;
+ }
+ }
+ else
+ {
+ LOG(("The new service binary was copied in."));
}
- // Attempt to get rid of the old service temp path.
- if (DeleteFileW(oldServiceBinaryTempPath)) {
- LOG(("The old temp service path was deleted: %ls.",
- oldServiceBinaryTempPath));
- } else {
- // The old temp path could not be removed. It will be removed
- // the next time the user can't copy the binary in or on uninstall.
- LOG_WARN(("The old temp service path was not deleted."));
+ // We made a copy of ourselves to the existing location.
+ // The tmp file (the process of which we are executing right now) will be
+ // left over. Attempt to delete the file on the next reboot.
+ if (MoveFileExW(newServiceBinaryPath, nullptr,
+ MOVEFILE_DELAY_UNTIL_REBOOT))
+ {
+ LOG(("Deleting the old file path on the next reboot: %ls.",
+ newServiceBinaryPath));
+ }
+ else
+ {
+ LOG_WARN(("Call to delete the old file path failed: %ls.",
+ newServiceBinaryPath));
}
- } else {
- // It is best to leave the old service binary in this condition.
- LOG_WARN(("Could not move old service file out of the way from:"
- " \"%ls\" to \"%ls\". Service will not be upgraded. (%d)",
- serviceConfig.lpBinaryPathName,
- oldServiceBinaryTempPath, GetLastError()));
- result = FALSE;
- }
- delete[] oldServiceBinaryTempPath;
- } else {
- // It is best to leave the old service binary in this condition.
- LOG_WARN(("Service binary path was less than 3, service will"
- " not be updated. This should never happen."));
- result = FALSE;
+
+ return result;
}
- } else {
- LOG(("The new service binary was copied in."));
- }
-
- // We made a copy of ourselves to the existing location.
- // The tmp file (the process of which we are executing right now) will be
- // left over. Attempt to delete the file on the next reboot.
- if (MoveFileExW(newServiceBinaryPath, nullptr,
- MOVEFILE_DELAY_UNTIL_REBOOT)) {
- LOG(("Deleting the old file path on the next reboot: %ls.",
- newServiceBinaryPath));
- } else {
- LOG_WARN(("Call to delete the old file path failed: %ls.",
- newServiceBinaryPath));
- }
-
- return result;
- }
-
- // We don't need to copy ourselves to the existing location.
- // The tmp file (the process of which we are executing right now) will be
- // left over. Attempt to delete the file on the next reboot.
- MoveFileExW(newServiceBinaryPath, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT);
-
- // nothing to do, we already have a newer service installed
- return TRUE;
- }
- // If the service does not exist and we are upgrading, don't install it.
- if (UpgradeSvc == action) {
- // The service does not exist and we are upgrading, so don't install it
+ // We don't need to copy ourselves to the existing location.
+ // The tmp file (the process of which we are executing right now) will be
+ // left over. Attempt to delete the file on the next reboot.
+ MoveFileExW(newServiceBinaryPath, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT);
+
+ // nothing to do, we already have a newer service installed
+ return TRUE;
+ }
+
+ // If the service does not exist and we are upgrading, don't install it.
+ if (UpgradeSvc == action)
+ {
+ // The service does not exist and we are upgrading, so don't install it
+ return TRUE;
+ }
+
+ // Quote the path only if it contains spaces.
+ PathQuoteSpacesW(newServiceBinaryPath);
+ // The service does not already exist so create the service as on demand
+ schService.reset(CreateServiceW(schSCManager.get(), SVC_NAME, SVC_DISPLAY_NAME,
+ SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
+ newServiceBinaryPath, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+ if (!schService)
+ {
+ LOG_WARN(("Could not create Windows service. "
+ "This error should never happen since a service install "
+ "should only be called when elevated. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (!SetUserAccessServiceDACL(schService.get()))
+ {
+ LOG_WARN(("Could not set security ACE on service handle, the service will not "
+ "be able to be started from unelevated processes. "
+ "This error should never happen. (%d)",
+ GetLastError()));
+ }
+
+ UpdateServiceDescription(schService.get());
+
return TRUE;
- }
-
- // Quote the path only if it contains spaces.
- PathQuoteSpacesW(newServiceBinaryPath);
- // The service does not already exist so create the service as on demand
- schService.reset(CreateServiceW(schSCManager.get(), SVC_NAME, SVC_DISPLAY_NAME,
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
- newServiceBinaryPath, nullptr, nullptr,
- nullptr, nullptr, nullptr));
- if (!schService) {
- LOG_WARN(("Could not create Windows service. "
- "This error should never happen since a service install "
- "should only be called when elevated. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (!SetUserAccessServiceDACL(schService.get())) {
- LOG_WARN(("Could not set security ACE on service handle, the service will not "
- "be able to be started from unelevated processes. "
- "This error should never happen. (%d)",
- GetLastError()));
- }
-
- UpdateServiceDescription(schService.get());
-
- return TRUE;
}
/**
@@ -541,42 +591,45 @@ SvcInstall(SvcInstallAction action)
BOOL
StopService()
{
- // Get a handle to the local computer SCM database with full access rights.
- AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
- SC_MANAGER_ALL_ACCESS));
- if (!schSCManager) {
- LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
- return FALSE;
- }
-
- // Open the service
- AutoServiceHandle schService(OpenServiceW(schSCManager.get(), SVC_NAME,
- SERVICE_ALL_ACCESS));
- if (!schService) {
- LOG_WARN(("Could not open service. (%d)", GetLastError()));
- return FALSE;
- }
-
- LOG(("Sending stop request..."));
- SERVICE_STATUS status;
- SetLastError(ERROR_SUCCESS);
- if (!ControlService(schService.get(), SERVICE_CONTROL_STOP, &status) &&
- GetLastError() != ERROR_SERVICE_NOT_ACTIVE) {
- LOG_WARN(("Error sending stop request. (%d)", GetLastError()));
- }
-
- schSCManager.reset();
- schService.reset();
-
- LOG(("Waiting for service stop..."));
- DWORD lastState = WaitForServiceStop(SVC_NAME, 30);
-
- // The service can be in a stopped state but the exe still in use
- // so make sure the process is really gone before proceeding
- WaitForProcessExit(L"maintenanceservice.exe", 30);
- LOG(("Done waiting for service stop, last service state: %d", lastState));
-
- return lastState == SERVICE_STOPPED;
+ // Get a handle to the local computer SCM database with full access rights.
+ AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_ALL_ACCESS));
+ if (!schSCManager)
+ {
+ LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ // Open the service
+ AutoServiceHandle schService(OpenServiceW(schSCManager.get(), SVC_NAME,
+ SERVICE_ALL_ACCESS));
+ if (!schService)
+ {
+ LOG_WARN(("Could not open service. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ LOG(("Sending stop request..."));
+ SERVICE_STATUS status;
+ SetLastError(ERROR_SUCCESS);
+ if (!ControlService(schService.get(), SERVICE_CONTROL_STOP, &status) &&
+ GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
+ {
+ LOG_WARN(("Error sending stop request. (%d)", GetLastError()));
+ }
+
+ schSCManager.reset();
+ schService.reset();
+
+ LOG(("Waiting for service stop..."));
+ DWORD lastState = WaitForServiceStop(SVC_NAME, 30);
+
+ // The service can be in a stopped state but the exe still in use
+ // so make sure the process is really gone before proceeding
+ WaitForProcessExit(L"maintenanceservice.exe", 30);
+ LOG(("Done waiting for service stop, last service state: %d", lastState));
+
+ return lastState == SERVICE_STOPPED;
}
/**
@@ -587,46 +640,55 @@ StopService()
BOOL
SvcUninstall()
{
- // Get a handle to the local computer SCM database with full access rights.
- AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
- SC_MANAGER_ALL_ACCESS));
- if (!schSCManager) {
- LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
- return FALSE;
- }
-
- // Open the service
- AutoServiceHandle schService(OpenServiceW(schSCManager.get(), SVC_NAME,
- SERVICE_ALL_ACCESS));
- if (!schService) {
- LOG_WARN(("Could not open service. (%d)", GetLastError()));
- return FALSE;
- }
-
- //Stop the service so it deletes faster and so the uninstaller
- // can actually delete its EXE.
- DWORD totalWaitTime = 0;
- SERVICE_STATUS status;
- static const int maxWaitTime = 1000 * 60; // Never wait more than a minute
- if (ControlService(schService.get(), SERVICE_CONTROL_STOP, &status)) {
- do {
- Sleep(status.dwWaitHint);
- totalWaitTime += (status.dwWaitHint + 10);
- if (status.dwCurrentState == SERVICE_STOPPED) {
- break;
- } else if (totalWaitTime > maxWaitTime) {
- break;
- }
- } while (QueryServiceStatus(schService.get(), &status));
- }
-
- // Delete the service or mark it for deletion
- BOOL deleted = DeleteService(schService.get());
- if (!deleted) {
- deleted = (GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE);
- }
-
- return deleted;
+ // Get a handle to the local computer SCM database with full access rights.
+ AutoServiceHandle schSCManager(OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_ALL_ACCESS));
+ if (!schSCManager)
+ {
+ LOG_WARN(("Could not open service manager. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ // Open the service
+ AutoServiceHandle schService(OpenServiceW(schSCManager.get(), SVC_NAME,
+ SERVICE_ALL_ACCESS));
+ if (!schService)
+ {
+ LOG_WARN(("Could not open service. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ //Stop the service so it deletes faster and so the uninstaller
+ // can actually delete its EXE.
+ DWORD totalWaitTime = 0;
+ SERVICE_STATUS status;
+ static const int maxWaitTime = 1000 * 60; // Never wait more than a minute
+ if (ControlService(schService.get(), SERVICE_CONTROL_STOP, &status))
+ {
+ do
+ {
+ Sleep(status.dwWaitHint);
+ totalWaitTime += (status.dwWaitHint + 10);
+ if (status.dwCurrentState == SERVICE_STOPPED)
+ {
+ break;
+ }
+ else if (totalWaitTime > maxWaitTime)
+ {
+ break;
+ }
+ }
+ while (QueryServiceStatus(schService.get(), &status));
+ }
+
+ // Delete the service or mark it for deletion
+ BOOL deleted = DeleteService(schService.get());
+ if (!deleted)
+ {
+ deleted = (GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE);
+ }
+
+ return deleted;
}
/**
@@ -638,16 +700,18 @@ SvcUninstall()
BOOL
SetUserAccessServiceDACL(SC_HANDLE hService)
{
- PACL pNewAcl = nullptr;
- PSECURITY_DESCRIPTOR psd = nullptr;
- DWORD lastError = SetUserAccessServiceDACL(hService, pNewAcl, psd);
- if (pNewAcl) {
- LocalFree((HLOCAL)pNewAcl);
- }
- if (psd) {
- LocalFree((LPVOID)psd);
- }
- return ERROR_SUCCESS == lastError;
+ PACL pNewAcl = nullptr;
+ PSECURITY_DESCRIPTOR psd = nullptr;
+ DWORD lastError = SetUserAccessServiceDACL(hService, pNewAcl, psd);
+ if (pNewAcl)
+ {
+ LocalFree((HLOCAL)pNewAcl);
+ }
+ if (psd)
+ {
+ LocalFree((LPVOID)psd);
+ }
+ return ERROR_SUCCESS == lastError;
}
/**
@@ -662,112 +726,124 @@ DWORD
SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl,
PSECURITY_DESCRIPTOR psd)
{
- // Get the current security descriptor needed size
- DWORD needed = 0;
- if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION,
- &psd, 0, &needed)) {
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- LOG_WARN(("Could not query service object security size. (%d)",
- GetLastError()));
- return GetLastError();
+ // Get the current security descriptor needed size
+ DWORD needed = 0;
+ if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION,
+ &psd, 0, &needed))
+ {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ LOG_WARN(("Could not query service object security size. (%d)",
+ GetLastError()));
+ return GetLastError();
+ }
+
+ DWORD size = needed;
+ psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
+ if (!psd)
+ {
+ LOG_WARN(("Could not allocate security descriptor. (%d)",
+ GetLastError()));
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ // Get the actual security descriptor now
+ if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION,
+ psd, size, &needed))
+ {
+ LOG_WARN(("Could not allocate security descriptor. (%d)",
+ GetLastError()));
+ return GetLastError();
+ }
}
- DWORD size = needed;
- psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
- if (!psd) {
- LOG_WARN(("Could not allocate security descriptor. (%d)",
- GetLastError()));
- return ERROR_INSUFFICIENT_BUFFER;
+ // Get the current DACL from the security descriptor.
+ PACL pacl = nullptr;
+ BOOL bDaclPresent = FALSE;
+ BOOL bDaclDefaulted = FALSE;
+ if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
+ &bDaclDefaulted))
+ {
+ LOG_WARN(("Could not obtain DACL. (%d)", GetLastError()));
+ return GetLastError();
}
- // Get the actual security descriptor now
- if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION,
- psd, size, &needed)) {
- LOG_WARN(("Could not allocate security descriptor. (%d)",
- GetLastError()));
- return GetLastError();
- }
- }
-
- // Get the current DACL from the security descriptor.
- PACL pacl = nullptr;
- BOOL bDaclPresent = FALSE;
- BOOL bDaclDefaulted = FALSE;
- if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
- &bDaclDefaulted)) {
- LOG_WARN(("Could not obtain DACL. (%d)", GetLastError()));
- return GetLastError();
- }
-
- PSID sid;
- DWORD SIDSize = SECURITY_MAX_SID_SIZE;
- sid = LocalAlloc(LMEM_FIXED, SIDSize);
- if (!sid) {
- LOG_WARN(("Could not allocate SID memory. (%d)", GetLastError()));
- return GetLastError();
- }
-
- if (!CreateWellKnownSid(WinBuiltinUsersSid, nullptr, sid, &SIDSize)) {
- DWORD lastError = GetLastError();
- LOG_WARN(("Could not create well known SID. (%d)", lastError));
- LocalFree(sid);
- return lastError;
- }
-
- // Lookup the account name, the function fails if you don't pass in
- // a buffer for the domain name but it's not used since we're using
- // the built in account Sid.
- SID_NAME_USE accountType;
- WCHAR accountName[UNLEN + 1] = { L'\0' };
- WCHAR domainName[DNLEN + 1] = { L'\0' };
- DWORD accountNameSize = UNLEN + 1;
- DWORD domainNameSize = DNLEN + 1;
- if (!LookupAccountSidW(nullptr, sid, accountName,
- &accountNameSize,
- domainName, &domainNameSize, &accountType)) {
- LOG_WARN(("Could not lookup account Sid, will try Users. (%d)",
- GetLastError()));
- wcsncpy(accountName, L"Users", UNLEN);
- }
-
- // We already have the group name so we can get rid of the SID
- FreeSid(sid);
- sid = nullptr;
-
- // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged.
- EXPLICIT_ACCESS ea;
- BuildExplicitAccessWithNameW(&ea, accountName,
- SERVICE_START | SERVICE_STOP | GENERIC_READ,
- SET_ACCESS, NO_INHERITANCE);
- DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
- if (ERROR_SUCCESS != lastError) {
- LOG_WARN(("Could not set entries in ACL. (%d)", lastError));
- return lastError;
- }
-
- // Initialize a new security descriptor.
- SECURITY_DESCRIPTOR sd;
- if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
- LOG_WARN(("Could not initialize security descriptor. (%d)",
- GetLastError()));
- return GetLastError();
- }
-
- // Set the new DACL in the security descriptor.
- if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) {
- LOG_WARN(("Could not set security descriptor DACL. (%d)",
- GetLastError()));
- return GetLastError();
- }
-
- // Set the new security descriptor for the service object.
- if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd)) {
- LOG_WARN(("Could not set object security. (%d)",
- GetLastError()));
- return GetLastError();
- }
-
- // Woohoo, raise the roof
- LOG(("User access was set successfully on the service."));
- return ERROR_SUCCESS;
+ PSID sid;
+ DWORD SIDSize = SECURITY_MAX_SID_SIZE;
+ sid = LocalAlloc(LMEM_FIXED, SIDSize);
+ if (!sid)
+ {
+ LOG_WARN(("Could not allocate SID memory. (%d)", GetLastError()));
+ return GetLastError();
+ }
+
+ if (!CreateWellKnownSid(WinBuiltinUsersSid, nullptr, sid, &SIDSize))
+ {
+ DWORD lastError = GetLastError();
+ LOG_WARN(("Could not create well known SID. (%d)", lastError));
+ LocalFree(sid);
+ return lastError;
+ }
+
+ // Lookup the account name, the function fails if you don't pass in
+ // a buffer for the domain name but it's not used since we're using
+ // the built in account Sid.
+ SID_NAME_USE accountType;
+ WCHAR accountName[UNLEN + 1] = { L'\0' };
+ WCHAR domainName[DNLEN + 1] = { L'\0' };
+ DWORD accountNameSize = UNLEN + 1;
+ DWORD domainNameSize = DNLEN + 1;
+ if (!LookupAccountSidW(nullptr, sid, accountName,
+ &accountNameSize,
+ domainName, &domainNameSize, &accountType))
+ {
+ LOG_WARN(("Could not lookup account Sid, will try Users. (%d)",
+ GetLastError()));
+ wcsncpy(accountName, L"Users", UNLEN);
+ }
+
+ // We already have the group name so we can get rid of the SID
+ FreeSid(sid);
+ sid = nullptr;
+
+ // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged.
+ EXPLICIT_ACCESS ea;
+ BuildExplicitAccessWithNameW(&ea, accountName,
+ SERVICE_START | SERVICE_STOP | GENERIC_READ,
+ SET_ACCESS, NO_INHERITANCE);
+ DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
+ if (ERROR_SUCCESS != lastError)
+ {
+ LOG_WARN(("Could not set entries in ACL. (%d)", lastError));
+ return lastError;
+ }
+
+ // Initialize a new security descriptor.
+ SECURITY_DESCRIPTOR sd;
+ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ LOG_WARN(("Could not initialize security descriptor. (%d)",
+ GetLastError()));
+ return GetLastError();
+ }
+
+ // Set the new DACL in the security descriptor.
+ if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
+ {
+ LOG_WARN(("Could not set security descriptor DACL. (%d)",
+ GetLastError()));
+ return GetLastError();
+ }
+
+ // Set the new security descriptor for the service object.
+ if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd))
+ {
+ LOG_WARN(("Could not set object security. (%d)",
+ GetLastError()));
+ return GetLastError();
+ }
+
+ // Woohoo, raise the roof
+ LOG(("User access was set successfully on the service."));
+ return ERROR_SUCCESS;
}
diff --git a/onlineupdate/source/service/serviceinstall.hxx b/onlineupdate/source/service/serviceinstall.hxx
index d8532a968e42..1afaada84519 100644
--- a/onlineupdate/source/service/serviceinstall.hxx
+++ b/onlineupdate/source/service/serviceinstall.hxx
@@ -11,11 +11,11 @@ BOOL SvcInstall(SvcInstallAction action);
BOOL SvcUninstall();
BOOL StopService();
BOOL SetUserAccessServiceDACL(SC_HANDLE hService);
-DWORD SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl,
+DWORD SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl,
PSECURITY_DESCRIPTOR psd);
struct MaintenanceServiceStringTable
{
- char serviceDescription[MAX_TEXT_LEN];
+ char serviceDescription[MAX_TEXT_LEN];
};
diff --git a/onlineupdate/source/service/workmonitor.cxx b/onlineupdate/source/service/workmonitor.cxx
index 76bbe1c911d7..05cf2481e7ce 100644
--- a/onlineupdate/source/service/workmonitor.cxx
+++ b/onlineupdate/source/service/workmonitor.cxx
@@ -45,38 +45,41 @@ BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath,
static BOOL
IsStatusApplying(LPCWSTR updateDirPath, BOOL &isApplying)
{
- isApplying = FALSE;
- WCHAR updateStatusFilePath[MAX_PATH + 1] = {L'\0'};
- wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
- if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
- LOG_WARN(("Could not append path for update.status file"));
- return FALSE;
- }
-
- AutoHandle statusFile(CreateFileW(updateStatusFilePath, GENERIC_READ,
+ isApplying = FALSE;
+ WCHAR updateStatusFilePath[MAX_PATH + 1] = {L'\0'};
+ wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
+ if (!PathAppendSafe(updateStatusFilePath, L"update.status"))
+ {
+ LOG_WARN(("Could not append path for update.status file"));
+ return FALSE;
+ }
+
+ AutoHandle statusFile(CreateFileW(updateStatusFilePath, GENERIC_READ,
FILE_SHARE_READ |
FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, 0, nullptr));
- if (statusFile == INVALID_HANDLE_VALUE) {
- LOG_WARN(("Could not open update.status file"));
- return FALSE;
- }
+ if (statusFile == INVALID_HANDLE_VALUE)
+ {
+ LOG_WARN(("Could not open update.status file"));
+ return FALSE;
+ }
- char buf[32] = { 0 };
- DWORD read;
- if (!ReadFile(statusFile.get(), buf, sizeof(buf), &read, nullptr)) {
- LOG_WARN(("Could not read from update.status file"));
- return FALSE;
- }
+ char buf[32] = { 0 };
+ DWORD read;
+ if (!ReadFile(statusFile.get(), buf, sizeof(buf), &read, nullptr))
+ {
+ LOG_WARN(("Could not read from update.status file"));
+ return FALSE;
+ }
- LOG(("updater.exe returned status: %s", buf));
+ LOG(("updater.exe returned status: %s", buf));
- const char kApplying[] = "applying";
- isApplying = strncmp(buf, kApplying,
- sizeof(kApplying) - 1) == 0;
- return TRUE;
+ const char kApplying[] = "applying";
+ isApplying = strncmp(buf, kApplying,
+ sizeof(kApplying) - 1) == 0;
+ return TRUE;
}
/**
@@ -89,9 +92,9 @@ IsStatusApplying(LPCWSTR updateDirPath, BOOL &isApplying)
static bool
IsUpdateBeingStaged(int argc, LPWSTR *argv)
{
- // PID will be set to -1 if we're supposed to stage an update.
- return argc == 4 && !wcscmp(argv[3], L"-1") ||
- argc == 5 && !wcscmp(argv[4], L"-1");
+ // PID will be set to -1 if we're supposed to stage an update.
+ return argc == 4 && !wcscmp(argv[3], L"-1") ||
+ argc == 5 && !wcscmp(argv[4], L"-1");
}
/**
@@ -103,12 +106,14 @@ IsUpdateBeingStaged(int argc, LPWSTR *argv)
static bool
IsDigits(WCHAR *str)
{
- while (*str) {
- if (!iswdigit(*str++)) {
- return FALSE;
+ while (*str)
+ {
+ if (!iswdigit(*str++))
+ {
+ return FALSE;
+ }
}
- }
- return TRUE;
+ return TRUE;
}
/**
@@ -124,8 +129,8 @@ IsDigits(WCHAR *str)
static bool
IsOldCommandline(int argc, LPWSTR *argv)
{
- return argc == 4 && !wcscmp(argv[3], L"-1") ||
- argc >= 4 && (wcsstr(argv[3], L"/replace") || IsDigits(argv[3]));
+ return argc == 4 && !wcscmp(argv[3], L"-1") ||
+ argc >= 4 && (wcsstr(argv[3], L"/replace") || IsDigits(argv[3]));
}
/**
@@ -138,31 +143,36 @@ IsOldCommandline(int argc, LPWSTR *argv)
static BOOL
GetInstallationDir(int argcTmp, LPWSTR *argvTmp, WCHAR aResultDir[MAX_PATH + 1])
{
- int index = 3;
- if (IsOldCommandline(argcTmp, argvTmp)) {
- index = 2;
- }
-
- if (argcTmp < index) {
- return FALSE;
- }
-
- wcsncpy(aResultDir, argvTmp[2], MAX_PATH);
- WCHAR* backSlash = wcsrchr(aResultDir, L'\\');
- // Make sure that the path does not include trailing backslashes
- if (backSlash && (backSlash[1] == L'\0')) {
- *backSlash = L'\0';
- }
-
- // The new command line's argv[2] is always the installation directory.
- if (index == 2) {
- bool backgroundUpdate = IsUpdateBeingStaged(argcTmp, argvTmp);
- bool replaceRequest = (argcTmp >= 4 && wcsstr(argvTmp[3], L"/replace"));
- if (backgroundUpdate || replaceRequest) {
- return PathRemoveFileSpecW(aResultDir);
- }
- }
- return TRUE;
+ int index = 3;
+ if (IsOldCommandline(argcTmp, argvTmp))
+ {
+ index = 2;
+ }
+
+ if (argcTmp < index)
+ {
+ return FALSE;
+ }
+
+ wcsncpy(aResultDir, argvTmp[2], MAX_PATH);
+ WCHAR* backSlash = wcsrchr(aResultDir, L'\\');
+ // Make sure that the path does not include trailing backslashes
+ if (backSlash && (backSlash[1] == L'\0'))
+ {
+ *backSlash = L'\0';
+ }
+
+ // The new command line's argv[2] is always the installation directory.
+ if (index == 2)
+ {
+ bool backgroundUpdate = IsUpdateBeingStaged(argcTmp, argvTmp);
+ bool replaceRequest = (argcTmp >= 4 && wcsstr(argvTmp[3], L"/replace"));
+ if (backgroundUpdate || replaceRequest)
+ {
+ return PathRemoveFileSpecW(aResultDir);
+ }
+ }
+ return TRUE;
}
/**
@@ -180,150 +190,172 @@ StartUpdateProcess(int argc,
LPCWSTR installDir,
BOOL &processStarted)
{
- LOG(("Starting update process as the service in session 0."));
- STARTUPINFO si = {0};
- si.cb = sizeof(STARTUPINFO);
- si.lpDesktop = L"winsta0\\Default";
- PROCESS_INFORMATION pi = {0};
-
- // The updater command line is of the form:
- // updater.exe update-dir apply [wait-pid [callback-dir callback-path args]]
- LPWSTR cmdLine = MakeCommandLine(argc, argv);
-
- int index = 3;
- if (IsOldCommandline(argc, argv)) {
- index = 2;
- }
-
- // If we're about to start the update process from session 0,
- // then we should not show a GUI. This only really needs to be done
- // on Vista and higher, but it's better to keep everything consistent
- // across all OS if it's of no harm.
- if (argc >= index) {
- // Setting the desktop to blank will ensure no GUI is displayed
- si.lpDesktop = L"";
- si.dwFlags |= STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
- }
-
- // We move the updater.ini file out of the way because we will handle
- // executing PostUpdate through the service. We handle PostUpdate from
- // the service because there are some per user things that happen that
- // can't run in session 0 which we run updater.exe in.
- // Once we are done running updater.exe we rename updater.ini back so
- // that if there were any errors the next updater.exe will run correctly.
- WCHAR updaterINI[MAX_PATH + 1];
- WCHAR updaterINITemp[MAX_PATH + 1];
- BOOL selfHandlePostUpdate = FALSE;
- // We use the updater.ini from the same directory as the updater.exe
- // because of background updates.
- if (PathGetSiblingFilePath(updaterINI, argv[0], L"updater.ini") &&
- PathGetSiblingFilePath(updaterINITemp, argv[0], L"updater.tmp")) {
- selfHandlePostUpdate = MoveFileExW(updaterINI, updaterINITemp,
- MOVEFILE_REPLACE_EXISTING);
- }
-
- // Add an env var for USING_SERVICE so the updater.exe can
- // do anything special that it needs to do for service updates.
- // Search in updater.cpp for more info on USING_SERVICE.
- putenv(const_cast<char*>("USING_SERVICE=1"));
- LOG(("Starting service with cmdline: %ls", cmdLine));
- processStarted = CreateProcessW(argv[0], cmdLine,
- nullptr, nullptr, FALSE,
- CREATE_DEFAULT_ERROR_MODE,
- nullptr,
- nullptr, &si, &pi);
- // Empty value on putenv is how you remove an env variable in Windows
- putenv(const_cast<char*>("USING_SERVICE="));
-
- BOOL updateWasSuccessful = FALSE;
- if (processStarted) {
- // Wait for the updater process to finish
- LOG(("Process was started... waiting on result."));
- DWORD waitRes = WaitForSingleObject(pi.hProcess, TIME_TO_WAIT_ON_UPDATER);
- if (WAIT_TIMEOUT == waitRes) {
- // We waited a long period of time for updater.exe and it never finished
- // so kill it.
- TerminateProcess(pi.hProcess, 1);
- } else {
- // Check the return code of updater.exe to make sure we get 0
- DWORD returnCode;
- if (GetExitCodeProcess(pi.hProcess, &returnCode)) {
- LOG(("Process finished with return code %d.", returnCode));
- // updater returns 0 if successful.
- updateWasSuccessful = (returnCode == 0);
- } else {
- LOG_WARN(("Process finished but could not obtain return code."));
- }
- }
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
-
- // Check just in case updater.exe didn't change the status from
- // applying. If this is the case we report an error.
- BOOL isApplying = FALSE;
- if (IsStatusApplying(argv[1], isApplying) && isApplying) {
- if (updateWasSuccessful) {
- LOG(("update.status is still applying even know update "
- " was successful."));
- if (!WriteStatusFailure(argv[1],
- SERVICE_STILL_APPLYING_ON_SUCCESS)) {
- LOG_WARN(("Could not write update.status still applying on"
- " success error."));
+ LOG(("Starting update process as the service in session 0."));
+ STARTUPINFO si = {0};
+ si.cb = sizeof(STARTUPINFO);
+ si.lpDesktop = L"winsta0\\Default";
+ PROCESS_INFORMATION pi = {0};
+
+ // The updater command line is of the form:
+ // updater.exe update-dir apply [wait-pid [callback-dir callback-path args]]
+ LPWSTR cmdLine = MakeCommandLine(argc, argv);
+
+ int index = 3;
+ if (IsOldCommandline(argc, argv))
+ {
+ index = 2;
+ }
+
+ // If we're about to start the update process from session 0,
+ // then we should not show a GUI. This only really needs to be done
+ // on Vista and higher, but it's better to keep everything consistent
+ // across all OS if it's of no harm.
+ if (argc >= index)
+ {
+ // Setting the desktop to blank will ensure no GUI is displayed
+ si.lpDesktop = L"";
+ si.dwFlags |= STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+ }
+
+ // We move the updater.ini file out of the way because we will handle
+ // executing PostUpdate through the service. We handle PostUpdate from
+ // the service because there are some per user things that happen that
+ // can't run in session 0 which we run updater.exe in.
+ // Once we are done running updater.exe we rename updater.ini back so
+ // that if there were any errors the next updater.exe will run correctly.
+ WCHAR updaterINI[MAX_PATH + 1];
+ WCHAR updaterINITemp[MAX_PATH + 1];
+ BOOL selfHandlePostUpdate = FALSE;
+ // We use the updater.ini from the same directory as the updater.exe
+ // because of background updates.
+ if (PathGetSiblingFilePath(updaterINI, argv[0], L"updater.ini") &&
+ PathGetSiblingFilePath(updaterINITemp, argv[0], L"updater.tmp"))
+ {
+ selfHandlePostUpdate = MoveFileExW(updaterINI, updaterINITemp,
+ MOVEFILE_REPLACE_EXISTING);
+ }
+
+ // Add an env var for USING_SERVICE so the updater.exe can
+ // do anything special that it needs to do for service updates.
+ // Search in updater.cpp for more info on USING_SERVICE.
+ putenv(const_cast<char*>("USING_SERVICE=1"));
+ LOG(("Starting service with cmdline: %ls", cmdLine));
+ processStarted = CreateProcessW(argv[0], cmdLine,
+ nullptr, nullptr, FALSE,
+ CREATE_DEFAULT_ERROR_MODE,
+ nullptr,
+ nullptr, &si, &pi);
+ // Empty value on putenv is how you remove an env variable in Windows
+ putenv(const_cast<char*>("USING_SERVICE="));
+
+ BOOL updateWasSuccessful = FALSE;
+ if (processStarted)
+ {
+ // Wait for the updater process to finish
+ LOG(("Process was started... waiting on result."));
+ DWORD waitRes = WaitForSingleObject(pi.hProcess, TIME_TO_WAIT_ON_UPDATER);
+ if (WAIT_TIMEOUT == waitRes)
+ {
+ // We waited a long period of time for updater.exe and it never finished
+ // so kill it.
+ TerminateProcess(pi.hProcess, 1);
}
- // Since we still had applying we know updater.exe didn't do its
- // job correctly.
- updateWasSuccessful = FALSE;
- } else {
- LOG_WARN(("update.status is still applying and update was not successful."));
- if (!WriteStatusFailure(argv[1],
- SERVICE_STILL_APPLYING_ON_FAILURE)) {
- LOG_WARN(("Could not write update.status still applying on"
- " success error."));
+ else
+ {
+ // Check the return code of updater.exe to make sure we get 0
+ DWORD returnCode;
+ if (GetExitCodeProcess(pi.hProcess, &returnCode))
+ {
+ LOG(("Process finished with return code %d.", returnCode));
+ // updater returns 0 if successful.
+ updateWasSuccessful = (returnCode == 0);
+ }
+ else
+ {
+ LOG_WARN(("Process finished but could not obtain return code."));
+ }
+ }
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ // Check just in case updater.exe didn't change the status from
+ // applying. If this is the case we report an error.
+ BOOL isApplying = FALSE;
+ if (IsStatusApplying(argv[1], isApplying) && isApplying)
+ {
+ if (updateWasSuccessful)
+ {
+ LOG(("update.status is still applying even know update "
+ " was successful."));
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_STILL_APPLYING_ON_SUCCESS))
+ {
+ LOG_WARN(("Could not write update.status still applying on"
+ " success error."));
+ }
+ // Since we still had applying we know updater.exe didn't do its
+ // job correctly.
+ updateWasSuccessful = FALSE;
+ }
+ else
+ {
+ LOG_WARN(("update.status is still applying and update was not successful."));
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_STILL_APPLYING_ON_FAILURE))
+ {
+ LOG_WARN(("Could not write update.status still applying on"
+ " success error."));
+ }
+ }
}
- }
- }
- } else {
- DWORD lastError = GetLastError();
- LOG_WARN(("Could not create process as current user, "
- "updaterPath: %ls; cmdLine: %ls. (%d)",
- argv[0], cmdLine, lastError));
- }
-
- // Now that we're done with the update, restore back the updater.ini file
- // We use it ourselves, and also we want it back in case we had any type
- // of error so that the normal update process can use it.
- if (selfHandlePostUpdate) {
- MoveFileExW(updaterINITemp, updaterINI, MOVEFILE_REPLACE_EXISTING);
-
- // Only run the PostUpdate if the update was successful
- if (updateWasSuccessful && argc > index) {
- LPCWSTR updateInfoDir = argv[1];
- bool stagingUpdate = IsUpdateBeingStaged(argc, argv);
-
- // Launch the PostProcess with admin access in session 0. This is
- // actually launching the post update process but it takes in the
- // callback app path to figure out where to apply to.
- // The PostUpdate process with user only access will be done inside
- // the unelevated updater.exe after the update process is complete
- // from the service. We don't know here which session to start
- // the user PostUpdate process from.
- // Note that we don't need to do this if we're just staging the
- // update in the background, as the PostUpdate step runs when
- // performing the replacing in that case.
- if (!stagingUpdate) {
- LOG(("Launching post update process as the service in session 0."));
- if (!LaunchWinPostProcess(installDir, updateInfoDir, true, nullptr)) {
- LOG_WARN(("The post update process could not be launched."
- " installDir: %ls, updateInfoDir: %ls",
- installDir, updateInfoDir));
+ }
+ else
+ {
+ DWORD lastError = GetLastError();
+ LOG_WARN(("Could not create process as current user, "
+ "updaterPath: %ls; cmdLine: %ls. (%d)",
+ argv[0], cmdLine, lastError));
+ }
+
+ // Now that we're done with the update, restore back the updater.ini file
+ // We use it ourselves, and also we want it back in case we had any type
+ // of error so that the normal update process can use it.
+ if (selfHandlePostUpdate)
+ {
+ MoveFileExW(updaterINITemp, updaterINI, MOVEFILE_REPLACE_EXISTING);
+
+ // Only run the PostUpdate if the update was successful
+ if (updateWasSuccessful && argc > index)
+ {
+ LPCWSTR updateInfoDir = argv[1];
+ bool stagingUpdate = IsUpdateBeingStaged(argc, argv);
+
+ // Launch the PostProcess with admin access in session 0. This is
+ // actually launching the post update process but it takes in the
+ // callback app path to figure out where to apply to.
+ // The PostUpdate process with user only access will be done inside
+ // the unelevated updater.exe after the update process is complete
+ // from the service. We don't know here which session to start
+ // the user PostUpdate process from.
+ // Note that we don't need to do this if we're just staging the
+ // update in the background, as the PostUpdate step runs when
+ // performing the replacing in that case.
+ if (!stagingUpdate)
+ {
+ LOG(("Launching post update process as the service in session 0."));
+ if (!LaunchWinPostProcess(installDir, updateInfoDir, true, nullptr))
+ {
+ LOG_WARN(("The post update process could not be launched."
+ " installDir: %ls, updateInfoDir: %ls",
+ installDir, updateInfoDir));
+ }
+ }
}
- }
}
- }
- free(cmdLine);
- return updateWasSuccessful;
+ free(cmdLine);
+ return updateWasSuccessful;
}
/**
@@ -337,185 +369,219 @@ StartUpdateProcess(int argc,
BOOL
ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
{
- BOOL result = TRUE;
- if (argc < 3) {
- LOG_WARN(("Not enough command line parameters specified. "
- "Updating update.status."));
-
- // We can only update update.status if argv[1] exists. argv[1] is
- // the directory where the update.status file exists.
- if (argc < 2 ||
- !WriteStatusFailure(argv[1],
- SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS)) {
- LOG_WARN(("Could not write update.status service update failure. (%d)",
- GetLastError()));
- }
- return FALSE;
- }
-
- WCHAR installDir[MAX_PATH + 1] = {L'\0'};
- if (!GetInstallationDir(argc, argv, installDir)) {
- LOG_WARN(("Could not get the installation directory"));
- if (!WriteStatusFailure(argv[1],
- SERVICE_INSTALLDIR_ERROR)) {
- LOG_WARN(("Could not write update.status for GetInstallationDir failure."));
- }
- return FALSE;
- }
-
- // Make sure the path to the updater to use for the update is local.
- // We do this check to make sure that file locking is available for
- // race condition security checks.
- BOOL isLocal = FALSE;
- if (!IsLocalFile(argv[0], isLocal) || !isLocal) {
- LOG_WARN(("Filesystem in path %ls is not supported (%d)",
- argv[0], GetLastError()));
- if (!WriteStatusFailure(argv[1],
- SERVICE_UPDATER_NOT_FIXED_DRIVE)) {
- LOG_WARN(("Could not write update.status service update failure. (%d)",
- GetLastError()));
- }
- return FALSE;
- }
-
- AutoHandle noWriteLock(CreateFileW(argv[0], GENERIC_READ, FILE_SHARE_READ,
+ BOOL result = TRUE;
+ if (argc < 3)
+ {
+ LOG_WARN(("Not enough command line parameters specified. "
+ "Updating update.status."));
+
+ // We can only update update.status if argv[1] exists. argv[1] is
+ // the directory where the update.status file exists.
+ if (argc < 2 ||
+ !WriteStatusFailure(argv[1],
+ SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS))
+ {
+ LOG_WARN(("Could not write update.status service update failure. (%d)",
+ GetLastError()));
+ }
+ return FALSE;
+ }
+
+ WCHAR installDir[MAX_PATH + 1] = {L'\0'};
+ if (!GetInstallationDir(argc, argv, installDir))
+ {
+ LOG_WARN(("Could not get the installation directory"));
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_INSTALLDIR_ERROR))
+ {
+ LOG_WARN(("Could not write update.status for GetInstallationDir failure."));
+ }
+ return FALSE;
+ }
+
+ // Make sure the path to the updater to use for the update is local.
+ // We do this check to make sure that file locking is available for
+ // race condition security checks.
+ BOOL isLocal = FALSE;
+ if (!IsLocalFile(argv[0], isLocal) || !isLocal)
+ {
+ LOG_WARN(("Filesystem in path %ls is not supported (%d)",
+ argv[0], GetLastError()));
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_UPDATER_NOT_FIXED_DRIVE))
+ {
+ LOG_WARN(("Could not write update.status service update failure. (%d)",
+ GetLastError()));
+ }
+ return FALSE;
+ }
+
+ AutoHandle noWriteLock(CreateFileW(argv[0], GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr));
- if (noWriteLock == INVALID_HANDLE_VALUE) {
- LOG_WARN(("Could not set no write sharing access on file. (%d)",
- GetLastError()));
- if (!WriteStatusFailure(argv[1],
- SERVICE_COULD_NOT_LOCK_UPDATER)) {
- LOG_WARN(("Could not write update.status service update failure. (%d)",
- GetLastError()));
- }
- return FALSE;
- }
-
- // Verify that the updater.exe that we are executing is the same
- // as the one in the installation directory which we are updating.
- // The installation dir that we are installing to is installDir.
- WCHAR installDirUpdater[MAX_PATH + 1] = { L'\0' };
- wcsncpy(installDirUpdater, installDir, MAX_PATH);
- if (!PathAppendSafe(installDirUpdater, L"updater.exe")) {
- LOG_WARN(("Install directory updater could not be determined."));
- result = FALSE;
- }
-
- BOOL updaterIsCorrect = FALSE;
- if (result && !VerifySameFiles(argv[0], installDirUpdater,
- updaterIsCorrect)) {
- LOG_WARN(("Error checking if the updaters are the same.\n"
- "Path 1: %ls\nPath 2: %ls", argv[0], installDirUpdater));
- result = FALSE;
- }
-
- if (result && !updaterIsCorrect) {
- LOG_WARN(("The updaters do not match, updater will not run.\n"
- "Path 1: %ls\nPath 2: %ls", argv[0], installDirUpdater));
- result = FALSE;
- }
-
- if (result) {
- LOG(("updater.exe was compared successfully to the installation directory"
- " updater.exe."));
- } else {
- if (!WriteStatusFailure(argv[1],
- SERVICE_UPDATER_COMPARE_ERROR)) {
- LOG_WARN(("Could not write update.status updater compare failure."));
- }
- return FALSE;
- }
-
- // Check to make sure the updater.exe module has the unique updater identity.
- // This is a security measure to make sure that the signed executable that
- // we will run is actually an updater.
- HMODULE updaterModule = LoadLibraryEx(argv[0], nullptr,
- LOAD_LIBRARY_AS_DATAFILE);
- if (!updaterModule) {
- LOG_WARN(("updater.exe module could not be loaded. (%d)", GetLastError()));
- result = FALSE;
- } else {
- char updaterIdentity[64];
- if (!LoadStringA(updaterModule, IDS_UPDATER_IDENTITY,
- updaterIdentity, sizeof(updaterIdentity))) {
- LOG_WARN(("The updater.exe application does not contain the Mozilla"
- " updater identity."));
- result = FALSE;
- }
-
- if (strcmp(updaterIdentity, UPDATER_IDENTITY_STRING)) {
- LOG_WARN(("The updater.exe identity string is not valid."));
- result = FALSE;
- }
- FreeLibrary(updaterModule);
- }
-
- if (result) {
- LOG(("The updater.exe application contains the Mozilla"
- " updater identity."));
- } else {
- if (!WriteStatusFailure(argv[1],
- SERVICE_UPDATER_IDENTITY_ERROR)) {
- LOG_WARN(("Could not write update.status no updater identity."));
+ if (noWriteLock == INVALID_HANDLE_VALUE)
+ {
+ LOG_WARN(("Could not set no write sharing access on file. (%d)",
+ GetLastError()));
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_COULD_NOT_LOCK_UPDATER))
+ {
+ LOG_WARN(("Could not write update.status service update failure. (%d)",
+ GetLastError()));
+ }
+ return FALSE;
}
- return TRUE;
- }
- // Check for updater.exe sign problems
- BOOL updaterSignProblem = FALSE;
-#ifndef DISABLE_UPDATER_AUTHENTICODE_CHECK
- updaterSignProblem = !DoesBinaryMatchAllowedCertificates(installDir,
- argv[0]);
-#endif
+ // Verify that the updater.exe that we are executing is the same
+ // as the one in the installation directory which we are updating.
+ // The installation dir that we are installing to is installDir.
+ WCHAR installDirUpdater[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(installDirUpdater, installDir, MAX_PATH);
+ if (!PathAppendSafe(installDirUpdater, L"updater.exe"))
+ {
+ LOG_WARN(("Install directory updater could not be determined."));
+ result = FALSE;
+ }
+
+ BOOL updaterIsCorrect = FALSE;
+ if (result && !VerifySameFiles(argv[0], installDirUpdater,
+ updaterIsCorrect))
+ {
+ LOG_WARN(("Error checking if the updaters are the same.\n"
+ "Path 1: %ls\nPath 2: %ls", argv[0], installDirUpdater));
+ result = FALSE;
+ }
+
+ if (result && !updaterIsCorrect)
+ {
+ LOG_WARN(("The updaters do not match, updater will not run.\n"
+ "Path 1: %ls\nPath 2: %ls", argv[0], installDirUpdater));
+ result = FALSE;
+ }
- // Only proceed with the update if we have no signing problems
- if (!updaterSignProblem) {
- BOOL updateProcessWasStarted = FALSE;
- if (StartUpdateProcess(argc, argv, installDir,
- updateProcessWasStarted)) {
- LOG(("updater.exe was launched and run successfully!"));
- LogFlush();
-
- // Don't attempt to update the service when the update is being staged.
- if (!IsUpdateBeingStaged(argc, argv)) {
- // We might not execute code after StartServiceUpdate because
- // the service installer will stop the service if it is running.
- StartServiceUpdate(installDir);
- }
- } else {
- result = FALSE;
- LOG_WARN(("Error running update process. Updating update.status (%d)",
- GetLastError()));
- LogFlush();
-
- // If the update process was started, then updater.exe is responsible for
- // setting the failure code. If it could not be started then we do the
- // work. We set an error instead of directly setting status pending
- // so that the app.update.service.errors pref can be updated when
- // the callback app restarts.
- if (!updateProcessWasStarted) {
+ if (result)
+ {
+ LOG(("updater.exe was compared successfully to the installation directory"
+ " updater.exe."));
+ }
+ else
+ {
if (!WriteStatusFailure(argv[1],
- SERVICE_UPDATER_COULD_NOT_BE_STARTED)) {
- LOG_WARN(("Could not write update.status service update failure. (%d)",
- GetLastError()));
+ SERVICE_UPDATER_COMPARE_ERROR))
+ {
+ LOG_WARN(("Could not write update.status updater compare failure."));
+ }
+ return FALSE;
+ }
+
+ // Check to make sure the updater.exe module has the unique updater identity.
+ // This is a security measure to make sure that the signed executable that
+ // we will run is actually an updater.
+ HMODULE updaterModule = LoadLibraryEx(argv[0], nullptr,
+ LOAD_LIBRARY_AS_DATAFILE);
+ if (!updaterModule)
+ {
+ LOG_WARN(("updater.exe module could not be loaded. (%d)", GetLastError()));
+ result = FALSE;
+ }
+ else
+ {
+ char updaterIdentity[64];
+ if (!LoadStringA(updaterModule, IDS_UPDATER_IDENTITY,
+ updaterIdentity, sizeof(updaterIdentity)))
+ {
+ LOG_WARN(("The updater.exe application does not contain the Mozilla"
+ " updater identity."));
+ result = FALSE;
+ }
+
+ if (strcmp(updaterIdentity, UPDATER_IDENTITY_STRING))
+ {
+ LOG_WARN(("The updater.exe identity string is not valid."));
+ result = FALSE;
}
- }
+ FreeLibrary(updaterModule);
}
- } else {
- result = FALSE;
- LOG_WARN(("Could not start process due to certificate check error on "
- "updater.exe. Updating update.status. (%d)", GetLastError()));
- // When there is a certificate check error on the updater.exe application,
- // we want to write out the error.
- if (!WriteStatusFailure(argv[1],
- SERVICE_UPDATER_SIGN_ERROR)) {
- LOG_WARN(("Could not write pending state to update.status. (%d)",
- GetLastError()));
+ if (result)
+ {
+ LOG(("The updater.exe application contains the Mozilla"
+ " updater identity."));
+ }
+ else
+ {
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_UPDATER_IDENTITY_ERROR))
+ {
+ LOG_WARN(("Could not write update.status no updater identity."));
+ }
+ return TRUE;
+ }
+
+ // Check for updater.exe sign problems
+ BOOL updaterSignProblem = FALSE;
+#ifndef DISABLE_UPDATER_AUTHENTICODE_CHECK
+ updaterSignProblem = !DoesBinaryMatchAllowedCertificates(installDir,
+ argv[0]);
+#endif
+
+ // Only proceed with the update if we have no signing problems
+ if (!updaterSignProblem)
+ {
+ BOOL updateProcessWasStarted = FALSE;
+ if (StartUpdateProcess(argc, argv, installDir,
+ updateProcessWasStarted))
+ {
+ LOG(("updater.exe was launched and run successfully!"));
+ LogFlush();
+
+ // Don't attempt to update the service when the update is being staged.
+ if (!IsUpdateBeingStaged(argc, argv))
+ {
+ // We might not execute code after StartServiceUpdate because
+ // the service installer will stop the service if it is running.
+ StartServiceUpdate(installDir);
+ }
+ }
+ else
+ {
+ result = FALSE;
+ LOG_WARN(("Error running update process. Updating update.status (%d)",
+ GetLastError()));
+ LogFlush();
+
+ // If the update process was started, then updater.exe is responsible for
+ // setting the failure code. If it could not be started then we do the
+ // work. We set an error instead of directly setting status pending
+ // so that the app.update.service.errors pref can be updated when
+ // the callback app restarts.
+ if (!updateProcessWasStarted)
+ {
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_UPDATER_COULD_NOT_BE_STARTED))
+ {
+ LOG_WARN(("Could not write update.status service update failure. (%d)",
+ GetLastError()));
+ }
+ }
+ }
+ }
+ else
+ {
+ result = FALSE;
+ LOG_WARN(("Could not start process due to certificate check error on "
+ "updater.exe. Updating update.status. (%d)", GetLastError()));
+
+ // When there is a certificate check error on the updater.exe application,
+ // we want to write out the error.
+ if (!WriteStatusFailure(argv[1],
+ SERVICE_UPDATER_SIGN_ERROR))
+ {
+ LOG_WARN(("Could not write pending state to update.status. (%d)",
+ GetLastError()));
+ }
}
- }
- return result;
+ return result;
}
/**
@@ -530,33 +596,37 @@ ProcessSoftwareUpdateCommand(DWORD argc, LPWSTR *argv)
BOOL
GetSecureUpdaterPath(WCHAR serviceUpdaterPath[MAX_PATH + 1])
{
- if (!GetModuleFileNameW(nullptr, serviceUpdaterPath, MAX_PATH)) {
- LOG_WARN(("Could not obtain module filename when attempting to "
- "use a secure updater path. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (!PathRemoveFileSpecW(serviceUpdaterPath)) {
- LOG_WARN(("Couldn't remove file spec when attempting to use a secure "
- "updater path. (%d)", GetLastError()));
- return FALSE;
- }
-
- if (!PathAppendSafe(serviceUpdaterPath, L"update")) {
- LOG_WARN(("Couldn't append file spec when attempting to use a secure "
- "updater path. (%d)", GetLastError()));
- return FALSE;
- }
-
- CreateDirectoryW(serviceUpdaterPath, nullptr);
-
- if (!PathAppendSafe(serviceUpdaterPath, L"updater.exe")) {
- LOG_WARN(("Couldn't append file spec when attempting to use a secure "
- "updater path. (%d)", GetLastError()));
- return FALSE;
- }
-
- return TRUE;
+ if (!GetModuleFileNameW(nullptr, serviceUpdaterPath, MAX_PATH))
+ {
+ LOG_WARN(("Could not obtain module filename when attempting to "
+ "use a secure updater path. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (!PathRemoveFileSpecW(serviceUpdaterPath))
+ {
+ LOG_WARN(("Couldn't remove file spec when attempting to use a secure "
+ "updater path. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ if (!PathAppendSafe(serviceUpdaterPath, L"update"))
+ {
+ LOG_WARN(("Couldn't append file spec when attempting to use a secure "
+ "updater path. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ CreateDirectoryW(serviceUpdaterPath, nullptr);
+
+ if (!PathAppendSafe(serviceUpdaterPath, L"updater.exe"))
+ {
+ LOG_WARN(("Couldn't append file spec when attempting to use a secure "
+ "updater path. (%d)", GetLastError()));
+ return FALSE;
+ }
+
+ return TRUE;
}
/**
@@ -568,27 +638,31 @@ GetSecureUpdaterPath(WCHAR serviceUpdaterPath[MAX_PATH + 1])
BOOL
DeleteSecureUpdater(WCHAR serviceUpdaterPath[MAX_PATH + 1])
{
- BOOL result = FALSE;
- if (serviceUpdaterPath[0]) {
- result = DeleteFileW(serviceUpdaterPath);
- if (!result && GetLastError() != ERROR_PATH_NOT_FOUND &&
- GetLastError() != ERROR_FILE_NOT_FOUND) {
- LOG_WARN(("Could not delete service updater path: '%ls'.",
- serviceUpdaterPath));
- }
-
- WCHAR updaterINIPath[MAX_PATH + 1] = { L'\0' };
- if (PathGetSiblingFilePath(updaterINIPath, serviceUpdaterPath,
- L"updater.ini")) {
- result = DeleteFileW(updaterINIPath);
- if (!result && GetLastError() != ERROR_PATH_NOT_FOUND &&
- GetLastError() != ERROR_FILE_NOT_FOUND) {
- LOG_WARN(("Could not delete service updater INI path: '%ls'.",
- updaterINIPath));
- }
- }
- }
- return result;
+ BOOL result = FALSE;
+ if (serviceUpdaterPath[0])
+ {
+ result = DeleteFileW(serviceUpdaterPath);
+ if (!result && GetLastError() != ERROR_PATH_NOT_FOUND &&
+ GetLastError() != ERROR_FILE_NOT_FOUND)
+ {
+ LOG_WARN(("Could not delete service updater path: '%ls'.",
+ serviceUpdaterPath));
+ }
+
+ WCHAR updaterINIPath[MAX_PATH + 1] = { L'\0' };
+ if (PathGetSiblingFilePath(updaterINIPath, serviceUpdaterPath,
+ L"updater.ini"))
+ {
+ result = DeleteFileW(updaterINIPath);
+ if (!result && GetLastError() != ERROR_PATH_NOT_FOUND &&
+ GetLastError() != ERROR_FILE_NOT_FOUND)
+ {
+ LOG_WARN(("Could not delete service updater INI path: '%ls'.",
+ updaterINIPath));
+ }
+ }
+ }
+ return result;
}
/**
@@ -604,81 +678,93 @@ DeleteSecureUpdater(WCHAR serviceUpdaterPath[MAX_PATH + 1])
BOOL
ExecuteServiceCommand(int argc, LPWSTR *argv)
{
- if (argc < 3) {
- LOG_WARN(("Not enough command line arguments to execute a service command"));
- return FALSE;
- }
-
- // The tests work by making sure the log has changed, so we put a
- // unique ID in the log.
- RPC_WSTR guidString = RPC_WSTR(L"");
- GUID guid;
- HRESULT hr = CoCreateGuid(&guid);
- if (SUCCEEDED(hr)) {
- UuidToString(&guid, &guidString);
- }
- LOG(("Executing service command %ls, ID: %ls",
- argv[2], reinterpret_cast<LPCWSTR>(guidString)));
- RpcStringFree(&guidString);
-
- BOOL result = FALSE;
- if (!lstrcmpi(argv[2], L"software-update")) {
-
- // Use the passed in command line arguments for the update, except for the
- // path to updater.exe. We copy updater.exe to a the directory of the
- // MozillaMaintenance service so that a low integrity process cannot
- // replace the updater.exe at any point and use that for the update.
- // It also makes DLL injection attacks harder.
- LPWSTR oldUpdaterPath = argv[3];
- WCHAR secureUpdaterPath[MAX_PATH + 1] = { L'\0' };
- result = GetSecureUpdaterPath(secureUpdaterPath); // Does its own logging
- if (result) {
- LOG(("Passed in path: '%ls'; Using this path for updating: '%ls'.",
- oldUpdaterPath, secureUpdaterPath));
- DeleteSecureUpdater(secureUpdaterPath);
- result = CopyFileW(oldUpdaterPath, secureUpdaterPath, FALSE);
- }
-
- if (!result) {
- LOG_WARN(("Could not copy path to secure location. (%d)",
- GetLastError()));
- if (argc > 4 && !WriteStatusFailure(argv[4],
- SERVICE_COULD_NOT_COPY_UPDATER)) {
- LOG_WARN(("Could not write update.status could not copy updater error"));
- }
- } else {
-
- // We obtained the path and copied it successfully, update the path to
- // use for the service update.
- argv[3] = secureUpdaterPath;
-
- WCHAR oldUpdaterINIPath[MAX_PATH + 1] = { L'\0' };
- WCHAR secureUpdaterINIPath[MAX_PATH + 1] = { L'\0' };
- if (PathGetSiblingFilePath(secureUpdaterINIPath, secureUpdaterPath,
- L"updater.ini") &&
- PathGetSiblingFilePath(oldUpdaterINIPath, oldUpdaterPath,
- L"updater.ini")) {
- // This is non fatal if it fails there is no real harm
- if (!CopyFileW(oldUpdaterINIPath, secureUpdaterINIPath, FALSE)) {
- LOG_WARN(("Could not copy updater.ini from: '%ls' to '%ls'. (%d)",
- oldUpdaterINIPath, secureUpdaterINIPath, GetLastError()));
- }
- }
+ if (argc < 3)
+ {
+ LOG_WARN(("Not enough command line arguments to execute a service command"));
+ return FALSE;
+ }
- result = ProcessSoftwareUpdateCommand(argc - 3, argv + 3);
- DeleteSecureUpdater(secureUpdaterPath);
+ // The tests work by making sure the log has changed, so we put a
+ // unique ID in the log.
+ RPC_WSTR guidString = RPC_WSTR(L"");
+ GUID guid;
+ HRESULT hr = CoCreateGuid(&guid);
+ if (SUCCEEDED(hr))
+ {
+ UuidToString(&guid, &guidString);
}
+ LOG(("Executing service command %ls, ID: %ls",
+ argv[2], reinterpret_cast<LPCWSTR>(guidString)));
+ RpcStringFree(&guidString);
+
+ BOOL result = FALSE;
+ if (!lstrcmpi(argv[2], L"software-update"))
+ {
+
+ // Use the passed in command line arguments for the update, except for the
+ // path to updater.exe. We copy updater.exe to a the directory of the
+ // MozillaMaintenance service so that a low integrity process cannot
+ // replace the updater.exe at any point and use that for the update.
+ // It also makes DLL injection attacks harder.
+ LPWSTR oldUpdaterPath = argv[3];
+ WCHAR secureUpdaterPath[MAX_PATH + 1] = { L'\0' };
+ result = GetSecureUpdaterPath(secureUpdaterPath); // Does its own logging
+ if (result)
+ {
+ LOG(("Passed in path: '%ls'; Using this path for updating: '%ls'.",
+ oldUpdaterPath, secureUpdaterPath));
+ DeleteSecureUpdater(secureUpdaterPath);
+ result = CopyFileW(oldUpdaterPath, secureUpdaterPath, FALSE);
+ }
- // We might not reach here if the service install succeeded
- // because the service self updates itself and the service
- // installer will stop the service.
- LOG(("Service command %ls complete.", argv[2]));
- } else {
- LOG_WARN(("Service command not recognized: %ls.", argv[2]));
- // result is already set to FALSE
- }
+ if (!result)
+ {
+ LOG_WARN(("Could not copy path to secure location. (%d)",
+ GetLastError()));
+ if (argc > 4 && !WriteStatusFailure(argv[4],
+ SERVICE_COULD_NOT_COPY_UPDATER))
+ {
+ LOG_WARN(("Could not write update.status could not copy updater error"));
+ }
+ }
+ else
+ {
+
+ // We obtained the path and copied it successfully, update the path to
+ // use for the service update.
+ argv[3] = secureUpdaterPath;
+
+ WCHAR oldUpdaterINIPath[MAX_PATH + 1] = { L'\0' };
+ WCHAR secureUpdaterINIPath[MAX_PATH + 1] = { L'\0' };
+ if (PathGetSiblingFilePath(secureUpdaterINIPath, secureUpdaterPath,
+ L"updater.ini") &&
+ PathGetSiblingFilePath(oldUpdaterINIPath, oldUpdaterPath,
+ L"updater.ini"))
+ {
+ // This is non fatal if it fails there is no real harm
+ if (!CopyFileW(oldUpdaterINIPath, secureUpdaterINIPath, FALSE))
+ {
+ LOG_WARN(("Could not copy updater.ini from: '%ls' to '%ls'. (%d)",
+ oldUpdaterINIPath, secureUpdaterINIPath, GetLastError()));
+ }
+ }
+
+ result = ProcessSoftwareUpdateCommand(argc - 3, argv + 3);
+ DeleteSecureUpdater(secureUpdaterPath);
+ }
- LOG(("service command %ls complete with result: %ls.",
- argv[1], (result ? L"Success" : L"Failure")));
- return TRUE;
+ // We might not reach here if the service install succeeded
+ // because the service self updates itself and the service
+ // installer will stop the service.
+ LOG(("Service command %ls complete.", argv[2]));
+ }
+ else
+ {
+ LOG_WARN(("Service command not recognized: %ls.", argv[2]));
+ // result is already set to FALSE
+ }
+
+ LOG(("service command %ls complete with result: %ls.",
+ argv[1], (result ? L"Success" : L"Failure")));
+ return TRUE;
}
diff --git a/onlineupdate/source/update/common/pathhash.cxx b/onlineupdate/source/update/common/pathhash.cxx
index 3c3c1f5d31f0..67e53fa35bea 100644
--- a/onlineupdate/source/update/common/pathhash.cxx
+++ b/onlineupdate/source/update/common/pathhash.cxx
@@ -20,11 +20,12 @@ static void
BinaryDataToHexString(const BYTE *hash, DWORD &hashSize,
LPWSTR hexString)
{
- WCHAR *p = hexString;
- for (DWORD i = 0; i < hashSize; ++i) {
- wsprintfW(p, L"%.2x", hash[i]);
- p += 2;
- }
+ WCHAR *p = hexString;
+ for (DWORD i = 0; i < hashSize; ++i)
+ {
+ wsprintfW(p, L"%.2x", hash[i]);
+ p += 2;
+ }
}
/**
@@ -40,52 +41,61 @@ static BOOL
CalculateMD5(const char *data, DWORD dataSize,
BYTE **hash, DWORD &hashSize)
{
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
+ HCRYPTPROV hProv = 0;
+ HCRYPTHASH hHash = 0;
- if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- if (NTE_BAD_KEYSET != GetLastError()) {
- return FALSE;
+ if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT))
+ {
+ if (NTE_BAD_KEYSET != GetLastError())
+ {
+ return FALSE;
+ }
+
+ // Maybe it doesn't exist, try to create it.
+ if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET))
+ {
+ return FALSE;
+ }
}
- // Maybe it doesn't exist, try to create it.
- if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) {
- return FALSE;
+ if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
+ {
+ return FALSE;
+ }
+
+ if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(data),
+ dataSize, 0))
+ {
+ return FALSE;
+ }
+
+ DWORD dwCount = sizeof(DWORD);
+ if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize,
+ &dwCount, 0))
+ {
+ return FALSE;
+ }
+
+ *hash = new BYTE[hashSize];
+ ZeroMemory(*hash, hashSize);
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, *hash, &hashSize, 0))
+ {
+ return FALSE;
+ }
+
+ if (hHash)
+ {
+ CryptDestroyHash(hHash);
+ }
+
+ if (hProv)
+ {
+ CryptReleaseContext(hProv,0);
}
- }
-
- if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
- return FALSE;
- }
-
- if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(data),
- dataSize, 0)) {
- return FALSE;
- }
-
- DWORD dwCount = sizeof(DWORD);
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize,
- &dwCount, 0)) {
- return FALSE;
- }
-
- *hash = new BYTE[hashSize];
- ZeroMemory(*hash, hashSize);
- if (!CryptGetHashParam(hHash, HP_HASHVAL, *hash, &hashSize, 0)) {
- return FALSE;
- }
-
- if (hHash) {
- CryptDestroyHash(hHash);
- }
-
- if (hProv) {
- CryptReleaseContext(hProv,0);
- }
-
- return TRUE;
+
+ return TRUE;
}
/**
@@ -100,41 +110,44 @@ BOOL
CalculateRegistryPathFromFilePath(const LPCWSTR filePath,
LPWSTR registryPath)
{
- size_t filePathLen = wcslen(filePath);
- if (!filePathLen) {
- return FALSE;
- }
-
- // If the file path ends in a slash, ignore that character
- if (filePath[filePathLen -1] == L'\\' ||
- filePath[filePathLen - 1] == L'/') {
- filePathLen--;
- }
-
- // Copy in the full path into our own buffer.
- // Copying in the extra slash is OK because we calculate the hash
- // based on the filePathLen which excludes the slash.
- // +2 to account for the possibly trailing slash and the null terminator.
- WCHAR *lowercasePath = new WCHAR[filePathLen + 2];
- memset(lowercasePath, 0, (filePathLen + 2) * sizeof(WCHAR));
- wcsncpy(lowercasePath, filePath, filePathLen + 1);
- _wcslwr(lowercasePath);
-
- BYTE *hash;
- DWORD hashSize = 0;
- if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath),
- filePathLen * 2,
- &hash, hashSize)) {
+ size_t filePathLen = wcslen(filePath);
+ if (!filePathLen)
+ {
+ return FALSE;
+ }
+
+ // If the file path ends in a slash, ignore that character
+ if (filePath[filePathLen -1] == L'\\' ||
+ filePath[filePathLen - 1] == L'/')
+ {
+ filePathLen--;
+ }
+
+ // Copy in the full path into our own buffer.
+ // Copying in the extra slash is OK because we calculate the hash
+ // based on the filePathLen which excludes the slash.
+ // +2 to account for the possibly trailing slash and the null terminator.
+ WCHAR *lowercasePath = new WCHAR[filePathLen + 2];
+ memset(lowercasePath, 0, (filePathLen + 2) * sizeof(WCHAR));
+ wcsncpy(lowercasePath, filePath, filePathLen + 1);
+ _wcslwr(lowercasePath);
+
+ BYTE *hash;
+ DWORD hashSize = 0;
+ if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath),
+ filePathLen * 2,
+ &hash, hashSize))
+ {
+ delete[] lowercasePath;
+ return FALSE;
+ }
delete[] lowercasePath;
- return FALSE;
- }
- delete[] lowercasePath;
-
- LPCWSTR baseRegPath = L"SOFTWARE\\LibreOffice\\MaintenanceService\\";
- wcsncpy(registryPath, baseRegPath, MAX_PATH);
- BinaryDataToHexString(hash, hashSize,
- registryPath + wcslen(baseRegPath));
- delete[] hash;
- return TRUE;
+
+ LPCWSTR baseRegPath = L"SOFTWARE\\LibreOffice\\MaintenanceService\\";
+ wcsncpy(registryPath, baseRegPath, MAX_PATH);
+ BinaryDataToHexString(hash, hashSize,
+ registryPath + wcslen(baseRegPath));
+ delete[] hash;
+ return TRUE;
}
#endif
diff --git a/onlineupdate/source/update/common/readstrings.cxx b/onlineupdate/source/update/common/readstrings.cxx
index d2792117773e..e1366cdddaed 100644
--- a/onlineupdate/source/update/common/readstrings.cxx
+++ b/onlineupdate/source/update/common/readstrings.cxx
@@ -19,22 +19,39 @@
#endif
// stack based FILE wrapper to ensure that fclose is called.
-class AutoFILE {
+class AutoFILE
+{
public:
- explicit AutoFILE(FILE *fp) : fp_(fp) {}
- ~AutoFILE() { if (fp_) fclose(fp_); }
- operator FILE *() { return fp_; }
+ explicit AutoFILE(FILE *fp) : fp_(fp) {}
+ ~AutoFILE()
+ {
+ if (fp_) fclose(fp_);
+ }
+ operator FILE *()
+ {
+ return fp_;
+ }
private:
- FILE *fp_;
+ FILE *fp_;
};
-class AutoCharArray {
+class AutoCharArray
+{
public:
- explicit AutoCharArray(size_t len) { ptr_ = new char[len]; }
- ~AutoCharArray() { delete[] ptr_; }
- operator char *() { return ptr_; }
+ explicit AutoCharArray(size_t len)
+ {
+ ptr_ = new char[len];
+ }
+ ~AutoCharArray()
+ {
+ delete[] ptr_;
+ }
+ operator char *()
+ {
+ return ptr_;
+ }
private:
- char *ptr_;
+ char *ptr_;
};
static const char kNL[] = "\r\n";
@@ -45,46 +62,55 @@ static const char kRBracket[] = "]";
static const char*
NS_strspnp(const char *delims, const char *str)
{
- const char *d;
- do {
- for (d = delims; *d != '\0'; ++d) {
- if (*str == *d) {
- ++str;
- break;
- }
+ const char *d;
+ do
+ {
+ for (d = delims; *d != '\0'; ++d)
+ {
+ if (*str == *d)
+ {
+ ++str;
+ break;
+ }
+ }
}
- } while (*d);
+ while (*d);
- return str;
+ return str;
}
static char*
NS_strtok(const char *delims, char **str)
{
- if (!*str)
- return nullptr;
-
- char *ret = (char*) NS_strspnp(delims, *str);
-
- if (!*ret) {
- *str = ret;
- return nullptr;
- }
-
- char *i = ret;
- do {
- for (const char *d = delims; *d != '\0'; ++d) {
- if (*i == *d) {
- *i = '\0';
- *str = ++i;
- return ret;
- }
+ if (!*str)
+ return nullptr;
+
+ char *ret = (char*) NS_strspnp(delims, *str);
+
+ if (!*ret)
+ {
+ *str = ret;
+ return nullptr;
}
- ++i;
- } while (*i);
- *str = nullptr;
- return ret;
+ char *i = ret;
+ do
+ {
+ for (const char *d = delims; *d != '\0'; ++d)
+ {
+ if (*i == *d)
+ {
+ *i = '\0';
+ *str = ++i;
+ return ret;
+ }
+ }
+ ++i;
+ }
+ while (*i);
+
+ *str = nullptr;
+ return ret;
}
/**
@@ -94,22 +120,22 @@ NS_strtok(const char *delims, char **str)
static int
find_key(const char *keyList, char* key)
{
- if (!keyList)
- return -1;
+ if (!keyList)
+ return -1;
- int index = 0;
- const char *p = keyList;
- while (*p)
- {
- if (strcmp(key, p) == 0)
- return index;
+ int index = 0;
+ const char *p = keyList;
+ while (*p)
+ {
+ if (strcmp(key, p) == 0)
+ return index;
- p += strlen(p) + 1;
- index++;
- }
+ p += strlen(p) + 1;
+ index++;
+ }
- // The key was not found if we came here
- return -1;
+ // The key was not found if we came here
+ return -1;
}
/**
@@ -129,91 +155,96 @@ ReadStrings(const NS_tchar *path,
char results[][MAX_TEXT_LEN],
const char *section)
{
- AutoFILE fp(NS_tfopen(path, OPEN_MODE));
-
- if (!fp)
- return READ_ERROR;
-
- /* get file size */
- if (fseek(fp, 0, SEEK_END) != 0)
- return READ_ERROR;
-
- long len = ftell(fp);
- if (len <= 0)
- return READ_ERROR;
-
- size_t flen = size_t(len);
- AutoCharArray fileContents(flen + 1);
- if (!fileContents)
- return READ_STRINGS_MEM_ERROR;
-
- /* read the file in one swoop */
- if (fseek(fp, 0, SEEK_SET) != 0)
- return READ_ERROR;
-
- size_t rd = fread(fileContents, sizeof(char), flen, fp);
- if (rd != flen)
- return READ_ERROR;
-
- fileContents[flen] = '\0';
-
- char *buffer = fileContents;
- bool inStringsSection = false;
-
- unsigned int read = 0;
-
- while (char *token = NS_strtok(kNL, &buffer)) {
- if (token[0] == '#' || token[0] == ';') // it's a comment
- continue;
-
- token = (char*) NS_strspnp(kWhitespace, token);
- if (!*token) // empty line
- continue;
-
- if (token[0] == '[') { // section header!
- ++token;
- char const * currSection = token;
-
- char *rb = NS_strtok(kRBracket, &token);
- if (!rb || NS_strtok(kWhitespace, &token)) {
- // there's either an unclosed [Section or a [Section]Moretext!
- // we could frankly decide that this INI file is malformed right
- // here and stop, but we won't... keep going, looking for
- // a well-formed [section] to continue working with
- inStringsSection = false;
- }
- else {
- if (section)
- inStringsSection = strcmp(currSection, section) == 0;
- else
- inStringsSection = strcmp(currSection, "Strings") == 0;
- }
-
- continue;
- }
+ AutoFILE fp(NS_tfopen(path, OPEN_MODE));
- if (!inStringsSection) {
- // If we haven't found a section header (or we found a malformed
- // section header), or this isn't the [Strings] section don't bother
- // parsing this line.
- continue;
- }
+ if (!fp)
+ return READ_ERROR;
+
+ /* get file size */
+ if (fseek(fp, 0, SEEK_END) != 0)
+ return READ_ERROR;
+
+ long len = ftell(fp);
+ if (len <= 0)
+ return READ_ERROR;
+
+ size_t flen = size_t(len);
+ AutoCharArray fileContents(flen + 1);
+ if (!fileContents)
+ return READ_STRINGS_MEM_ERROR;
+
+ /* read the file in one swoop */
+ if (fseek(fp, 0, SEEK_SET) != 0)
+ return READ_ERROR;
+
+ size_t rd = fread(fileContents, sizeof(char), flen, fp);
+ if (rd != flen)
+ return READ_ERROR;
+
+ fileContents[flen] = '\0';
+
+ char *buffer = fileContents;
+ bool inStringsSection = false;
- char *key = token;
- char *e = NS_strtok(kEquals, &token);
- if (!e)
- continue;
+ unsigned int read = 0;
- int keyIndex = find_key(keyList, key);
- if (keyIndex >= 0 && (unsigned int)keyIndex < numStrings)
+ while (char *token = NS_strtok(kNL, &buffer))
{
- strncpy(results[keyIndex], token, MAX_TEXT_LEN - 1);
- results[keyIndex][MAX_TEXT_LEN - 1] = '\0';
- read++;
+ if (token[0] == '#' || token[0] == ';') // it's a comment
+ continue;
+
+ token = (char*) NS_strspnp(kWhitespace, token);
+ if (!*token) // empty line
+ continue;
+
+ if (token[0] == '[') // section header!
+ {
+ ++token;
+ char const * currSection = token;
+
+ char *rb = NS_strtok(kRBracket, &token);
+ if (!rb || NS_strtok(kWhitespace, &token))
+ {
+ // there's either an unclosed [Section or a [Section]Moretext!
+ // we could frankly decide that this INI file is malformed right
+ // here and stop, but we won't... keep going, looking for
+ // a well-formed [section] to continue working with
+ inStringsSection = false;
+ }
+ else
+ {
+ if (section)
+ inStringsSection = strcmp(currSection, section) == 0;
+ else
+ inStringsSection = strcmp(currSection, "Strings") == 0;
+ }
+
+ continue;
+ }
+
+ if (!inStringsSection)
+ {
+ // If we haven't found a section header (or we found a malformed
+ // section header), or this isn't the [Strings] section don't bother
+ // parsing this line.
+ continue;
+ }
+
+ char *key = token;
+ char *e = NS_strtok(kEquals, &token);
+ if (!e)
+ continue;
+
+ int keyIndex = find_key(keyList, key);
+ if (keyIndex >= 0 && (unsigned int)keyIndex < numStrings)
+ {
+ strncpy(results[keyIndex], token, MAX_TEXT_LEN - 1);
+ results[keyIndex][MAX_TEXT_LEN - 1] = '\0';
+ read++;
+ }
}
- }
- return (read == numStrings) ? OK : PARSE_ERROR;
+ return (read == numStrings) ? OK : PARSE_ERROR;
}
// A wrapper function to read strings for the updater.
@@ -221,16 +252,16 @@ ReadStrings(const NS_tchar *path,
int
ReadStrings(const NS_tchar *path, StringTable *results)
{
- const unsigned int kNumStrings = 2;
- const char *kUpdaterKeys = "Title\0Info\0";
- char updater_strings[kNumStrings][MAX_TEXT_LEN];
+ const unsigned int kNumStrings = 2;
+ const char *kUpdaterKeys = "Title\0Info\0";
+ char updater_strings[kNumStrings][MAX_TEXT_LEN];
- int result = ReadStrings(path, kUpdaterKeys, kNumStrings, updater_strings);
+ int result = ReadStrings(path, kUpdaterKeys, kNumStrings, updater_strings);
- strncpy(results->title, updater_strings[0], MAX_TEXT_LEN - 1);
- results->title[MAX_TEXT_LEN - 1] = '\0';
- strncpy(results->info, updater_strings[1], MAX_TEXT_LEN - 1);
- results->info[MAX_TEXT_LEN - 1] = '\0';
+ strncpy(results->title, updater_strings[0], MAX_TEXT_LEN - 1);
+ results->title[MAX_TEXT_LEN - 1] = '\0';
+ strncpy(results->info, updater_strings[1], MAX_TEXT_LEN - 1);
+ results->info[MAX_TEXT_LEN - 1] = '\0';
- return result;
+ return result;
}
diff --git a/onlineupdate/source/update/common/readstrings.h b/onlineupdate/source/update/common/readstrings.h
index 47a9c171756d..bc837ef326b5 100644
--- a/onlineupdate/source/update/common/readstrings.h
+++ b/onlineupdate/source/update/common/readstrings.h
@@ -11,9 +11,9 @@
#ifdef _WIN32
# include <windows.h>
- typedef WCHAR NS_tchar;
+typedef WCHAR NS_tchar;
#else
- typedef char NS_tchar;
+typedef char NS_tchar;
#endif
#ifndef NULL
@@ -22,8 +22,8 @@
struct StringTable
{
- char title[MAX_TEXT_LEN];
- char info[MAX_TEXT_LEN];
+ char title[MAX_TEXT_LEN];
+ char info[MAX_TEXT_LEN];
};
/**
diff --git a/onlineupdate/source/update/common/uachelper.cxx b/onlineupdate/source/update/common/uachelper.cxx
index 4cae3ad4e5fc..831b12680719 100644
--- a/onlineupdate/source/update/common/uachelper.cxx
+++ b/onlineupdate/source/update/common/uachelper.cxx
@@ -11,48 +11,49 @@
// See the MSDN documentation with title: Privilege Constants
// At the time of this writing, this documentation is located at:
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb530716%28v=vs.85%29.aspx
-LPCTSTR UACHelper::PrivsToDisable[] = {
- SE_ASSIGNPRIMARYTOKEN_NAME,
- SE_AUDIT_NAME,
- SE_BACKUP_NAME,
- // CreateProcess will succeed but the app will fail to launch on some WinXP
- // machines if SE_CHANGE_NOTIFY_NAME is disabled. In particular this happens
- // for limited user accounts on those machines. The define is kept here as a
- // reminder that it should never be re-added.
- // This permission is for directory watching but also from MSDN: "This
- // privilege also causes the system to skip all traversal access checks."
- // SE_CHANGE_NOTIFY_NAME,
- SE_CREATE_GLOBAL_NAME,
- SE_CREATE_PAGEFILE_NAME,
- SE_CREATE_PERMANENT_NAME,
- SE_CREATE_SYMBOLIC_LINK_NAME,
- SE_CREATE_TOKEN_NAME,
- SE_DEBUG_NAME,
- SE_ENABLE_DELEGATION_NAME,
- SE_IMPERSONATE_NAME,
- SE_INC_BASE_PRIORITY_NAME,
- SE_INCREASE_QUOTA_NAME,
- SE_INC_WORKING_SET_NAME,
- SE_LOAD_DRIVER_NAME,
- SE_LOCK_MEMORY_NAME,
- SE_MACHINE_ACCOUNT_NAME,
- SE_MANAGE_VOLUME_NAME,
- SE_PROF_SINGLE_PROCESS_NAME,
- SE_RELABEL_NAME,
- SE_REMOTE_SHUTDOWN_NAME,
- SE_RESTORE_NAME,
- SE_SECURITY_NAME,
- SE_SHUTDOWN_NAME,
- SE_SYNC_AGENT_NAME,
- SE_SYSTEM_ENVIRONMENT_NAME,
- SE_SYSTEM_PROFILE_NAME,
- SE_SYSTEMTIME_NAME,
- SE_TAKE_OWNERSHIP_NAME,
- SE_TCB_NAME,
- SE_TIME_ZONE_NAME,
- SE_TRUSTED_CREDMAN_ACCESS_NAME,
- SE_UNDOCK_NAME,
- SE_UNSOLICITED_INPUT_NAME
+LPCTSTR UACHelper::PrivsToDisable[] =
+{
+ SE_ASSIGNPRIMARYTOKEN_NAME,
+ SE_AUDIT_NAME,
+ SE_BACKUP_NAME,
+ // CreateProcess will succeed but the app will fail to launch on some WinXP
+ // machines if SE_CHANGE_NOTIFY_NAME is disabled. In particular this happens
+ // for limited user accounts on those machines. The define is kept here as a
+ // reminder that it should never be re-added.
+ // This permission is for directory watching but also from MSDN: "This
+ // privilege also causes the system to skip all traversal access checks."
+ // SE_CHANGE_NOTIFY_NAME,
+ SE_CREATE_GLOBAL_NAME,
+ SE_CREATE_PAGEFILE_NAME,
+ SE_CREATE_PERMANENT_NAME,
+ SE_CREATE_SYMBOLIC_LINK_NAME,
+ SE_CREATE_TOKEN_NAME,
+ SE_DEBUG_NAME,
+ SE_ENABLE_DELEGATION_NAME,
+ SE_IMPERSONATE_NAME,
+ SE_INC_BASE_PRIORITY_NAME,
+ SE_INCREASE_QUOTA_NAME,
+ SE_INC_WORKING_SET_NAME,
+ SE_LOAD_DRIVER_NAME,
+ SE_LOCK_MEMORY_NAME,
+ SE_MACHINE_ACCOUNT_NAME,
+ SE_MANAGE_VOLUME_NAME,
+ SE_PROF_SINGLE_PROCESS_NAME,
+ SE_RELABEL_NAME,
+ SE_REMOTE_SHUTDOWN_NAME,
+ SE_RESTORE_NAME,
+ SE_SECURITY_NAME,
+ SE_SHUTDOWN_NAME,
+ SE_SYNC_AGENT_NAME,
+ SE_SYSTEM_ENVIRONMENT_NAME,
+ SE_SYSTEM_PROFILE_NAME,
+ SE_SYSTEMTIME_NAME,
+ SE_TAKE_OWNERSHIP_NAME,
+ SE_TCB_NAME,
+ SE_TIME_ZONE_NAME,
+ SE_TRUSTED_CREDMAN_ACCESS_NAME,
+ SE_UNDOCK_NAME,
+ SE_UNSOLICITED_INPUT_NAME
};
/**
@@ -65,15 +66,16 @@ LPCTSTR UACHelper::PrivsToDisable[] = {
HANDLE
UACHelper::OpenUserToken(DWORD sessionID)
{
- HMODULE module = LoadLibraryW(L"wtsapi32.dll");
- HANDLE token = nullptr;
- decltype(WTSQueryUserToken)* wtsQueryUserToken =
- (decltype(WTSQueryUserToken)*) GetProcAddress(module, "WTSQueryUserToken");
- if (wtsQueryUserToken) {
- wtsQueryUserToken(sessionID, &token);
- }
- FreeLibrary(module);
- return token;
+ HMODULE module = LoadLibraryW(L"wtsapi32.dll");
+ HANDLE token = nullptr;
+ decltype(WTSQueryUserToken)* wtsQueryUserToken =
+ (decltype(WTSQueryUserToken)*) GetProcAddress(module, "WTSQueryUserToken");
+ if (wtsQueryUserToken)
+ {
+ wtsQueryUserToken(sessionID, &token);
+ }
+ FreeLibrary(module);
+ return token;
}
/**
@@ -86,19 +88,20 @@ UACHelper::OpenUserToken(DWORD sessionID)
HANDLE
UACHelper::OpenLinkedToken(HANDLE token)
{
- // Magic below...
- // UAC creates 2 tokens. One is the restricted token which we have.
- // the other is the UAC elevated one. Since we are running as a service
- // as the system account we have access to both.
- TOKEN_LINKED_TOKEN tlt;
- HANDLE hNewLinkedToken = nullptr;
- DWORD len;
- if (GetTokenInformation(token, (TOKEN_INFORMATION_CLASS)TokenLinkedToken,
- &tlt, sizeof(TOKEN_LINKED_TOKEN), &len)) {
- token = tlt.LinkedToken;
- hNewLinkedToken = token;
- }
- return hNewLinkedToken;
+ // Magic below...
+ // UAC creates 2 tokens. One is the restricted token which we have.
+ // the other is the UAC elevated one. Since we are running as a service
+ // as the system account we have access to both.
+ TOKEN_LINKED_TOKEN tlt;
+ HANDLE hNewLinkedToken = nullptr;
+ DWORD len;
+ if (GetTokenInformation(token, (TOKEN_INFORMATION_CLASS)TokenLinkedToken,
+ &tlt, sizeof(TOKEN_LINKED_TOKEN), &len))
+ {
+ token = tlt.LinkedToken;
+ hNewLinkedToken = token;
+ }
+ return hNewLinkedToken;
}
@@ -113,23 +116,25 @@ UACHelper::OpenLinkedToken(HANDLE token)
BOOL
UACHelper::SetPrivilege(HANDLE token, LPCTSTR priv, BOOL enable)
{
- LUID luidOfPriv;
- if (!LookupPrivilegeValue(nullptr, priv, &luidOfPriv)) {
- return FALSE;
- }
-
- TOKEN_PRIVILEGES tokenPriv;
- tokenPriv.PrivilegeCount = 1;
- tokenPriv.Privileges[0].Luid = luidOfPriv;
- tokenPriv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
-
- SetLastError(ERROR_SUCCESS);
- if (!AdjustTokenPrivileges(token, false, &tokenPriv,
- sizeof(tokenPriv), nullptr, nullptr)) {
- return FALSE;
- }
-
- return GetLastError() == ERROR_SUCCESS;
+ LUID luidOfPriv;
+ if (!LookupPrivilegeValue(nullptr, priv, &luidOfPriv))
+ {
+ return FALSE;
+ }
+
+ TOKEN_PRIVILEGES tokenPriv;
+ tokenPriv.PrivilegeCount = 1;
+ tokenPriv.Privileges[0].Luid = luidOfPriv;
+ tokenPriv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
+
+ SetLastError(ERROR_SUCCESS);
+ if (!AdjustTokenPrivileges(token, false, &tokenPriv,
+ sizeof(tokenPriv), nullptr, nullptr))
+ {
+ return FALSE;
+ }
+
+ return GetLastError() == ERROR_SUCCESS;
}
/**
@@ -147,34 +152,41 @@ UACHelper::DisableUnneededPrivileges(HANDLE token,
LPCTSTR *unneededPrivs,
size_t count)
{
- HANDLE obtainedToken = nullptr;
- if (!token) {
- // Note: This handle is a pseudo-handle and need not be closed
- HANDLE process = GetCurrentProcess();
- if (!OpenProcessToken(process, TOKEN_ALL_ACCESS_P, &obtainedToken)) {
- LOG_WARN(("Could not obtain token for current process, no "
- "privileges changed. (%d)", GetLastError()));
- return FALSE;
+ HANDLE obtainedToken = nullptr;
+ if (!token)
+ {
+ // Note: This handle is a pseudo-handle and need not be closed
+ HANDLE process = GetCurrentProcess();
+ if (!OpenProcessToken(process, TOKEN_ALL_ACCESS_P, &obtainedToken))
+ {
+ LOG_WARN(("Could not obtain token for current process, no "
+ "privileges changed. (%d)", GetLastError()));
+ return FALSE;
+ }
+ token = obtainedToken;
}
- token = obtainedToken;
- }
-
- BOOL result = TRUE;
- for (size_t i = 0; i < count; i++) {
- if (SetPrivilege(token, unneededPrivs[i], FALSE)) {
- LOG(("Disabled unneeded token privilege: %s.",
- unneededPrivs[i]));
- } else {
- LOG(("Could not disable token privilege value: %s. (%d)",
- unneededPrivs[i], GetLastError()));
- result = FALSE;
+
+ BOOL result = TRUE;
+ for (size_t i = 0; i < count; i++)
+ {
+ if (SetPrivilege(token, unneededPrivs[i], FALSE))
+ {
+ LOG(("Disabled unneeded token privilege: %s.",
+ unneededPrivs[i]));
+ }
+ else
+ {
+ LOG(("Could not disable token privilege value: %s. (%d)",
+ unneededPrivs[i], GetLastError()));
+ result = FALSE;
+ }
}
- }
- if (obtainedToken) {
- CloseHandle(obtainedToken);
- }
- return result;
+ if (obtainedToken)
+ {
+ CloseHandle(obtainedToken);
+ }
+ return result;
}
/**
@@ -190,11 +202,11 @@ UACHelper::DisableUnneededPrivileges(HANDLE token,
BOOL
UACHelper::DisablePrivileges(HANDLE token)
{
- static const size_t PrivsToDisableSize =
- sizeof(UACHelper::PrivsToDisable) / sizeof(UACHelper::PrivsToDisable[0]);
+ static const size_t PrivsToDisableSize =
+ sizeof(UACHelper::PrivsToDisable) / sizeof(UACHelper::PrivsToDisable[0]);
- return DisableUnneededPrivileges(token, UACHelper::PrivsToDisable,
- PrivsToDisableSize);
+ return DisableUnneededPrivileges(token, UACHelper::PrivsToDisable,
+ PrivsToDisableSize);
}
/**
@@ -206,19 +218,20 @@ UACHelper::DisablePrivileges(HANDLE token)
bool
UACHelper::CanUserElevate()
{
- HANDLE token;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
- return false;
- }
-
- TOKEN_ELEVATION_TYPE elevationType;
- DWORD len;
- bool canElevate = GetTokenInformation(token, TokenElevationType,
- &elevationType,
- sizeof(elevationType), &len) &&
- (elevationType == TokenElevationTypeLimited);
- CloseHandle(token);
-
- return canElevate;
+ HANDLE token;
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
+ {
+ return false;
+ }
+
+ TOKEN_ELEVATION_TYPE elevationType;
+ DWORD len;
+ bool canElevate = GetTokenInformation(token, TokenElevationType,
+ &elevationType,
+ sizeof(elevationType), &len) &&
+ (elevationType == TokenElevationTypeLimited);
+ CloseHandle(token);
+
+ return canElevate;
}
#endif
diff --git a/onlineupdate/source/update/common/uachelper.h b/onlineupdate/source/update/common/uachelper.h
index 810d79d79f24..4e8d1c84239a 100644
--- a/onlineupdate/source/update/common/uachelper.h
+++ b/onlineupdate/source/update/common/uachelper.h
@@ -8,16 +8,16 @@
class UACHelper
{
public:
- static HANDLE OpenUserToken(DWORD sessionID);
- static HANDLE OpenLinkedToken(HANDLE token);
- static BOOL DisablePrivileges(HANDLE token);
- static bool CanUserElevate();
+ static HANDLE OpenUserToken(DWORD sessionID);
+ static HANDLE OpenLinkedToken(HANDLE token);
+ static BOOL DisablePrivileges(HANDLE token);
+ static bool CanUserElevate();
private:
- static BOOL SetPrivilege(HANDLE token, LPCTSTR privs, BOOL enable);
- static BOOL DisableUnneededPrivileges(HANDLE token,
- LPCTSTR *unneededPrivs, size_t count);
- static LPCTSTR PrivsToDisable[];
+ static BOOL SetPrivilege(HANDLE token, LPCTSTR privs, BOOL enable);
+ static BOOL DisableUnneededPrivileges(HANDLE token,
+ LPCTSTR *unneededPrivs, size_t count);
+ static LPCTSTR PrivsToDisable[];
};
#endif
diff --git a/onlineupdate/source/update/common/updatedefines.h b/onlineupdate/source/update/common/updatedefines.h
index 95969b169426..acca6887f422 100644
--- a/onlineupdate/source/update/common/updatedefines.h
+++ b/onlineupdate/source/update/common/updatedefines.h
@@ -47,13 +47,13 @@
static inline int mywcsprintf(WCHAR* dest, size_t count, const WCHAR* fmt, ...)
{
- size_t _count = count - 1;
- va_list varargs;
- va_start(varargs, fmt);
- int result = _vsnwprintf(dest, count - 1, fmt, varargs);
- va_end(varargs);
- dest[_count] = L'\0';
- return result;
+ size_t _count = count - 1;
+ va_list varargs;
+ va_start(varargs, fmt);
+ int result = _vsnwprintf(dest, count - 1, fmt, varargs);
+ va_end(varargs);
+ dest[_count] = L'\0';
+ return result;
}
#define NS_tsnprintf mywcsprintf
# define NS_taccess _waccess
diff --git a/onlineupdate/source/update/common/updatehelper.cxx b/onlineupdate/source/update/common/updatehelper.cxx
index c19b830e36e1..ab9e77f00979 100644
--- a/onlineupdate/source/update/common/updatehelper.cxx
+++ b/onlineupdate/source/update/common/updatehelper.cxx
@@ -35,20 +35,23 @@ PathGetSiblingFilePath(LPWSTR destinationBuffer,
LPCWSTR siblingFilePath,
LPCWSTR newFileName)
{
- if (wcslen(siblingFilePath) >= MAX_PATH) {
- return FALSE;
- }
+ if (wcslen(siblingFilePath) >= MAX_PATH)
+ {
+ return FALSE;
+ }
- wcsncpy(destinationBuffer, siblingFilePath, MAX_PATH);
- if (!PathRemoveFileSpecW(destinationBuffer)) {
- return FALSE;
- }
+ wcsncpy(destinationBuffer, siblingFilePath, MAX_PATH);
+ if (!PathRemoveFileSpecW(destinationBuffer))
+ {
+ return FALSE;
+ }
- if (wcslen(destinationBuffer) + wcslen(newFileName) >= MAX_PATH) {
- return FALSE;
- }
+ if (wcslen(destinationBuffer) + wcslen(newFileName) >= MAX_PATH)
+ {
+ return FALSE;
+ }
- return PathAppendSafe(destinationBuffer, newFileName);
+ return PathAppendSafe(destinationBuffer, newFileName);
}
/**
@@ -71,115 +74,128 @@ LaunchWinPostProcess(const WCHAR *installationDir,
bool forceSync,
HANDLE userToken)
{
- WCHAR workingDirectory[MAX_PATH + 1] = { L'\0' };
- wcsncpy(workingDirectory, installationDir, MAX_PATH);
-
- // Launch helper.exe to perform post processing (e.g. registry and log file
- // modifications) for the update.
- WCHAR inifile[MAX_PATH + 1] = { L'\0' };
- wcsncpy(inifile, installationDir, MAX_PATH);
- if (!PathAppendSafe(inifile, L"updater.ini")) {
- return FALSE;
- }
-
- WCHAR exefile[MAX_PATH + 1];
- WCHAR exearg[MAX_PATH + 1];
- WCHAR exeasync[10];
- bool async = true;
- if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", nullptr,
- exefile, MAX_PATH + 1, inifile)) {
- return FALSE;
- }
-
- if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeArg", nullptr, exearg,
- MAX_PATH + 1, inifile)) {
- return FALSE;
- }
-
- if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeAsync", L"TRUE",
- exeasync,
- sizeof(exeasync)/sizeof(exeasync[0]),
- inifile)) {
- return FALSE;
- }
-
- WCHAR exefullpath[MAX_PATH + 1] = { L'\0' };
- wcsncpy(exefullpath, installationDir, MAX_PATH);
- if (!PathAppendSafe(exefullpath, exefile)) {
- return false;
- }
-
- WCHAR dlogFile[MAX_PATH + 1];
- if (!PathGetSiblingFilePath(dlogFile, exefullpath, L"uninstall.update")) {
- return FALSE;
- }
-
- WCHAR slogFile[MAX_PATH + 1] = { L'\0' };
- wcsncpy(slogFile, updateInfoDir, MAX_PATH);
- if (!PathAppendSafe(slogFile, L"update.log")) {
- return FALSE;
- }
-
- WCHAR dummyArg[14] = { L'\0' };
- wcsncpy(dummyArg, L"argv0ignored ", sizeof(dummyArg) / sizeof(dummyArg[0]) - 1);
-
- size_t len = wcslen(exearg) + wcslen(dummyArg);
- WCHAR *cmdline = (WCHAR *) malloc((len + 1) * sizeof(WCHAR));
- if (!cmdline) {
- return FALSE;
- }
-
- wcsncpy(cmdline, dummyArg, len);
- wcscat(cmdline, exearg);
-
- if (forceSync ||
- !_wcsnicmp(exeasync, L"false", 6) ||
- !_wcsnicmp(exeasync, L"0", 2)) {
- async = false;
- }
-
- // We want to launch the post update helper app to update the Windows
- // registry even if there is a failure with removing the uninstall.update
- // file or copying the update.log file.
- CopyFileW(slogFile, dlogFile, false);
-
- STARTUPINFOW si = {sizeof(si), 0};
- si.lpDesktop = L"";
- PROCESS_INFORMATION pi = {0};
-
- bool ok;
- if (userToken) {
- ok = CreateProcessAsUserW(userToken,
- exefullpath,
- cmdline,
- nullptr, // no special security attributes
- nullptr, // no special thread attributes
- false, // don't inherit filehandles
- 0, // No special process creation flags
- nullptr, // inherit my environment
- workingDirectory,
- &si,
- &pi);
- } else {
- ok = CreateProcessW(exefullpath,
- cmdline,
- nullptr, // no special security attributes
- nullptr, // no special thread attributes
- false, // don't inherit filehandles
- 0, // No special process creation flags
- nullptr, // inherit my environment
- workingDirectory,
- &si,
- &pi);
- }
- free(cmdline);
- if (ok) {
- if (!async)
- WaitForSingleObject(pi.hProcess, INFINITE);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- return ok;
+ WCHAR workingDirectory[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(workingDirectory, installationDir, MAX_PATH);
+
+ // Launch helper.exe to perform post processing (e.g. registry and log file
+ // modifications) for the update.
+ WCHAR inifile[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(inifile, installationDir, MAX_PATH);
+ if (!PathAppendSafe(inifile, L"updater.ini"))
+ {
+ return FALSE;
+ }
+
+ WCHAR exefile[MAX_PATH + 1];
+ WCHAR exearg[MAX_PATH + 1];
+ WCHAR exeasync[10];
+ bool async = true;
+ if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", nullptr,
+ exefile, MAX_PATH + 1, inifile))
+ {
+ return FALSE;
+ }
+
+ if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeArg", nullptr, exearg,
+ MAX_PATH + 1, inifile))
+ {
+ return FALSE;
+ }
+
+ if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeAsync", L"TRUE",
+ exeasync,
+ sizeof(exeasync)/sizeof(exeasync[0]),
+ inifile))
+ {
+ return FALSE;
+ }
+
+ WCHAR exefullpath[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(exefullpath, installationDir, MAX_PATH);
+ if (!PathAppendSafe(exefullpath, exefile))
+ {
+ return false;
+ }
+
+ WCHAR dlogFile[MAX_PATH + 1];
+ if (!PathGetSiblingFilePath(dlogFile, exefullpath, L"uninstall.update"))
+ {
+ return FALSE;
+ }
+
+ WCHAR slogFile[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(slogFile, updateInfoDir, MAX_PATH);
+ if (!PathAppendSafe(slogFile, L"update.log"))
+ {
+ return FALSE;
+ }
+
+ WCHAR dummyArg[14] = { L'\0' };
+ wcsncpy(dummyArg, L"argv0ignored ", sizeof(dummyArg) / sizeof(dummyArg[0]) - 1);
+
+ size_t len = wcslen(exearg) + wcslen(dummyArg);
+ WCHAR *cmdline = (WCHAR *) malloc((len + 1) * sizeof(WCHAR));
+ if (!cmdline)
+ {
+ return FALSE;
+ }
+
+ wcsncpy(cmdline, dummyArg, len);
+ wcscat(cmdline, exearg);
+
+ if (forceSync ||
+ !_wcsnicmp(exeasync, L"false", 6) ||
+ !_wcsnicmp(exeasync, L"0", 2))
+ {
+ async = false;
+ }
+
+ // We want to launch the post update helper app to update the Windows
+ // registry even if there is a failure with removing the uninstall.update
+ // file or copying the update.log file.
+ CopyFileW(slogFile, dlogFile, false);
+
+ STARTUPINFOW si = {sizeof(si), 0};
+ si.lpDesktop = L"";
+ PROCESS_INFORMATION pi = {0};
+
+ bool ok;
+ if (userToken)
+ {
+ ok = CreateProcessAsUserW(userToken,
+ exefullpath,
+ cmdline,
+ nullptr, // no special security attributes
+ nullptr, // no special thread attributes
+ false, // don't inherit filehandles
+ 0, // No special process creation flags
+ nullptr, // inherit my environment
+ workingDirectory,
+ &si,
+ &pi);
+ }
+ else
+ {
+ ok = CreateProcessW(exefullpath,
+ cmdline,
+ nullptr, // no special security attributes
+ nullptr, // no special thread attributes
+ false, // don't inherit filehandles
+ 0, // No special process creation flags
+ nullptr, // inherit my environment
+ workingDirectory,
+ &si,
+ &pi);
+ }
+ free(cmdline);
+ if (ok)
+ {
+ if (!async)
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ return ok;
}
/**
@@ -193,89 +209,96 @@ LaunchWinPostProcess(const WCHAR *installationDir,
BOOL
StartServiceUpdate(LPCWSTR installDir)
{
- // Get a handle to the local computer SCM database
- SC_HANDLE manager = OpenSCManager(nullptr, nullptr,
- SC_MANAGER_ALL_ACCESS);
- if (!manager) {
- return FALSE;
- }
-
- // Open the service
- SC_HANDLE svc = OpenServiceW(manager, SVC_NAME,
- SERVICE_ALL_ACCESS);
- if (!svc) {
+ // Get a handle to the local computer SCM database
+ SC_HANDLE manager = OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_ALL_ACCESS);
+ if (!manager)
+ {
+ return FALSE;
+ }
+
+ // Open the service
+ SC_HANDLE svc = OpenServiceW(manager, SVC_NAME,
+ SERVICE_ALL_ACCESS);
+ if (!svc)
+ {
+ CloseServiceHandle(manager);
+ return FALSE;
+ }
+
+ // If we reach here, then the service is installed, so
+ // proceed with upgrading it.
+
CloseServiceHandle(manager);
- return FALSE;
- }
- // If we reach here, then the service is installed, so
- // proceed with upgrading it.
+ // The service exists and we opened it, get the config bytes needed
+ DWORD bytesNeeded;
+ if (!QueryServiceConfigW(svc, nullptr, 0, &bytesNeeded) &&
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ CloseServiceHandle(svc);
+ return FALSE;
+ }
- CloseServiceHandle(manager);
+ // Get the service config information, in particular we want the binary
+ // path of the service.
+ std::unique_ptr<char[]> serviceConfigBuffer = std::make_unique<char[]>(bytesNeeded);
+ if (!QueryServiceConfigW(svc,
+ reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()),
+ bytesNeeded, &bytesNeeded))
+ {
+ CloseServiceHandle(svc);
+ return FALSE;
+ }
- // The service exists and we opened it, get the config bytes needed
- DWORD bytesNeeded;
- if (!QueryServiceConfigW(svc, nullptr, 0, &bytesNeeded) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- CloseServiceHandle(svc);
- return FALSE;
- }
-
- // Get the service config information, in particular we want the binary
- // path of the service.
- std::unique_ptr<char[]> serviceConfigBuffer = std::make_unique<char[]>(bytesNeeded);
- if (!QueryServiceConfigW(svc,
- reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()),
- bytesNeeded, &bytesNeeded)) {
CloseServiceHandle(svc);
- return FALSE;
- }
-
- CloseServiceHandle(svc);
-
- QUERY_SERVICE_CONFIGW &serviceConfig =
- *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());
-
- PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);
-
- // Obtain the temp path of the maintenance service binary
- WCHAR tmpService[MAX_PATH + 1] = { L'\0' };
- if (!PathGetSiblingFilePath(tmpService, serviceConfig.lpBinaryPathName,
- L"maintenanceservice_tmp.exe")) {
- return FALSE;
- }
-
- // Get the new maintenance service path from the install dir
- WCHAR newMaintServicePath[MAX_PATH + 1] = { L'\0' };
- wcsncpy(newMaintServicePath, installDir, MAX_PATH);
- PathAppendSafe(newMaintServicePath,
- L"maintenanceservice.exe");
-
- // Copy the temp file in alongside the maintenance service.
- // This is a requirement for maintenance service upgrades.
- if (!CopyFileW(newMaintServicePath, tmpService, FALSE)) {
- return FALSE;
- }
-
- // Start the upgrade comparison process
- STARTUPINFOW si = {0};
- si.cb = sizeof(STARTUPINFOW);
- // No particular desktop because no UI
- si.lpDesktop = L"";
- PROCESS_INFORMATION pi = {0};
- WCHAR cmdLine[64] = { '\0' };
- wcsncpy(cmdLine, L"dummyparam.exe upgrade",
- sizeof(cmdLine) / sizeof(cmdLine[0]) - 1);
- BOOL svcUpdateProcessStarted = CreateProcessW(tmpService,
- cmdLine,
- nullptr, nullptr, FALSE,
- 0,
- nullptr, installDir, &si, &pi);
- if (svcUpdateProcessStarted) {
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- return svcUpdateProcessStarted;
+
+ QUERY_SERVICE_CONFIGW &serviceConfig =
+ *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());
+
+ PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);
+
+ // Obtain the temp path of the maintenance service binary
+ WCHAR tmpService[MAX_PATH + 1] = { L'\0' };
+ if (!PathGetSiblingFilePath(tmpService, serviceConfig.lpBinaryPathName,
+ L"maintenanceservice_tmp.exe"))
+ {
+ return FALSE;
+ }
+
+ // Get the new maintenance service path from the install dir
+ WCHAR newMaintServicePath[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(newMaintServicePath, installDir, MAX_PATH);
+ PathAppendSafe(newMaintServicePath,
+ L"maintenanceservice.exe");
+
+ // Copy the temp file in alongside the maintenace service.
+ // This is a requirement for maintenance service upgrades.
+ if (!CopyFileW(newMaintServicePath, tmpService, FALSE))
+ {
+ return FALSE;
+ }
+
+ // Start the upgrade comparison process
+ STARTUPINFOW si = {0};
+ si.cb = sizeof(STARTUPINFOW);
+ // No particular desktop because no UI
+ si.lpDesktop = L"";
+ PROCESS_INFORMATION pi = {0};
+ WCHAR cmdLine[64] = { '\0' };
+ wcsncpy(cmdLine, L"dummyparam.exe upgrade",
+ sizeof(cmdLine) / sizeof(cmdLine[0]) - 1);
+ BOOL svcUpdateProcessStarted = CreateProcessW(tmpService,
+ cmdLine,
+ nullptr, nullptr, FALSE,
+ 0,
+ nullptr, installDir, &si, &pi);
+ if (svcUpdateProcessStarted)
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ return svcUpdateProcessStarted;
}
#endif
@@ -295,47 +318,54 @@ StartServiceUpdate(LPCWSTR installDir)
DWORD
StartServiceCommand(int argc, LPCWSTR* argv)
{
- DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
- if (lastState != SERVICE_STOPPED) {
- return 20000 + lastState;
- }
-
- // Get a handle to the SCM database.
- SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
- SC_MANAGER_CONNECT |
- SC_MANAGER_ENUMERATE_SERVICE);
- if (!serviceManager) {
- return 17001;
- }
-
- // Get a handle to the service.
- SC_HANDLE service = OpenServiceW(serviceManager,
- SVC_NAME,
- SERVICE_START);
- if (!service) {
+ DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
+ if (lastState != SERVICE_STOPPED)
+ {
+ return 20000 + lastState;
+ }
+
+ // Get a handle to the SCM database.
+ SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_CONNECT |
+ SC_MANAGER_ENUMERATE_SERVICE);
+ if (!serviceManager)
+ {
+ return 17001;
+ }
+
+ // Get a handle to the service.
+ SC_HANDLE service = OpenServiceW(serviceManager,
+ SVC_NAME,
+ SERVICE_START);
+ if (!service)
+ {
+ CloseServiceHandle(serviceManager);
+ return 17002;
+ }
+
+ // Wait at most 5 seconds trying to start the service in case of errors
+ // like ERROR_SERVICE_DATABASE_LOCKED or ERROR_SERVICE_REQUEST_TIMEOUT.
+ const DWORD maxWaitMS = 5000;
+ DWORD currentWaitMS = 0;
+ DWORD lastError = ERROR_SUCCESS;
+ while (currentWaitMS < maxWaitMS)
+ {
+ BOOL result = StartServiceW(service, argc, argv);
+ if (result)
+ {
+ lastError = ERROR_SUCCESS;
+ break;
+ }
+ else
+ {
+ lastError = GetLastError();
+ }
+ Sleep(100);
+ currentWaitMS += 100;
+ }
+ CloseServiceHandle(service);
CloseServiceHandle(serviceManager);
- return 17002;
- }
-
- // Wait at most 5 seconds trying to start the service in case of errors
- // like ERROR_SERVICE_DATABASE_LOCKED or ERROR_SERVICE_REQUEST_TIMEOUT.
- const DWORD maxWaitMS = 5000;
- DWORD currentWaitMS = 0;
- DWORD lastError = ERROR_SUCCESS;
- while (currentWaitMS < maxWaitMS) {
- BOOL result = StartServiceW(service, argc, argv);
- if (result) {
- lastError = ERROR_SUCCESS;
- break;
- } else {
- lastError = GetLastError();
- }
- Sleep(100);
- currentWaitMS += 100;
- }
- CloseServiceHandle(service);
- CloseServiceHandle(serviceManager);
- return lastError;
+ return lastError;
}
#ifndef ONLY_SERVICE_LAUNCHING
@@ -353,22 +383,23 @@ StartServiceCommand(int argc, LPCWSTR* argv)
DWORD
LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR* argv)
{
- // The service command is the same as the updater.exe command line except
- // it has 2 extra args: 1) The Path to updater.exe, and 2) the command
- // being executed which is "software-update"
- LPCWSTR *updaterServiceArgv = new LPCWSTR[argc + 2];
- updaterServiceArgv[0] = L"MozillaMaintenance";
- updaterServiceArgv[1] = L"software-update";
-
- for (int i = 0; i < argc; ++i) {
- updaterServiceArgv[i + 2] = argv[i];
- }
-
- // Execute the service command by starting the service with
- // the passed in arguments.
- DWORD ret = StartServiceCommand(argc + 2, updaterServiceArgv);
- delete[] updaterServiceArgv;
- return ret;
+ // The service command is the same as the updater.exe command line except
+ // it has 2 extra args: 1) The Path to updater.exe, and 2) the command
+ // being executed which is "software-update"
+ LPCWSTR *updaterServiceArgv = new LPCWSTR[argc + 2];
+ updaterServiceArgv[0] = L"MozillaMaintenance";
+ updaterServiceArgv[1] = L"software-update";
+
+ for (int i = 0; i < argc; ++i)
+ {
+ updaterServiceArgv[i + 2] = argv[i];
+ }
+
+ // Execute the service command by starting the service with
+ // the passed in arguments.
+ DWORD ret = StartServiceCommand(argc + 2, updaterServiceArgv);
+ delete[] updaterServiceArgv;
+ return ret;
}
/**
@@ -381,11 +412,12 @@ LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR* argv)
BOOL
PathAppendSafe(LPWSTR base, LPCWSTR extra)
{
- if (wcslen(base) + wcslen(extra) >= MAX_PATH) {
- return FALSE;
- }
+ if (wcslen(base) + wcslen(extra) >= MAX_PATH)
+ {
+ return FALSE;
+ }
- return PathAppendW(base, extra);
+ return PathAppendW(base, extra);
}
/**
@@ -398,24 +430,26 @@ PathAppendSafe(LPWSTR base, LPCWSTR extra)
BOOL
WriteStatusPending(LPCWSTR updateDirPath)
{
- WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
- wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
- if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
- return FALSE;
- }
-
- const char pending[] = "pending";
- HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
- nullptr, CREATE_ALWAYS, 0, nullptr);
- if (statusFile == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
-
- DWORD wrote;
- BOOL ok = WriteFile(statusFile, pending,
- sizeof(pending) - 1, &wrote, nullptr);
- CloseHandle(statusFile);
- return ok && (wrote == sizeof(pending) - 1);
+ WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
+ if (!PathAppendSafe(updateStatusFilePath, L"update.status"))
+ {
+ return FALSE;
+ }
+
+ const char pending[] = "pending";
+ HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
+ nullptr, CREATE_ALWAYS, 0, nullptr);
+ if (statusFile == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+
+ DWORD wrote;
+ BOOL ok = WriteFile(statusFile, pending,
+ sizeof(pending) - 1, &wrote, nullptr);
+ CloseHandle(statusFile);
+ return ok && (wrote == sizeof(pending) - 1);
}
/**
@@ -427,26 +461,28 @@ WriteStatusPending(LPCWSTR updateDirPath)
BOOL
WriteStatusFailure(LPCWSTR updateDirPath, int errorCode)
{
- WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
- wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
- if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
- return FALSE;
- }
-
- HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
- nullptr, CREATE_ALWAYS, 0, nullptr);
- if (statusFile == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
- char failure[32];
- sprintf(failure, "failed: %d", errorCode);
-
- DWORD toWrite = strlen(failure);
- DWORD wrote;
- BOOL ok = WriteFile(statusFile, failure,
- toWrite, &wrote, nullptr);
- CloseHandle(statusFile);
- return ok && wrote == toWrite;
+ WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
+ wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
+ if (!PathAppendSafe(updateStatusFilePath, L"update.status"))
+ {
+ return FALSE;
+ }
+
+ HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
+ nullptr, CREATE_ALWAYS, 0, nullptr);
+ if (statusFile == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+ char failure[32];
+ sprintf(failure, "failed: %d", errorCode);
+
+ DWORD toWrite = strlen(failure);
+ DWORD wrote;
+ BOOL ok = WriteFile(statusFile, failure,
+ toWrite, &wrote, nullptr);
+ CloseHandle(statusFile);
+ return ok && wrote == toWrite;
}
#endif
@@ -486,101 +522,109 @@ WriteStatusFailure(LPCWSTR updateDirPath, int errorCode)
DWORD
WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds)
{
- // 0x000000CF is defined above to be not set
- DWORD lastServiceState = 0x000000CF;
-
- // Get a handle to the SCM database.
- SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
- SC_MANAGER_CONNECT |
- SC_MANAGER_ENUMERATE_SERVICE);
- if (!serviceManager) {
- DWORD lastError = GetLastError();
- switch(lastError) {
- case ERROR_ACCESS_DENIED:
- return 0x000000FD;
- case ERROR_DATABASE_DOES_NOT_EXIST:
- return 0x000000FE;
- default:
- return 0x000000FF;
- }
- }
-
- // Get a handle to the service.
- SC_HANDLE service = OpenServiceW(serviceManager,
- serviceName,
- SERVICE_QUERY_STATUS);
- if (!service) {
- DWORD lastError = GetLastError();
- CloseServiceHandle(serviceManager);
- switch(lastError) {
- case ERROR_ACCESS_DENIED:
- return 0x000000EB;
- case ERROR_INVALID_HANDLE:
- return 0x000000EC;
- case ERROR_INVALID_NAME:
- return 0x000000ED;
- case ERROR_SERVICE_DOES_NOT_EXIST:
- return 0x000000EE;
- default:
- return 0x000000EF;
- }
- }
-
- DWORD currentWaitMS = 0;
- SERVICE_STATUS_PROCESS ssp;
- ssp.dwCurrentState = lastServiceState;
- while (currentWaitMS < maxWaitSeconds * 1000) {
- DWORD bytesNeeded;
- if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
- DWORD lastError = GetLastError();
- switch (lastError) {
- case ERROR_INVALID_HANDLE:
- ssp.dwCurrentState = 0x000000D9;
- break;
- case ERROR_ACCESS_DENIED:
- ssp.dwCurrentState = 0x000000DA;
- break;
- case ERROR_INSUFFICIENT_BUFFER:
- ssp.dwCurrentState = 0x000000DB;
- break;
- case ERROR_INVALID_PARAMETER:
- ssp.dwCurrentState = 0x000000DC;
- break;
- case ERROR_INVALID_LEVEL:
- ssp.dwCurrentState = 0x000000DD;
- break;
- case ERROR_SHUTDOWN_IN_PROGRESS:
- ssp.dwCurrentState = 0x000000DE;
- break;
- // These 3 errors can occur when the service is not yet stopped but
- // it is stopping.
- case ERROR_INVALID_SERVICE_CONTROL:
- case ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
- case ERROR_SERVICE_NOT_ACTIVE:
- currentWaitMS += 50;
- Sleep(50);
- continue;
- default:
- ssp.dwCurrentState = 0x000000DF;
- }
+ // 0x000000CF is defined above to be not set
+ DWORD lastServiceState = 0x000000CF;
+
+ // Get a handle to the SCM database.
+ SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
+ SC_MANAGER_CONNECT |
+ SC_MANAGER_ENUMERATE_SERVICE);
+ if (!serviceManager)
+ {
+ DWORD lastError = GetLastError();
+ switch (lastError)
+ {
+ case ERROR_ACCESS_DENIED:
+ return 0x000000FD;
+ case ERROR_DATABASE_DOES_NOT_EXIST:
+ return 0x000000FE;
+ default:
+ return 0x000000FF;
+ }
+ }
- // We couldn't query the status so just break out
- break;
+ // Get a handle to the service.
+ SC_HANDLE service = OpenServiceW(serviceManager,
+ serviceName,
+ SERVICE_QUERY_STATUS);
+ if (!service)
+ {
+ DWORD lastError = GetLastError();
+ CloseServiceHandle(serviceManager);
+ switch (lastError)
+ {
+ case ERROR_ACCESS_DENIED:
+ return 0x000000EB;
+ case ERROR_INVALID_HANDLE:
+ return 0x000000EC;
+ case ERROR_INVALID_NAME:
+ return 0x000000ED;
+ case ERROR_SERVICE_DOES_NOT_EXIST:
+ return 0x000000EE;
+ default:
+ return 0x000000EF;
+ }
}
- // The service is already in use.
- if (ssp.dwCurrentState == SERVICE_STOPPED) {
- break;
+ DWORD currentWaitMS = 0;
+ SERVICE_STATUS_PROCESS ssp;
+ ssp.dwCurrentState = lastServiceState;
+ while (currentWaitMS < maxWaitSeconds * 1000)
+ {
+ DWORD bytesNeeded;
+ if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
+ sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded))
+ {
+ DWORD lastError = GetLastError();
+ switch (lastError)
+ {
+ case ERROR_INVALID_HANDLE:
+ ssp.dwCurrentState = 0x000000D9;
+ break;
+ case ERROR_ACCESS_DENIED:
+ ssp.dwCurrentState = 0x000000DA;
+ break;
+ case ERROR_INSUFFICIENT_BUFFER:
+ ssp.dwCurrentState = 0x000000DB;
+ break;
+ case ERROR_INVALID_PARAMETER:
+ ssp.dwCurrentState = 0x000000DC;
+ break;
+ case ERROR_INVALID_LEVEL:
+ ssp.dwCurrentState = 0x000000DD;
+ break;
+ case ERROR_SHUTDOWN_IN_PROGRESS:
+ ssp.dwCurrentState = 0x000000DE;
+ break;
+ // These 3 errors can occur when the service is not yet stopped but
+ // it is stopping.
+ case ERROR_INVALID_SERVICE_CONTROL:
+ case ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
+ case ERROR_SERVICE_NOT_ACTIVE:
+ currentWaitMS += 50;
+ Sleep(50);
+ continue;
+ default:
+ ssp.dwCurrentState = 0x000000DF;
+ }
+
+ // We couldn't query the status so just break out
+ break;
+ }
+
+ // The service is already in use.
+ if (ssp.dwCurrentState == SERVICE_STOPPED)
+ {
+ break;
+ }
+ currentWaitMS += 50;
+ Sleep(50);
}
- currentWaitMS += 50;
- Sleep(50);
- }
- lastServiceState = ssp.dwCurrentState;
- CloseServiceHandle(service);
- CloseServiceHandle(serviceManager);
- return lastServiceState;
+ lastServiceState = ssp.dwCurrentState;
+ CloseServiceHandle(service);
+ CloseServiceHandle(serviceManager);
+ return lastServiceState;
}
#ifndef ONLY_SERVICE_LAUNCHING
@@ -597,28 +641,33 @@ WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds)
DWORD
IsProcessRunning(LPCWSTR filename)
{
- // Take a snapshot of all processes in the system.
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (INVALID_HANDLE_VALUE == snapshot) {
- return GetLastError();
- }
-
- PROCESSENTRY32W processEntry;
- processEntry.dwSize = sizeof(PROCESSENTRY32W);
- if (!Process32FirstW(snapshot, &processEntry)) {
- DWORD lastError = GetLastError();
- CloseHandle(snapshot);
- return lastError;
- }
+ // Take a snapshot of all processes in the system.
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (INVALID_HANDLE_VALUE == snapshot)
+ {
+ return GetLastError();
+ }
- do {
- if (wcsicmp(filename, processEntry.szExeFile) == 0) {
- CloseHandle(snapshot);
- return ERROR_SUCCESS;
+ PROCESSENTRY32W processEntry;
+ processEntry.dwSize = sizeof(PROCESSENTRY32W);
+ if (!Process32FirstW(snapshot, &processEntry))
+ {
+ DWORD lastError = GetLastError();
+ CloseHandle(snapshot);
+ return lastError;
}
- } while (Process32NextW(snapshot, &processEntry));
- CloseHandle(snapshot);
- return ERROR_NOT_FOUND;
+
+ do
+ {
+ if (wcsicmp(filename, processEntry.szExeFile) == 0)
+ {
+ CloseHandle(snapshot);
+ return ERROR_SUCCESS;
+ }
+ }
+ while (Process32NextW(snapshot, &processEntry));
+ CloseHandle(snapshot);
+ return ERROR_NOT_FOUND;
}
/**
@@ -634,20 +683,23 @@ IsProcessRunning(LPCWSTR filename)
DWORD
WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds)
{
- DWORD applicationRunningError = WAIT_TIMEOUT;
- for(DWORD i = 0; i < maxSeconds; i++) {
- DWORD applicationRunningError = IsProcessRunning(filename);
- if (ERROR_NOT_FOUND == applicationRunningError) {
- return ERROR_SUCCESS;
+ DWORD applicationRunningError = WAIT_TIMEOUT;
+ for (DWORD i = 0; i < maxSeconds; i++)
+ {
+ DWORD applicationRunningError = IsProcessRunning(filename);
+ if (ERROR_NOT_FOUND == applicationRunningError)
+ {
+ return ERROR_SUCCESS;
+ }
+ Sleep(1000);
}
- Sleep(1000);
- }
- if (ERROR_SUCCESS == applicationRunningError) {
- return WAIT_TIMEOUT;
- }
+ if (ERROR_SUCCESS == applicationRunningError)
+ {
+ return WAIT_TIMEOUT;
+ }
- return applicationRunningError;
+ return applicationRunningError;
}
/**
@@ -658,16 +710,17 @@ WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds)
BOOL
DoesFallbackKeyExist()
{
- HKEY testOnlyFallbackKey;
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- TEST_ONLY_FALLBACK_KEY_PATH, 0,
- KEY_READ | KEY_WOW64_64KEY,
- &testOnlyFallbackKey) != ERROR_SUCCESS) {
- return FALSE;
- }
-
- RegCloseKey(testOnlyFallbackKey);
- return TRUE;
+ HKEY testOnlyFallbackKey;
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ TEST_ONLY_FALLBACK_KEY_PATH, 0,
+ KEY_READ | KEY_WOW64_64KEY,
+ &testOnlyFallbackKey) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ RegCloseKey(testOnlyFallbackKey);
+ return TRUE;
}
#endif
@@ -681,15 +734,16 @@ DoesFallbackKeyExist()
BOOL
IsLocalFile(LPCWSTR file, BOOL &isLocal)
{
- WCHAR rootPath[MAX_PATH + 1] = { L'\0' };
- if (wcslen(file) > MAX_PATH) {
- return FALSE;
- }
-
- wcsncpy(rootPath, file, MAX_PATH);
- PathStripToRootW(rootPath);
- isLocal = GetDriveTypeW(rootPath) == DRIVE_FIXED;
- return TRUE;
+ WCHAR rootPath[MAX_PATH + 1] = { L'\0' };
+ if (wcslen(file) > MAX_PATH)
+ {
+ return FALSE;
+ }
+
+ wcsncpy(rootPath, file, MAX_PATH);
+ PathStripToRootW(rootPath);
+ isLocal = GetDriveTypeW(rootPath) == DRIVE_FIXED;
+ return TRUE;
}
@@ -704,11 +758,11 @@ IsLocalFile(LPCWSTR file, BOOL &isLocal)
static BOOL
GetDWORDValue(HKEY key, LPCWSTR valueName, DWORD &retValue)
{
- DWORD regDWORDValueSize = sizeof(DWORD);
- LONG retCode = RegQueryValueExW(key, valueName, 0, nullptr,
- reinterpret_cast<LPBYTE>(&retValue),
- &regDWORDValueSize);
- return ERROR_SUCCESS == retCode;
+ DWORD regDWORDValueSize = sizeof(DWORD);
+ LONG retCode = RegQueryValueExW(key, valueName, 0, nullptr,
+ reinterpret_cast<LPBYTE>(&retValue),
+ &regDWORDValueSize);
+ return ERROR_SUCCESS == retCode;
}
/**
@@ -723,29 +777,31 @@ GetDWORDValue(HKEY key, LPCWSTR valueName, DWORD &retValue)
BOOL
IsUnpromptedElevation(BOOL &isUnpromptedElevation)
{
- if (!UACHelper::CanUserElevate()) {
- return FALSE;
- }
-
- LPCWSTR UACBaseRegKey =
- L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
- HKEY baseKey;
- LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- UACBaseRegKey, 0,
- KEY_READ, &baseKey);
- if (retCode != ERROR_SUCCESS) {
- return FALSE;
- }
-
- DWORD consent;
- DWORD secureDesktop = 0;
- BOOL success = GetDWORDValue(baseKey, L"ConsentPromptBehaviorAdmin",
- consent);
- success = success &&
- GetDWORDValue(baseKey, L"PromptOnSecureDesktop", secureDesktop);
- isUnpromptedElevation = !consent && !secureDesktop;
-
- RegCloseKey(baseKey);
- return success;
+ if (!UACHelper::CanUserElevate())
+ {
+ return FALSE;
+ }
+
+ LPCWSTR UACBaseRegKey =
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
+ HKEY baseKey;
+ LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ UACBaseRegKey, 0,
+ KEY_READ, &baseKey);
+ if (retCode != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ DWORD consent;
+ DWORD secureDesktop = 0;
+ BOOL success = GetDWORDValue(baseKey, L"ConsentPromptBehaviorAdmin",
+ consent);
+ success = success &&
+ GetDWORDValue(baseKey, L"PromptOnSecureDesktop", secureDesktop);
+ isUnpromptedElevation = !consent && !secureDesktop;
+
+ RegCloseKey(baseKey);
+ return success;
}
#endif
diff --git a/onlineupdate/source/update/common/updatelogging.cxx b/onlineupdate/source/update/common/updatelogging.cxx
index 22a74e17e953..ed055cd47072 100644
--- a/onlineupdate/source/update/common/updatelogging.cxx
+++ b/onlineupdate/source/update/common/updatelogging.cxx
@@ -25,60 +25,61 @@ void UpdateLog::Init(NS_tchar* sourcePathParam,
const NS_tchar* alternateFileName,
bool append)
{
- if (logFP)
- return;
+ if (logFP)
+ return;
- sourcePath = sourcePathParam;
- NS_tchar logFile[MAXPATHLEN];
- NS_tsnprintf(logFile, sizeof(logFile)/sizeof(logFile[0]),
- NS_T("%s/%s"), sourcePathParam, fileName);
-
- if (alternateFileName && NS_taccess(logFile, F_OK)) {
+ sourcePath = sourcePathParam;
+ NS_tchar logFile[MAXPATHLEN];
NS_tsnprintf(logFile, sizeof(logFile)/sizeof(logFile[0]),
- NS_T("%s/%s"), sourcePathParam, alternateFileName);
- }
+ NS_T("%s/%s"), sourcePathParam, fileName);
+
+ if (alternateFileName && NS_taccess(logFile, F_OK))
+ {
+ NS_tsnprintf(logFile, sizeof(logFile)/sizeof(logFile[0]),
+ NS_T("%s/%s"), sourcePathParam, alternateFileName);
+ }
- logFP = NS_tfopen(logFile, append ? NS_T("a") : NS_T("w"));
+ logFP = NS_tfopen(logFile, append ? NS_T("a") : NS_T("w"));
}
void UpdateLog::Finish()
{
- if (!logFP)
- return;
+ if (!logFP)
+ return;
- fclose(logFP);
- logFP = nullptr;
+ fclose(logFP);
+ logFP = nullptr;
}
void UpdateLog::Flush()
{
- if (!logFP)
- return;
+ if (!logFP)
+ return;
- fflush(logFP);
+ fflush(logFP);
}
void UpdateLog::Printf(const char *fmt, ... )
{
- if (!logFP)
- return;
-
- va_list ap;
- va_start(ap, fmt);
- vfprintf(logFP, fmt, ap);
- fprintf(logFP, "\n");
- va_end(ap);
+ if (!logFP)
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(logFP, fmt, ap);
+ fprintf(logFP, "\n");
+ va_end(ap);
}
void UpdateLog::WarnPrintf(const char *fmt, ... )
{
- if (!logFP)
- return;
-
- va_list ap;
- va_start(ap, fmt);
- fprintf(logFP, "*** Warning: ");
- vfprintf(logFP, fmt, ap);
- fprintf(logFP, "***\n");
- va_end(ap);
+ if (!logFP)
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(logFP, "*** Warning: ");
+ vfprintf(logFP, fmt, ap);
+ fprintf(logFP, "***\n");
+ va_end(ap);
}
diff --git a/onlineupdate/source/update/common/updatelogging.h b/onlineupdate/source/update/common/updatelogging.h
index 8cdf0396df95..591cb3f4f2c2 100644
--- a/onlineupdate/source/update/common/updatelogging.h
+++ b/onlineupdate/source/update/common/updatelogging.h
@@ -11,28 +11,28 @@
class UpdateLog
{
public:
- static UpdateLog & GetPrimaryLog()
- {
- static UpdateLog primaryLog;
- return primaryLog;
- }
-
- void Init(NS_tchar* sourcePath, const NS_tchar* fileName,
- const NS_tchar* alternateFileName, bool append);
- void Finish();
- void Flush();
- void Printf(const char *fmt, ... );
- void WarnPrintf(const char *fmt, ... );
-
- ~UpdateLog()
- {
- Finish();
- }
+ static UpdateLog & GetPrimaryLog()
+ {
+ static UpdateLog primaryLog;
+ return primaryLog;
+ }
+
+ void Init(NS_tchar* sourcePath, const NS_tchar* fileName,
+ const NS_tchar* alternateFileName, bool append);
+ void Finish();
+ void Flush();
+ void Printf(const char *fmt, ... );
+ void WarnPrintf(const char *fmt, ... );
+
+ ~UpdateLog()
+ {
+ Finish();
+ }
protected:
- UpdateLog();
- FILE *logFP;
- NS_tchar* sourcePath;
+ UpdateLog();
+ FILE *logFP;
+ NS_tchar* sourcePath;
};
#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args
diff --git a/onlineupdate/source/update/common/win_dirent.h b/onlineupdate/source/update/common/win_dirent.h
index a2281557e25a..ee2ab6c67bd5 100644
--- a/onlineupdate/source/update/common/win_dirent.h
+++ b/onlineupdate/source/update/common/win_dirent.h
@@ -9,16 +9,18 @@
#ifdef _WIN32
#include <windows.h>
-struct DIR {
- explicit DIR(const WCHAR* path);
- ~DIR();
- HANDLE findHandle;
- WCHAR name[MAX_PATH];
+struct DIR
+{
+ explicit DIR(const WCHAR* path);
+ ~DIR();
+ HANDLE findHandle;
+ WCHAR name[MAX_PATH];
};
-struct dirent {
- dirent();
- WCHAR d_name[MAX_PATH];
+struct dirent
+{
+ dirent();
+ WCHAR d_name[MAX_PATH];
};
DIR* opendir(const WCHAR* path);
diff --git a/onlineupdate/source/update/updater/archivereader.cxx b/onlineupdate/source/update/updater/archivereader.cxx
index e62b65b1e4ba..b0395d14094e 100644
--- a/onlineupdate/source/update/updater/archivereader.cxx
+++ b/onlineupdate/source/update/updater/archivereader.cxx
@@ -52,18 +52,19 @@ template<uint32_t SIZE>
int
VerifyLoadedCert(MarFile *archive, const uint8_t (&certData)[SIZE])
{
- (void)archive;
- (void)certData;
+ (void)archive;
+ (void)certData;
#ifdef VERIFY_MAR_SIGNATURE
- const uint32_t size = SIZE;
- const uint8_t* const data = &certData[0];
- if (mar_verify_signatures(archive, &data, &size, 1)) {
- return CERT_VERIFY_ERROR;
- }
+ const uint32_t size = SIZE;
+ const uint8_t* const data = &certData[0];
+ if (mar_verify_signatures(archive, &data, &size, 1))
+ {
+ return CERT_VERIFY_ERROR;
+ }
#endif
- return OK;
+ return OK;
}
/**
@@ -77,22 +78,24 @@ VerifyLoadedCert(MarFile *archive, const uint8_t (&certData)[SIZE])
int
ArchiveReader::VerifySignature()
{
- if (!mArchive) {
- return ARCHIVE_NOT_OPEN;
- }
+ if (!mArchive)
+ {
+ return ARCHIVE_NOT_OPEN;
+ }
#ifndef VERIFY_MAR_SIGNATURE
- return OK;
+ return OK;
#else
#ifdef TEST_UPDATER
- int rv = VerifyLoadedCert(mArchive, xpcshellCertData);
+ int rv = VerifyLoadedCert(mArchive, xpcshellCertData);
#else
- int rv = VerifyLoadedCert(mArchive, primaryCertData);
- if (rv != OK) {
- rv = VerifyLoadedCert(mArchive, secondaryCertData);
- }
+ int rv = VerifyLoadedCert(mArchive, primaryCertData);
+ if (rv != OK)
+ {
+ rv = VerifyLoadedCert(mArchive, secondaryCertData);
+ }
#endif
- return rv;
+ return rv;
#endif
}
@@ -121,203 +124,224 @@ int
ArchiveReader::VerifyProductInformation(const char *MARChannelID,
const char *appVersion)
{
- if (!mArchive) {
- return ARCHIVE_NOT_OPEN;
- }
-
- ProductInformationBlock productInfoBlock;
- int rv = mar_read_product_info_block(mArchive,
- &productInfoBlock);
- if (rv != OK) {
- return COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR;
- }
-
- // Only check the MAR channel name if specified, it should be passed in from
- // the update-settings.ini file.
- if (MARChannelID && strlen(MARChannelID)) {
- // Check for at least one match in the comma separated list of values.
- const char *delimiter = " ,\t";
- // Make a copy of the string in case a read only memory buffer
- // was specified. strtok modifies the input buffer.
- char channelCopy[512] = { 0 };
- strncpy(channelCopy, MARChannelID, sizeof(channelCopy) - 1);
- char *channel = strtok(channelCopy, delimiter);
- rv = MAR_CHANNEL_MISMATCH_ERROR;
- while(channel) {
- if (!strcmp(channel, productInfoBlock.MARChannelID)) {
- rv = OK;
- break;
- }
- channel = strtok(nullptr, delimiter);
+ if (!mArchive)
+ {
+ return ARCHIVE_NOT_OPEN;
+ }
+
+ ProductInformationBlock productInfoBlock;
+ int rv = mar_read_product_info_block(mArchive,
+ &productInfoBlock);
+ if (rv != OK)
+ {
+ return COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR;
+ }
+
+ // Only check the MAR channel name if specified, it should be passed in from
+ // the update-settings.ini file.
+ if (MARChannelID && strlen(MARChannelID))
+ {
+ // Check for at least one match in the comma separated list of values.
+ const char *delimiter = " ,\t";
+ // Make a copy of the string in case a read only memory buffer
+ // was specified. strtok modifies the input buffer.
+ char channelCopy[512] = { 0 };
+ strncpy(channelCopy, MARChannelID, sizeof(channelCopy) - 1);
+ char *channel = strtok(channelCopy, delimiter);
+ rv = MAR_CHANNEL_MISMATCH_ERROR;
+ while (channel)
+ {
+ if (!strcmp(channel, productInfoBlock.MARChannelID))
+ {
+ rv = OK;
+ break;
+ }
+ channel = strtok(nullptr, delimiter);
+ }
}
- }
-
- if (rv == OK) {
- /* Compare both versions to ensure we don't have a downgrade
- -1 if appVersion is older than productInfoBlock.productVersion
- 1 if appVersion is newer than productInfoBlock.productVersion
- 0 if appVersion is the same as productInfoBlock.productVersion
- This even works with strings like:
- - 12.0a1 being older than 12.0a2
- - 12.0a2 being older than 12.0b1
- - 12.0a1 being older than 12.0
- - 12.0 being older than 12.1a1 */
- int versionCompareResult =
- mozilla::CompareVersions(appVersion, productInfoBlock.productVersion);
- if (1 == versionCompareResult) {
- rv = VERSION_DOWNGRADE_ERROR;
+
+ if (rv == OK)
+ {
+ /* Compare both versions to ensure we don't have a downgrade
+ -1 if appVersion is older than productInfoBlock.productVersion
+ 1 if appVersion is newer than productInfoBlock.productVersion
+ 0 if appVersion is the same as productInfoBlock.productVersion
+ This even works with strings like:
+ - 12.0a1 being older than 12.0a2
+ - 12.0a2 being older than 12.0b1
+ - 12.0a1 being older than 12.0
+ - 12.0 being older than 12.1a1 */
+ int versionCompareResult =
+ mozilla::CompareVersions(appVersion, productInfoBlock.productVersion);
+ if (1 == versionCompareResult)
+ {
+ rv = VERSION_DOWNGRADE_ERROR;
+ }
}
- }
- free((void *)productInfoBlock.MARChannelID);
- free((void *)productInfoBlock.productVersion);
- return rv;
+ free((void *)productInfoBlock.MARChannelID);
+ free((void *)productInfoBlock.productVersion);
+ return rv;
}
int
ArchiveReader::Open(const NS_tchar *path)
{
- if (mArchive)
- Close();
-
- if (!inbuf) {
- inbuf = (char *)malloc(inbuf_size);
- if (!inbuf) {
- // Try again with a smaller buffer.
- inbuf_size = 1024;
- inbuf = (char *)malloc(inbuf_size);
- if (!inbuf)
- return ARCHIVE_READER_MEM_ERROR;
+ if (mArchive)
+ Close();
+
+ if (!inbuf)
+ {
+ inbuf = (char *)malloc(inbuf_size);
+ if (!inbuf)
+ {
+ // Try again with a smaller buffer.
+ inbuf_size = 1024;
+ inbuf = (char *)malloc(inbuf_size);
+ if (!inbuf)
+ return ARCHIVE_READER_MEM_ERROR;
+ }
}
- }
-
- if (!outbuf) {
- outbuf = (char *)malloc(outbuf_size);
- if (!outbuf) {
- // Try again with a smaller buffer.
- outbuf_size = 1024;
- outbuf = (char *)malloc(outbuf_size);
- if (!outbuf)
- return ARCHIVE_READER_MEM_ERROR;
+
+ if (!outbuf)
+ {
+ outbuf = (char *)malloc(outbuf_size);
+ if (!outbuf)
+ {
+ // Try again with a smaller buffer.
+ outbuf_size = 1024;
+ outbuf = (char *)malloc(outbuf_size);
+ if (!outbuf)
+ return ARCHIVE_READER_MEM_ERROR;
+ }
}
- }
#ifdef _WIN32
- mArchive = mar_wopen(path);
+ mArchive = mar_wopen(path);
#else
- mArchive = mar_open(path);
+ mArchive = mar_open(path);
#endif
- if (!mArchive)
- return READ_ERROR;
+ if (!mArchive)
+ return READ_ERROR;
- return OK;
+ return OK;
}
void
ArchiveReader::Close()
{
- if (mArchive) {
- mar_close(mArchive);
- mArchive = nullptr;
- }
-
- if (inbuf) {
- free(inbuf);
- inbuf = nullptr;
- }
-
- if (outbuf) {
- free(outbuf);
- outbuf = nullptr;
- }
+ if (mArchive)
+ {
+ mar_close(mArchive);
+ mArchive = nullptr;
+ }
+
+ if (inbuf)
+ {
+ free(inbuf);
+ inbuf = nullptr;
+ }
+
+ if (outbuf)
+ {
+ free(outbuf);
+ outbuf = nullptr;
+ }
}
int
ArchiveReader::ExtractFile(const char *name, const NS_tchar *dest)
{
- const MarItem *item = mar_find_item(mArchive, name);
- if (!item)
- return READ_ERROR;
+ const MarItem *item = mar_find_item(mArchive, name);
+ if (!item)
+ return READ_ERROR;
#ifdef _WIN32
- FILE* fp = _wfopen(dest, L"wb+");
+ FILE* fp = _wfopen(dest, L"wb+");
#else
- int fd = creat(dest, item->flags);
- if (fd == -1)
- return WRITE_ERROR;
+ int fd = creat(dest, item->flags);
+ if (fd == -1)
+ return WRITE_ERROR;
- FILE *fp = fdopen(fd, "wb");
+ FILE *fp = fdopen(fd, "wb");
#endif
- if (!fp)
- return WRITE_ERROR;
+ if (!fp)
+ return WRITE_ERROR;
- int rv = ExtractItemToStream(item, fp);
+ int rv = ExtractItemToStream(item, fp);
- fclose(fp);
- return rv;
+ fclose(fp);
+ return rv;
}
int
ArchiveReader::ExtractFileToStream(const char *name, FILE *fp)
{
- const MarItem *item = mar_find_item(mArchive, name);
- if (!item)
- return READ_ERROR;
+ const MarItem *item = mar_find_item(mArchive, name);
+ if (!item)
+ return READ_ERROR;
- return ExtractItemToStream(item, fp);
+ return ExtractItemToStream(item, fp);
}
int
ArchiveReader::ExtractItemToStream(const MarItem *item, FILE *fp)
{
- /* decompress the data chunk by chunk */
-
- bz_stream strm;
- int offset, inlen, ret = OK;
-
- memset(&strm, 0, sizeof(strm));
- if (BZ2_bzDecompressInit(&strm, 0, 0) != BZ_OK)
- return UNEXPECTED_BZIP_ERROR;
-
- offset = 0;
- for (;;) {
- if (!item->length) {
- ret = UNEXPECTED_MAR_ERROR;
- break;
- }
-
- if (offset < (int) item->length && strm.avail_in == 0) {
- inlen = mar_read(mArchive, item, offset, inbuf, inbuf_size);
- if (inlen <= 0)
- return READ_ERROR;
- offset += inlen;
- strm.next_in = inbuf;
- strm.avail_in = inlen;
- }
-
- strm.next_out = outbuf;
- strm.avail_out = outbuf_size;
-
- ret = BZ2_bzDecompress(&strm);
- if (ret != BZ_OK && ret != BZ_STREAM_END) {
- ret = UNEXPECTED_BZIP_ERROR;
- break;
- }
-
- int outlen = outbuf_size - strm.avail_out;
- if (outlen) {
- if (fwrite(outbuf, outlen, 1, fp) != 1) {
- ret = WRITE_ERROR_EXTRACT;
- break;
- }
- }
-
- if (ret == BZ_STREAM_END) {
- ret = OK;
- break;
+ /* decompress the data chunk by chunk */
+
+ bz_stream strm;
+ int offset, inlen, ret = OK;
+
+ memset(&strm, 0, sizeof(strm));
+ if (BZ2_bzDecompressInit(&strm, 0, 0) != BZ_OK)
+ return UNEXPECTED_BZIP_ERROR;
+
+ offset = 0;
+ for (;;)
+ {
+ if (!item->length)
+ {
+ ret = UNEXPECTED_MAR_ERROR;
+ break;
+ }
+
+ if (offset < (int) item->length && strm.avail_in == 0)
+ {
+ inlen = mar_read(mArchive, item, offset, inbuf, inbuf_size);
+ if (inlen <= 0)
+ return READ_ERROR;
+ offset += inlen;
+ strm.next_in = inbuf;
+ strm.avail_in = inlen;
+ }
+
+ strm.next_out = outbuf;
+ strm.avail_out = outbuf_size;
+
+ ret = BZ2_bzDecompress(&strm);
+ if (ret != BZ_OK && ret != BZ_STREAM_END)
+ {
+ ret = UNEXPECTED_BZIP_ERROR;
+ break;
+ }
+
+ int outlen = outbuf_size - strm.avail_out;
+ if (outlen)
+ {
+ if (fwrite(outbuf, outlen, 1, fp) != 1)
+ {
+ ret = WRITE_ERROR_EXTRACT;
+ break;
+ }
+ }
+
+ if (ret == BZ_STREAM_END)
+ {
+ ret = OK;
+ break;
+ }
}
- }
- BZ2_bzDecompressEnd(&strm);
- return ret;
+ BZ2_bzDecompressEnd(&strm);
+ return ret;
}
diff --git a/onlineupdate/source/update/updater/archivereader.h b/onlineupdate/source/update/updater/archivereader.h
index f045566b772b..9b7885dc0103 100644
--- a/onlineupdate/source/update/updater/archivereader.h
+++ b/onlineupdate/source/update/updater/archivereader.h
@@ -11,31 +11,34 @@
#include <onlineupdate/mar.h>
#ifdef _WIN32
- typedef WCHAR NS_tchar;
+typedef WCHAR NS_tchar;
#else
- typedef char NS_tchar;
+typedef char NS_tchar;
#endif
// This class provides an API to extract files from an update archive.
class ArchiveReader
{
public:
- ArchiveReader() : mArchive(nullptr) {}
- ~ArchiveReader() { Close(); }
+ ArchiveReader() : mArchive(nullptr) {}
+ ~ArchiveReader()
+ {
+ Close();
+ }
- int Open(const NS_tchar *path);
- int VerifySignature();
- int VerifyProductInformation(const char *MARChannelID,
- const char *appVersion);
- void Close();
+ int Open(const NS_tchar *path);
+ int VerifySignature();
+ int VerifyProductInformation(const char *MARChannelID,
+ const char *appVersion);
+ void Close();
- int ExtractFile(const char *item, const NS_tchar *destination);
- int ExtractFileToStream(const char *item, FILE *fp);
+ int ExtractFile(const char *item, const NS_tchar *destination);
+ int ExtractFileToStream(const char *item, FILE *fp);
private:
- int ExtractItemToStream(const MarItem *item, FILE *fp);
+ int ExtractItemToStream(const MarItem *item, FILE *fp);
- MarFile *mArchive;
+ MarFile *mArchive;
};
#endif // ArchiveReader_h__
diff --git a/onlineupdate/source/update/updater/bspatch.cxx b/onlineupdate/source/update/updater/bspatch.cxx
index 09a3c4354fcb..b39c50f92627 100644
--- a/onlineupdate/source/update/updater/bspatch.cxx
+++ b/onlineupdate/source/update/updater/bspatch.cxx
@@ -58,130 +58,140 @@
int
MBS_ReadHeader(FILE* file, MBSPatchHeader *header)
{
- size_t s = fread(header, 1, sizeof(MBSPatchHeader), file);
- if (s != sizeof(MBSPatchHeader))
- return READ_ERROR;
-
- header->slen = ntohl(header->slen);
- header->scrc32 = ntohl(header->scrc32);
- header->dlen = ntohl(header->dlen);
- header->cblen = ntohl(header->cblen);
- header->difflen = ntohl(header->difflen);
- header->extralen = ntohl(header->extralen);
-
- struct stat hs;
- s = fstat(fileno(file), &hs);
- if (s)
- return READ_ERROR;
-
- if (memcmp(header->tag, "MBDIFF10", 8) != 0)
- return UNEXPECTED_BSPATCH_ERROR;
-
- if (sizeof(MBSPatchHeader) +
- header->cblen +
- header->difflen +
- header->extralen != uint32_t(hs.st_size))
- return UNEXPECTED_BSPATCH_ERROR;
-
- return OK;
+ size_t s = fread(header, 1, sizeof(MBSPatchHeader), file);
+ if (s != sizeof(MBSPatchHeader))
+ return READ_ERROR;
+
+ header->slen = ntohl(header->slen);
+ header->scrc32 = ntohl(header->scrc32);
+ header->dlen = ntohl(header->dlen);
+ header->cblen = ntohl(header->cblen);
+ header->difflen = ntohl(header->difflen);
+ header->extralen = ntohl(header->extralen);
+
+ struct stat hs;
+ s = fstat(fileno(file), &hs);
+ if (s)
+ return READ_ERROR;
+
+ if (memcmp(header->tag, "MBDIFF10", 8) != 0)
+ return UNEXPECTED_BSPATCH_ERROR;
+
+ if (sizeof(MBSPatchHeader) +
+ header->cblen +
+ header->difflen +
+ header->extralen != uint32_t(hs.st_size))
+ return UNEXPECTED_BSPATCH_ERROR;
+
+ return OK;
}
int
MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
unsigned char *fbuffer, FILE* file)
{
- unsigned char *fbufend = fbuffer + header->slen;
-
- unsigned char *buf = (unsigned char*) malloc(header->cblen +
- header->difflen +
- header->extralen);
- if (!buf)
- return BSPATCH_MEM_ERROR;
-
- int rv = OK;
-
- size_t r = header->cblen + header->difflen + header->extralen;
- unsigned char *wb = buf;
- while (r) {
- const size_t count = (r > SSIZE_MAX) ? SSIZE_MAX : r;
- size_t c = fread(wb, 1, count, patchFile);
- if (c != count) {
- rv = READ_ERROR;
- goto end;
+ unsigned char *fbufend = fbuffer + header->slen;
+
+ unsigned char *buf = (unsigned char*) malloc(header->cblen +
+ header->difflen +
+ header->extralen);
+ if (!buf)
+ return BSPATCH_MEM_ERROR;
+
+ int rv = OK;
+
+ size_t r = header->cblen + header->difflen + header->extralen;
+ unsigned char *wb = buf;
+ while (r)
+ {
+ const size_t count = (r > SSIZE_MAX) ? SSIZE_MAX : r;
+ size_t c = fread(wb, 1, count, patchFile);
+ if (c != count)
+ {
+ rv = READ_ERROR;
+ goto end;
+ }
+
+ r -= c;
+ wb += c;
}
- r -= c;
- wb += c;
- }
+ {
+ MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf;
+ unsigned char *diffsrc = buf + header->cblen;
+ unsigned char *extrasrc = diffsrc + header->difflen;
- {
- MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf;
- unsigned char *diffsrc = buf + header->cblen;
- unsigned char *extrasrc = diffsrc + header->difflen;
+ MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc;
+ unsigned char *diffend = extrasrc;
+ unsigned char *extraend = extrasrc + header->extralen;
- MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc;
- unsigned char *diffend = extrasrc;
- unsigned char *extraend = extrasrc + header->extralen;
-
- do {
- ctrlsrc->x = ntohl(ctrlsrc->x);
- ctrlsrc->y = ntohl(ctrlsrc->y);
- ctrlsrc->z = ntohl(ctrlsrc->z);
+ do
+ {
+ ctrlsrc->x = ntohl(ctrlsrc->x);
+ ctrlsrc->y = ntohl(ctrlsrc->y);
+ ctrlsrc->z = ntohl(ctrlsrc->z);
#ifdef DEBUG_bsmedberg
- printf("Applying block:\n"
- " x: %u\n"
- " y: %u\n"
- " z: %i\n",
- ctrlsrc->x,
- ctrlsrc->y,
- ctrlsrc->z);
+ printf("Applying block:\n"
+ " x: %u\n"
+ " y: %u\n"
+ " z: %i\n",
+ ctrlsrc->x,
+ ctrlsrc->y,
+ ctrlsrc->z);
#endif
- /* Add x bytes from oldfile to x bytes from the diff block */
-
- if (fbuffer + ctrlsrc->x > fbufend ||
- diffsrc + ctrlsrc->x > diffend) {
- rv = UNEXPECTED_BSPATCH_ERROR;
- goto end;
- }
- for (uint32_t i = 0; i < ctrlsrc->x; ++i) {
- diffsrc[i] += fbuffer[i];
- }
- if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x) {
- rv = WRITE_ERROR_PATCH_FILE;
- goto end;
- }
- fbuffer += ctrlsrc->x;
- diffsrc += ctrlsrc->x;
-
- /* Copy y bytes from the extra block */
-
- if (extrasrc + ctrlsrc->y > extraend) {
- rv = UNEXPECTED_BSPATCH_ERROR;
- goto end;
- }
- if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y) {
- rv = WRITE_ERROR_PATCH_FILE;
- goto end;
- }
- extrasrc += ctrlsrc->y;
-
- /* "seek" forwards in oldfile by z bytes */
-
- if (fbuffer + ctrlsrc->z > fbufend) {
- rv = UNEXPECTED_BSPATCH_ERROR;
- goto end;
- }
- fbuffer += ctrlsrc->z;
-
- /* and on to the next control block */
-
- ++ctrlsrc;
- } while (ctrlsrc < ctrlend);
- }
+ /* Add x bytes from oldfile to x bytes from the diff block */
+
+ if (fbuffer + ctrlsrc->x > fbufend ||
+ diffsrc + ctrlsrc->x > diffend)
+ {
+ rv = UNEXPECTED_BSPATCH_ERROR;
+ goto end;
+ }
+ for (uint32_t i = 0; i < ctrlsrc->x; ++i)
+ {
+ diffsrc[i] += fbuffer[i];
+ }
+ if ((uint32_t) fwrite(diffsrc, 1, ctrlsrc->x, file) != ctrlsrc->x)
+ {
+ rv = WRITE_ERROR_PATCH_FILE;
+ goto end;
+ }
+ fbuffer += ctrlsrc->x;
+ diffsrc += ctrlsrc->x;
+
+ /* Copy y bytes from the extra block */
+
+ if (extrasrc + ctrlsrc->y > extraend)
+ {
+ rv = UNEXPECTED_BSPATCH_ERROR;
+ goto end;
+ }
+ if ((uint32_t) fwrite(extrasrc, 1, ctrlsrc->y, file) != ctrlsrc->y)
+ {
+ rv = WRITE_ERROR_PATCH_FILE;
+ goto end;
+ }
+ extrasrc += ctrlsrc->y;
+
+ /* "seek" forwards in oldfile by z bytes */
+
+ if (fbuffer + ctrlsrc->z > fbufend)
+ {
+ rv = UNEXPECTED_BSPATCH_ERROR;
+ goto end;
+ }
+ fbuffer += ctrlsrc->z;
+
+ /* and on to the next control block */
+
+ ++ctrlsrc;
+ }
+ while (ctrlsrc < ctrlend);
+ }
end:
- free(buf);
- return rv;
+ free(buf);
+ return rv;
}
diff --git a/onlineupdate/source/update/updater/bspatch.h b/onlineupdate/source/update/updater/bspatch.h
index 2b5fb338726f..ff1a8072964f 100644
--- a/onlineupdate/source/update/updater/bspatch.h
+++ b/onlineupdate/source/update/updater/bspatch.h
@@ -35,31 +35,32 @@
#include <stdint.h>
#include <stdio.h>
-typedef struct MBSPatchHeader_ {
- /* "MBDIFF10" */
- char tag[8];
+typedef struct MBSPatchHeader_
+{
+ /* "MBDIFF10" */
+ char tag[8];
- /* Length of the file to be patched */
- uint32_t slen;
+ /* Length of the file to be patched */
+ uint32_t slen;
- /* CRC32 of the file to be patched */
- uint32_t scrc32;
+ /* CRC32 of the file to be patched */
+ uint32_t scrc32;
- /* Length of the result file */
- uint32_t dlen;
+ /* Length of the result file */
+ uint32_t dlen;
- /* Length of the control block in bytes */
- uint32_t cblen;
+ /* Length of the control block in bytes */
+ uint32_t cblen;
- /* Length of the diff block in bytes */
- uint32_t difflen;
+ /* Length of the diff block in bytes */
+ uint32_t difflen;
- /* Length of the extra block in bytes */
- uint32_t extralen;
+ /* Length of the extra block in bytes */
+ uint32_t extralen;
- /* Control block (MBSPatchTriple[]) */
- /* Diff block (binary data) */
- /* Extra block (binary data) */
+ /* Control block (MBSPatchTriple[]) */
+ /* Diff block (binary data) */
+ /* Extra block (binary data) */
} MBSPatchHeader;
/**
@@ -84,10 +85,11 @@ int MBS_ReadHeader(FILE* file, MBSPatchHeader *header);
int MBS_ApplyPatch(const MBSPatchHeader *header, FILE* patchFile,
unsigned char *fbuffer, FILE* file);
-typedef struct MBSPatchTriple_ {
- uint32_t x; /* add x bytes from oldfile to x bytes from the diff block */
- uint32_t y; /* copy y bytes from the extra block */
- int32_t z; /* seek forwards in oldfile by z bytes */
+typedef struct MBSPatchTriple_
+{
+ uint32_t x; /* add x bytes from oldfile to x bytes from the diff block */
+ uint32_t y; /* copy y bytes from the extra block */
+ int32_t z; /* seek forwards in oldfile by z bytes */
} MBSPatchTriple;
#endif // bspatch_h__
diff --git a/onlineupdate/source/update/updater/loaddlls.cxx b/onlineupdate/source/update/updater/loaddlls.cxx
index 94a4222136b5..246d9f86bf79 100644
--- a/onlineupdate/source/update/updater/loaddlls.cxx
+++ b/onlineupdate/source/update/updater/loaddlls.cxx
@@ -15,95 +15,104 @@
// system directory.
struct AutoLoadSystemDependencies
{
- AutoLoadSystemDependencies()
- {
- // Remove the current directory from the search path for dynamically loaded
- // DLLs as a precaution. This call has no effect for delay load DLLs.
- SetDllDirectory(L"");
+ AutoLoadSystemDependencies()
+ {
+ // Remove the current directory from the search path for dynamically loaded
+ // DLLs as a precaution. This call has no effect for delay load DLLs.
+ SetDllDirectory(L"");
- HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
- if (module) {
- // SetDefaultDllDirectories is always available on Windows 8 and above. It
- // is also available on Windows Vista, Windows Server 2008, and
- // Windows 7 when MS KB2533623 has been applied.
- decltype(SetDefaultDllDirectories)* setDefaultDllDirectories =
- (decltype(SetDefaultDllDirectories)*) GetProcAddress(module, "SetDefaultDllDirectories");
- if (setDefaultDllDirectories) {
- setDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
- return;
- }
- }
+ HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
+ if (module)
+ {
+ // SetDefaultDllDirectories is always available on Windows 8 and above. It
+ // is also available on Windows Vista, Windows Server 2008, and
+ // Windows 7 when MS KB2533623 has been applied.
+ decltype(SetDefaultDllDirectories)* setDefaultDllDirectories =
+ (decltype(SetDefaultDllDirectories)*) GetProcAddress(module, "SetDefaultDllDirectories");
+ if (setDefaultDllDirectories)
+ {
+ setDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
+ return;
+ }
+ }
- // When SetDefaultDllDirectories is not available, fallback to preloading
- // dlls. The order that these are loaded does not matter since they are
- // loaded using the LOAD_WITH_ALTERED_SEARCH_PATH flag.
+ // When SetDefaultDllDirectories is not available, fallback to preloading
+ // dlls. The order that these are loaded does not matter since they are
+ // loaded using the LOAD_WITH_ALTERED_SEARCH_PATH flag.
#ifdef HAVE_64BIT_BUILD
- // DLLs for Firefox x64 on Windows 7 (x64).
- // Note: dwmapi.dll is preloaded since a crash will try to load it from the
- // application's directory.
- static LPCWSTR delayDLLs[] = { L"apphelp.dll",
- L"cryptbase.dll",
- L"cryptsp.dll",
- L"dwmapi.dll",
- L"mpr.dll",
- L"ntmarta.dll",
- L"profapi.dll",
- L"propsys.dll",
- L"sspicli.dll",
- L"wsock32.dll" };
+ // DLLs for Firefox x64 on Windows 7 (x64).
+ // Note: dwmapi.dll is preloaded since a crash will try to load it from the
+ // application's directory.
+ static LPCWSTR delayDLLs[] = { L"apphelp.dll",
+ L"cryptbase.dll",
+ L"cryptsp.dll",
+ L"dwmapi.dll",
+ L"mpr.dll",
+ L"ntmarta.dll",
+ L"profapi.dll",
+ L"propsys.dll",
+ L"sspicli.dll",
+ L"wsock32.dll"
+ };
#else
- // DLLs for Firefox x86 on Windows XP through Windows 7 (x86 and x64).
- // Note: dwmapi.dll is preloaded since a crash will try to load it from the
- // application's directory.
- static LPCWSTR delayDLLs[] = { L"apphelp.dll",
- L"crypt32.dll",
- L"cryptbase.dll",
- L"cryptsp.dll",
- L"dwmapi.dll",
- L"mpr.dll",
- L"msasn1.dll",
- L"ntmarta.dll",
- L"profapi.dll",
- L"propsys.dll",
- L"psapi.dll",
- L"secur32.dll",
- L"sspicli.dll",
- L"userenv.dll",
- L"uxtheme.dll",
- L"ws2_32.dll",
- L"ws2help.dll",
- L"wsock32.dll" };
+ // DLLs for Firefox x86 on Windows XP through Windows 7 (x86 and x64).
+ // Note: dwmapi.dll is preloaded since a crash will try to load it from the
+ // application's directory.
+ static LPCWSTR delayDLLs[] = { L"apphelp.dll",
+ L"crypt32.dll",
+ L"cryptbase.dll",
+ L"cryptsp.dll",
+ L"dwmapi.dll",
+ L"mpr.dll",
+ L"msasn1.dll",
+ L"ntmarta.dll",
+ L"profapi.dll",
+ L"propsys.dll",
+ L"psapi.dll",
+ L"secur32.dll",
+ L"sspicli.dll",
+ L"userenv.dll",
+ L"uxtheme.dll",
+ L"ws2_32.dll",
+ L"ws2help.dll",
+ L"wsock32.dll"
+ };
#endif
- WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' };
- // If GetSystemDirectory fails we accept that we'll load the DLLs from the
- // normal search path.
- GetSystemDirectoryW(systemDirectory, MAX_PATH + 1);
- size_t systemDirLen = wcslen(systemDirectory);
+ WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' };
+ // If GetSystemDirectory fails we accept that we'll load the DLLs from the
+ // normal search path.
+ GetSystemDirectoryW(systemDirectory, MAX_PATH + 1);
+ size_t systemDirLen = wcslen(systemDirectory);
- // Make the system directory path terminate with a slash
- if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) {
- systemDirectory[systemDirLen] = L'\\';
- ++systemDirLen;
- // No need to re-null terminate
- }
+ // Make the system directory path terminate with a slash
+ if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen)
+ {
+ systemDirectory[systemDirLen] = L'\\';
+ ++systemDirLen;
+ // No need to re-null terminate
+ }
- // For each known DLL ensure it is loaded from the system32 directory
- for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) {
- size_t fileLen = wcslen(delayDLLs[i]);
- wcsncpy(systemDirectory + systemDirLen, delayDLLs[i],
- MAX_PATH - systemDirLen);
- if (systemDirLen + fileLen <= MAX_PATH) {
- systemDirectory[systemDirLen + fileLen] = L'\0';
- } else {
- systemDirectory[MAX_PATH] = L'\0';
- }
- LPCWSTR fullModulePath = systemDirectory; // just for code readability
- // LOAD_WITH_ALTERED_SEARCH_PATH makes a dll look in its own directory for
- // dependencies and is only available on Win 7 and below.
- LoadLibraryExW(fullModulePath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
+ // For each known DLL ensure it is loaded from the system32 directory
+ for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i)
+ {
+ size_t fileLen = wcslen(delayDLLs[i]);
+ wcsncpy(systemDirectory + systemDirLen, delayDLLs[i],
+ MAX_PATH - systemDirLen);
+ if (systemDirLen + fileLen <= MAX_PATH)
+ {
+ systemDirectory[systemDirLen + fileLen] = L'\0';
+ }
+ else
+ {
+ systemDirectory[MAX_PATH] = L'\0';
+ }
+ LPCWSTR fullModulePath = systemDirectory; // just for code readability
+ // LOAD_WITH_ALTERED_SEARCH_PATH makes a dll look in its own directory for
+ // dependencies and is only available on Win 7 and below.
+ LoadLibraryExW(fullModulePath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
+ }
}
- }
} loadDLLs;
#endif
diff --git a/onlineupdate/source/update/updater/primaryCert.h b/onlineupdate/source/update/updater/primaryCert.h
index f161aa3816b1..e46af0b59814 100644
--- a/onlineupdate/source/update/updater/primaryCert.h
+++ b/onlineupdate/source/update/updater/primaryCert.h
@@ -1,3 +1,4 @@
-const uint8_t primaryCertData[] = {
+const uint8_t primaryCertData[] =
+{
0x30, 0x82, 0x02, 0xc3, 0x30, 0x82, 0x01, 0xab, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xa7, 0x67, 0xe2, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x33, 0x30, 0x30, 0x30, 0x33, 0x31, 0x30, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x33, 0x30, 0x30, 0x30, 0x33, 0x31, 0x30, 0x35, 0x5a, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0x63, 0x91, 0x44, 0xf6, 0xf1, 0xd7, 0x7f, 0xc9, 0x3d, 0xee, 0x39, 0x44, 0xba, 0xd5, 0x1b, 0x68, 0x10, 0xfd, 0x2e, 0xb3, 0xe9, 0x17, 0xd8, 0x78, 0x18, 0xff, 0xbb, 0x63, 0x6f, 0x21, 0xd9, 0xb3, 0x55, 0x83, 0xe2, 0x90, 0x18, 0xba, 0x1e, 0x3b, 0x57, 0xbb, 0x4a, 0xc7, 0x4a, 0x3b, 0x49, 0x14, 0x1b, 0xe0, 0xc5, 0x01, 0x8e, 0xb3, 0xfc, 0xe0, 0x31, 0x21, 0xea, 0x6b, 0xc6, 0x5f, 0x70, 0x3c, 0x1f, 0x40, 0x9e, 0x6f, 0xf1, 0x37, 0xa0, 0x74, 0xc5, 0x55, 0xc7, 0x4d, 0x9c, 0xdd, 0x6b, 0xb4, 0xd3, 0x17, 0x22, 0x9e, 0x27, 0xea, 0x57, 0x45, 0x58, 0x19, 0x39, 0x18, 0x42, 0x37, 0x94, 0x8d, 0x11, 0xa1, 0xa9, 0xcb, 0xdd, 0x45, 0x7e, 0x82, 0xbf, 0x93, 0x75, 0xcc, 0x8d, 0x95, 0x04, 0x74, 0xc0, 0x84, 0x2e, 0x7d, 0xbc, 0x56, 0x2d, 0xd1, 0x0e, 0x2e, 0xbf, 0x0e, 0x52, 0x22, 0x0c, 0x65, 0xb2, 0x7a, 0x12, 0x14, 0x27, 0x0b, 0xc9, 0x37, 0x30, 0x48, 0xbc, 0xf0, 0xb8, 0x6d, 0x6f, 0x38, 0xda, 0x98, 0xd0, 0x1c, 0x87, 0xfe, 0x69, 0xc4, 0xc7, 0x73, 0xed, 0x78, 0x01, 0xa5, 0xea, 0x48, 0x08, 0x28, 0xcc, 0x0e, 0x52, 0x20, 0x1f, 0x46, 0x42, 0x83, 0x2e, 0xa6, 0xfd, 0x30, 0xc6, 0x48, 0x55, 0x78, 0xff, 0xd6, 0xac, 0xdd, 0x61, 0xd3, 0xb9, 0xdb, 0x49, 0x6b, 0x93, 0x5a, 0x5b, 0x37, 0xf5, 0xcb, 0x09, 0x4a, 0x6c, 0xa3, 0x85, 0x1f, 0xeb, 0x33, 0x3f, 0xd0, 0xda, 0x55, 0xc3, 0xb2, 0x56, 0x7d, 0x13, 0x16, 0x23, 0x2b, 0x1c, 0x3f, 0xdd, 0x1a, 0xf9, 0x90, 0xf7, 0x43, 0x63, 0x80, 0xa5, 0x71, 0xce, 0x23, 0x56, 0x1b, 0xbf, 0x51, 0x3a, 0xfe, 0x6b, 0x48, 0xfd, 0x42, 0x50, 0xc0, 0x09, 0x30, 0x32, 0x27, 0x20, 0x0d, 0xda, 0x32, 0x02, 0x23, 0x92, 0x10, 0x85, 0xbf, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0xb2, 0x3f, 0x45, 0x2c, 0xf5, 0x75, 0xeb, 0x20, 0x2f, 0x76, 0x6f, 0x18, 0x06, 0x42, 0x20, 0x83, 0x39, 0x50, 0x64, 0x07, 0xbb, 0xb1, 0x38, 0x74, 0xbe, 0xbb, 0xf4, 0x25, 0x11, 0x72, 0xf9, 0x4a, 0xf0, 0x9a, 0x0b, 0xe7, 0x45, 0x22, 0x59, 0x04, 0x7b, 0xa4, 0xe8, 0x46, 0xe5, 0x67, 0xdb, 0x9a, 0x9e, 0x27, 0x94, 0x5e, 0x60, 0x8b, 0xf5, 0xb1, 0x3f, 0xf2, 0xab, 0x1c, 0x54, 0xc8, 0xbc, 0x2b, 0x83, 0xf9, 0xa7, 0x18, 0x02, 0xb6, 0x95, 0xfa, 0xde, 0x16, 0x49, 0xca, 0xbd, 0x2e, 0xfc, 0xb6, 0x36, 0x9a, 0x9a, 0x7a, 0x1f, 0xc8, 0x91, 0xce, 0x30, 0xe2, 0x89, 0x58, 0x05, 0xee, 0xf3, 0xd1, 0xed, 0x79, 0x45, 0x20, 0xbd, 0x84, 0x48, 0xb0, 0x56, 0x8e, 0x04, 0xc8, 0xb7, 0x7e, 0x46, 0x2a, 0x2e, 0xb3, 0xca, 0xc1, 0xb6, 0x0b, 0xd4, 0x31, 0x6e, 0x83, 0x13, 0xe9, 0xa5, 0xbd, 0x17, 0x0e, 0x47, 0x34, 0x99, 0xc9, 0x5b, 0xb2, 0x53, 0x73, 0x57, 0xeb, 0x30, 0x0d, 0x2d, 0xaa, 0x25, 0xbb, 0xab, 0xac, 0xe8, 0xda, 0xf0, 0xf1, 0xd7, 0x2d, 0x17, 0x70, 0x9e, 0x30, 0x3c, 0x38, 0x59, 0xbf, 0x40, 0x3f, 0x6e, 0xe4, 0x22, 0x84, 0x94, 0x59, 0xf6, 0x32, 0xc1, 0xcb, 0x9c, 0x56, 0x52, 0x04, 0xeb, 0xf6, 0xa3, 0x75, 0xf8, 0xcb, 0xed, 0xaf, 0x17, 0x57, 0x8f, 0x98, 0x56, 0xa4, 0x9d, 0x85, 0x16, 0xc8, 0xf7, 0xd6, 0x97, 0xed, 0xab, 0xe0, 0x4c, 0x1a, 0x44, 0x5c, 0x68, 0x30, 0x26, 0x40, 0x6b, 0xe9, 0x88, 0x6a, 0x37, 0x1e, 0xbf, 0x25, 0x38, 0x55, 0xd9, 0x84, 0x8d, 0x55, 0x08, 0xe6, 0x18, 0xc3, 0xd7, 0x96, 0xfa, 0xd0, 0x2f, 0x17, 0x9b, 0xb6, 0x40, 0xc3, 0x47, 0xb3, 0x30, 0x01, 0x59, 0xec, 0x7c, 0x8d, 0x7e, 0x0a, 0x0d, 0xeb, 0xc4, 0x3b, 0x06, 0x4e, 0x97, 0x41, 0x5e
};
diff --git a/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx b/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx
index f77d0af6338a..c855e548efe0 100644
--- a/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx
+++ b/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx
@@ -20,34 +20,35 @@ using namespace std;
int InitProgressUI(int *argc, char ***argv)
{
- return 0;
+ return 0;
}
int ShowProgressUI()
{
- LOG("Starting to apply update ...\n");
- return 0;
+ LOG("Starting to apply update ...\n");
+ return 0;
}
void QuitProgressUI()
{
- LOG("Finished applying update\n");
+ LOG("Finished applying update\n");
}
void UpdateProgressUI(float progress)
{
- assert(0.0f <= progress && progress <= 100.0f);
-
- static const size_t kProgressBarLength = 50;
- static size_t sLastNumBars;
- size_t numBars = size_t(float(kProgressBarLength) * progress / 100.0f);
- if (numBars == sLastNumBars) {
- return;
- }
- sLastNumBars = numBars;
-
- size_t numSpaces = kProgressBarLength - numBars;
- string bars(numBars, '=');
- string spaces(numSpaces, ' ');
- LOG("Progress [ %s%s ]\n", bars.c_str(), spaces.c_str());
+ assert(0.0f <= progress && progress <= 100.0f);
+
+ static const size_t kProgressBarLength = 50;
+ static size_t sLastNumBars;
+ size_t numBars = size_t(float(kProgressBarLength) * progress / 100.0f);
+ if (numBars == sLastNumBars)
+ {
+ return;
+ }
+ sLastNumBars = numBars;
+
+ size_t numSpaces = kProgressBarLength - numBars;
+ string bars(numBars, '=');
+ string spaces(numSpaces, ' ');
+ LOG("Progress [ %s%s ]\n", bars.c_str(), spaces.c_str());
}
diff --git a/onlineupdate/source/update/updater/progressui.h b/onlineupdate/source/update/updater/progressui.h
index 7392ac167bc4..455ae125180a 100644
--- a/onlineupdate/source/update/updater/progressui.h
+++ b/onlineupdate/source/update/updater/progressui.h
@@ -10,23 +10,23 @@
#include "updatedefines.h"
#if defined(_WIN32)
- typedef WCHAR NS_tchar;
- #define NS_main wmain
+typedef WCHAR NS_tchar;
+#define NS_main wmain
#else
- typedef char NS_tchar;
- #define NS_main main
+typedef char NS_tchar;
+#define NS_main main
#endif
// Called to perform any initialization of the widget toolkit
int InitProgressUI(int *argc, NS_tchar ***argv);
#if defined(_WIN32)
- // Called on the main thread at startup
- int ShowProgressUI(bool indeterminate = false, bool initUIStrings = true);
- int InitProgressUIStrings();
+// Called on the main thread at startup
+int ShowProgressUI(bool indeterminate = false, bool initUIStrings = true);
+int InitProgressUIStrings();
#else
- // Called on the main thread at startup
- int ShowProgressUI();
+// Called on the main thread at startup
+int ShowProgressUI();
#endif
// May be called from any thread
void QuitProgressUI();
diff --git a/onlineupdate/source/update/updater/progressui_gtk.cxx b/onlineupdate/source/update/updater/progressui_gtk.cxx
index 29ed219d9e35..fecd98a8730a 100644
--- a/onlineupdate/source/update/updater/progressui_gtk.cxx
+++ b/onlineupdate/source/update/updater/progressui_gtk.cxx
@@ -28,106 +28,106 @@ static const char *sProgramPath;
static gboolean
UpdateDialog(gpointer /*data*/)
{
- if (sQuit)
- {
- gtk_widget_hide(sWin);
- gtk_main_quit();
- }
+ if (sQuit)
+ {
+ gtk_widget_hide(sWin);
+ gtk_main_quit();
+ }
- float progress = sProgressVal;
+ float progress = sProgressVal;
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sProgressBar),
- progress / 100.0);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sProgressBar),
+ progress / 100.0);
- return TRUE;
+ return TRUE;
}
static gboolean
OnDeleteEvent(GtkWidget * /*widget*/, GdkEvent * /*event*/, gpointer /*user_data*/)
{
- return TRUE;
+ return TRUE;
}
int
InitProgressUI(int *pargc, char ***pargv)
{
- sProgramPath = (*pargv)[0];
+ sProgramPath = (*pargv)[0];
- sEnableUI = gtk_init_check(pargc, pargv);
- return 0;
+ sEnableUI = gtk_init_check(pargc, pargv);
+ return 0;
}
int
ShowProgressUI()
{
- if (!sEnableUI)
- return -1;
+ if (!sEnableUI)
+ return -1;
- // Only show the Progress UI if the process is taking a significant amount of
- // time where a significant amount of time is defined as .5 seconds after
- // ShowProgressUI is called sProgress is less than 70.
- usleep(500000);
+ // Only show the Progress UI if the process is taking a significant amount of
+ // time where a significant amount of time is defined as .5 seconds after
+ // ShowProgressUI is called sProgress is less than 70.
+ usleep(500000);
- if (sQuit || sProgressVal > 70.0f)
- return 0;
+ if (sQuit || sProgressVal > 70.0f)
+ return 0;
- char ini_path[PATH_MAX];
- snprintf(ini_path, sizeof(ini_path), "%s.ini", sProgramPath);
+ char ini_path[PATH_MAX];
+ snprintf(ini_path, sizeof(ini_path), "%s.ini", sProgramPath);
- StringTable strings;
- if (ReadStrings(ini_path, &strings) != OK)
- return -1;
+ StringTable strings;
+ if (ReadStrings(ini_path, &strings) != OK)
+ return -1;
- sWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- if (!sWin)
- return -1;
+ sWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ if (!sWin)
+ return -1;
- static GdkPixbuf *pixbuf;
- char icon_path[PATH_MAX];
- snprintf(icon_path, sizeof(icon_path), "%s.png", sProgramPath);
+ static GdkPixbuf *pixbuf;
+ char icon_path[PATH_MAX];
+ snprintf(icon_path, sizeof(icon_path), "%s.png", sProgramPath);
- g_signal_connect(G_OBJECT(sWin), "delete_event",
- G_CALLBACK(OnDeleteEvent), nullptr);
+ g_signal_connect(G_OBJECT(sWin), "delete_event",
+ G_CALLBACK(OnDeleteEvent), nullptr);
- gtk_window_set_title(GTK_WINDOW(sWin), strings.title);
- gtk_window_set_type_hint(GTK_WINDOW(sWin), GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_position(GTK_WINDOW(sWin), GTK_WIN_POS_CENTER_ALWAYS);
- gtk_window_set_resizable(GTK_WINDOW(sWin), FALSE);
- gtk_window_set_decorated(GTK_WINDOW(sWin), TRUE);
- gtk_window_set_deletable(GTK_WINDOW(sWin),FALSE);
- pixbuf = gdk_pixbuf_new_from_file (icon_path, nullptr);
- gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf);
- g_object_unref(pixbuf);
+ gtk_window_set_title(GTK_WINDOW(sWin), strings.title);
+ gtk_window_set_type_hint(GTK_WINDOW(sWin), GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_window_set_position(GTK_WINDOW(sWin), GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_window_set_resizable(GTK_WINDOW(sWin), FALSE);
+ gtk_window_set_decorated(GTK_WINDOW(sWin), TRUE);
+ gtk_window_set_deletable(GTK_WINDOW(sWin),FALSE);
+ pixbuf = gdk_pixbuf_new_from_file (icon_path, nullptr);
+ gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf);
+ g_object_unref(pixbuf);
- GtkWidget *vbox = gtk_vbox_new(TRUE, 6);
- sLabel = gtk_label_new(strings.info);
- gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f);
- sProgressBar = gtk_progress_bar_new();
+ GtkWidget *vbox = gtk_vbox_new(TRUE, 6);
+ sLabel = gtk_label_new(strings.info);
+ gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f);
+ sProgressBar = gtk_progress_bar_new();
- gtk_box_pack_start(GTK_BOX(vbox), sLabel, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), sProgressBar, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), sLabel, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), sProgressBar, TRUE, TRUE, 0);
- sTimerID = g_timeout_add(TIMER_INTERVAL, UpdateDialog, nullptr);
+ sTimerID = g_timeout_add(TIMER_INTERVAL, UpdateDialog, nullptr);
- gtk_container_set_border_width(GTK_CONTAINER(sWin), 10);
- gtk_container_add(GTK_CONTAINER(sWin), vbox);
- gtk_widget_show_all(sWin);
+ gtk_container_set_border_width(GTK_CONTAINER(sWin), 10);
+ gtk_container_add(GTK_CONTAINER(sWin), vbox);
+ gtk_widget_show_all(sWin);
- gtk_main();
- return 0;
+ gtk_main();
+ return 0;
}
// Called on a background thread
void
QuitProgressUI()
{
- sQuit = TRUE;
+ sQuit = TRUE;
}
// Called on a background thread
void
UpdateProgressUI(float progress)
{
- sProgressVal = progress; // 32-bit writes are atomic
+ sProgressVal = progress; // 32-bit writes are atomic
}
#endif // defined(UNIX) || defined(MACOSX)
diff --git a/onlineupdate/source/update/updater/progressui_null.cxx b/onlineupdate/source/update/updater/progressui_null.cxx
index c4cd6413ff1f..66d294a133a0 100644
--- a/onlineupdate/source/update/updater/progressui_null.cxx
+++ b/onlineupdate/source/update/updater/progressui_null.cxx
@@ -9,12 +9,12 @@
int InitProgressUI(int *argc, char ***argv)
{
- return 0;
+ return 0;
}
int ShowProgressUI()
{
- return 0;
+ return 0;
}
void QuitProgressUI()
diff --git a/onlineupdate/source/update/updater/progressui_win.cxx b/onlineupdate/source/update/updater/progressui_win.cxx
index b1f2b99a5eb2..b7ff90acbbbf 100644
--- a/onlineupdate/source/update/updater/progressui_win.cxx
+++ b/onlineupdate/source/update/updater/progressui_win.cxx
@@ -51,23 +51,23 @@ static StringTable sUIStrings;
static BOOL
GetStringsFile(WCHAR filename[MAX_PATH])
{
- if (!GetModuleFileNameW(nullptr, filename, MAX_PATH))
- return FALSE;
+ if (!GetModuleFileNameW(nullptr, filename, MAX_PATH))
+ return FALSE;
- WCHAR *dot = wcsrchr(filename, '.');
- if (!dot || wcsicmp(dot + 1, L"exe"))
- return FALSE;
+ WCHAR *dot = wcsrchr(filename, '.');
+ if (!dot || wcsicmp(dot + 1, L"exe"))
+ return FALSE;
- wcscpy(dot + 1, L"ini");
- return TRUE;
+ wcscpy(dot + 1, L"ini");
+ return TRUE;
}
static void
UpdateDialog(HWND hDlg)
{
- int pos = int(sProgress + 0.5f);
- HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
- SendMessage(hWndPro, PBM_SETPOS, pos, 0L);
+ int pos = int(sProgress + 0.5f);
+ HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
+ SendMessage(hWndPro, PBM_SETPOS, pos, 0L);
}
// The code in this function is from MSDN:
@@ -75,139 +75,145 @@ UpdateDialog(HWND hDlg)
static void
CenterDialog(HWND hDlg)
{
- RECT rc, rcOwner, rcDlg;
+ RECT rc, rcOwner, rcDlg;
- // Get the owner window and dialog box rectangles.
- HWND desktop = GetDesktopWindow();
+ // Get the owner window and dialog box rectangles.
+ HWND desktop = GetDesktopWindow();
- GetWindowRect(desktop, &rcOwner);
- GetWindowRect(hDlg, &rcDlg);
- CopyRect(&rc, &rcOwner);
+ GetWindowRect(desktop, &rcOwner);
+ GetWindowRect(hDlg, &rcDlg);
+ CopyRect(&rc, &rcOwner);
- // Offset the owner and dialog box rectangles so that
- // right and bottom values represent the width and
- // height, and then offset the owner again to discard
- // space taken up by the dialog box.
+ // Offset the owner and dialog box rectangles so that
+ // right and bottom values represent the width and
+ // height, and then offset the owner again to discard
+ // space taken up by the dialog box.
- OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
- OffsetRect(&rc, -rc.left, -rc.top);
- OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+ OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+ OffsetRect(&rc, -rc.left, -rc.top);
+ OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
- // The new position is the sum of half the remaining
- // space and the owner's original position.
+ // The new position is the sum of half the remaining
+ // space and the owner's original position.
- SetWindowPos(hDlg,
- HWND_TOP,
- rcOwner.left + (rc.right / 2),
- rcOwner.top + (rc.bottom / 2),
- 0, 0, // ignores size arguments
- SWP_NOSIZE);
+ SetWindowPos(hDlg,
+ HWND_TOP,
+ rcOwner.left + (rc.right / 2),
+ rcOwner.top + (rc.bottom / 2),
+ 0, 0, // ignores size arguments
+ SWP_NOSIZE);
}
static void
InitDialog(HWND hDlg)
{
- WCHAR szwTitle[MAX_TEXT_LEN];
- WCHAR szwInfo[MAX_TEXT_LEN];
-
- MultiByteToWideChar(CP_UTF8, 0, sUIStrings.title, -1, szwTitle,
- sizeof(szwTitle)/sizeof(szwTitle[0]));
- MultiByteToWideChar(CP_UTF8, 0, sUIStrings.info, -1, szwInfo,
- sizeof(szwInfo)/sizeof(szwInfo[0]));
-
- SetWindowTextW(hDlg, szwTitle);
- SetWindowTextW(GetDlgItem(hDlg, IDC_INFO), szwInfo);
-
- // Set dialog icon
- HICON hIcon = LoadIcon(GetModuleHandle(nullptr),
- MAKEINTRESOURCE(IDI_DIALOG));
- if (hIcon)
- SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
-
- HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
- SendMessage(hWndPro, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
- if (sIndeterminate) {
- LONG_PTR val = GetWindowLongPtr(hWndPro, GWL_STYLE);
- SetWindowLongPtr(hWndPro, GWL_STYLE, val|PBS_MARQUEE);
- SendMessage(hWndPro,(UINT) PBM_SETMARQUEE,(WPARAM) TRUE,(LPARAM)50 );
- }
+ WCHAR szwTitle[MAX_TEXT_LEN];
+ WCHAR szwInfo[MAX_TEXT_LEN];
+
+ MultiByteToWideChar(CP_UTF8, 0, sUIStrings.title, -1, szwTitle,
+ sizeof(szwTitle)/sizeof(szwTitle[0]));
+ MultiByteToWideChar(CP_UTF8, 0, sUIStrings.info, -1, szwInfo,
+ sizeof(szwInfo)/sizeof(szwInfo[0]));
+
+ SetWindowTextW(hDlg, szwTitle);
+ SetWindowTextW(GetDlgItem(hDlg, IDC_INFO), szwInfo);
+
+ // Set dialog icon
+ HICON hIcon = LoadIcon(GetModuleHandle(nullptr),
+ MAKEINTRESOURCE(IDI_DIALOG));
+ if (hIcon)
+ SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+
+ HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
+ SendMessage(hWndPro, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+ if (sIndeterminate)
+ {
+ LONG_PTR val = GetWindowLongPtr(hWndPro, GWL_STYLE);
+ SetWindowLongPtr(hWndPro, GWL_STYLE, val|PBS_MARQUEE);
+ SendMessage(hWndPro,(UINT) PBM_SETMARQUEE,(WPARAM) TRUE,(LPARAM)50 );
+ }
- // Resize the dialog to fit all of the text if necessary.
- RECT infoSize, textSize;
- HWND hWndInfo = GetDlgItem(hDlg, IDC_INFO);
-
- // Get the control's font for calculating the new size for the control
- HDC hDCInfo = GetDC(hWndInfo);
- HFONT hInfoFont;
- HFONT hOldFont = 0;
- hInfoFont = (HFONT)SendMessage(hWndInfo, WM_GETFONT, 0, 0);
-
- if (hInfoFont)
- hOldFont = (HFONT)SelectObject(hDCInfo, hInfoFont);
-
- // Measure the space needed for the text on a single line. DT_CALCRECT means
- // nothing is drawn.
- if (DrawText(hDCInfo, szwInfo, -1, &textSize,
- DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE)) {
- GetClientRect(hWndInfo, &infoSize);
- SIZE extra;
- // Calculate the additional space needed for the text by subtracting from
- // the rectangle returned by DrawText the existing client rectangle's width
- // and height.
- extra.cx = (textSize.right - textSize.left) -
- (infoSize.right - infoSize.left);
- extra.cy = (textSize.bottom - textSize.top) -
- (infoSize.bottom - infoSize.top);
- if (extra.cx < 0)
- extra.cx = 0;
- if (extra.cy < 0)
- extra.cy = 0;
- if ((extra.cx > 0) || (extra.cy > 0)) {
- RESIZE_WINDOW(hDlg, extra.cx, extra.cy);
- RESIZE_WINDOW(hWndInfo, extra.cx, extra.cy);
- RESIZE_WINDOW(hWndPro, extra.cx, 0);
- MOVE_WINDOW(hWndPro, 0, extra.cy);
+ // Resize the dialog to fit all of the text if necessary.
+ RECT infoSize, textSize;
+ HWND hWndInfo = GetDlgItem(hDlg, IDC_INFO);
+
+ // Get the control's font for calculating the new size for the control
+ HDC hDCInfo = GetDC(hWndInfo);
+ HFONT hInfoFont;
+ HFONT hOldFont = 0;
+ hInfoFont = (HFONT)SendMessage(hWndInfo, WM_GETFONT, 0, 0);
+
+ if (hInfoFont)
+ hOldFont = (HFONT)SelectObject(hDCInfo, hInfoFont);
+
+ // Measure the space needed for the text on a single line. DT_CALCRECT means
+ // nothing is drawn.
+ if (DrawText(hDCInfo, szwInfo, -1, &textSize,
+ DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE))
+ {
+ GetClientRect(hWndInfo, &infoSize);
+ SIZE extra;
+ // Calculate the additional space needed for the text by subtracting from
+ // the rectangle returned by DrawText the existing client rectangle's width
+ // and height.
+ extra.cx = (textSize.right - textSize.left) - \
+ (infoSize.right - infoSize.left);
+ extra.cy = (textSize.bottom - textSize.top) - \
+ (infoSize.bottom - infoSize.top);
+ if (extra.cx < 0)
+ extra.cx = 0;
+ if (extra.cy < 0)
+ extra.cy = 0;
+ if ((extra.cx > 0) || (extra.cy > 0))
+ {
+ RESIZE_WINDOW(hDlg, extra.cx, extra.cy);
+ RESIZE_WINDOW(hWndInfo, extra.cx, extra.cy);
+ RESIZE_WINDOW(hWndPro, extra.cx, 0);
+ MOVE_WINDOW(hWndPro, 0, extra.cy);
+ }
}
- }
- if (hOldFont)
- SelectObject(hDCInfo, hOldFont);
+ if (hOldFont)
+ SelectObject(hDCInfo, hOldFont);
- ReleaseDC(hWndInfo, hDCInfo);
+ ReleaseDC(hWndInfo, hDCInfo);
- CenterDialog(hDlg); // make dialog appear in the center of the screen
+ CenterDialog(hDlg); // make dialog appear in the center of the screen
- SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, nullptr);
+ SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, nullptr);
}
// Message handler for update dialog.
static LRESULT CALLBACK
DialogProc(HWND hDlg, UINT message, WPARAM /*wParam*/, LPARAM /*lParam*/)
{
- switch (message)
- {
- case WM_INITDIALOG:
- InitDialog(hDlg);
- return TRUE;
-
- case WM_TIMER:
- if (sQuit) {
- EndDialog(hDlg, 0);
- } else {
- UpdateDialog(hDlg);
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ InitDialog(hDlg);
+ return TRUE;
+
+ case WM_TIMER:
+ if (sQuit)
+ {
+ EndDialog(hDlg, 0);
+ }
+ else
+ {
+ UpdateDialog(hDlg);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ return TRUE;
}
- return TRUE;
-
- case WM_COMMAND:
- return TRUE;
- }
- return FALSE;
+ return FALSE;
}
int
InitProgressUI(int* /*argc*/, WCHAR*** /*argv*/)
{
- return 0;
+ return 0;
}
/**
@@ -216,109 +222,122 @@ InitProgressUI(int* /*argc*/, WCHAR*** /*argv*/)
* @return 0 on success, -1 on error
*/
int
-InitProgressUIStrings() {
- // If we do not have updater.ini, then we should not bother showing UI.
- WCHAR filename[MAX_PATH];
- if (!GetStringsFile(filename)) {
- return -1;
- }
+InitProgressUIStrings()
+{
+ // If we do not have updater.ini, then we should not bother showing UI.
+ WCHAR filename[MAX_PATH];
+ if (!GetStringsFile(filename))
+ {
+ return -1;
+ }
- if (_waccess(filename, 04)) {
- return -1;
- }
+ if (_waccess(filename, 04))
+ {
+ return -1;
+ }
- // If the updater.ini doesn't have the required strings, then we should not
- // bother showing UI.
- if (ReadStrings(filename, &sUIStrings) != OK) {
- return -1;
- }
+ // If the updater.ini doesn't have the required strings, then we should not
+ // bother showing UI.
+ if (ReadStrings(filename, &sUIStrings) != OK)
+ {
+ return -1;
+ }
- return 0;
+ return 0;
}
int
ShowProgressUI(bool indeterminate, bool initUIStrings)
{
- sIndeterminate = indeterminate;
- if (!indeterminate) {
- // Only show the Progress UI if the process is taking a significant amount of
- // time where a significant amount of time is defined as .5 seconds after
- // ShowProgressUI is called sProgress is less than 70.
- Sleep(500);
-
- if (sQuit || sProgress > 70.0f)
- return 0;
- }
-
- // Don't load the UI if there's an <exe_name>.Local directory for redirection.
- WCHAR appPath[MAX_PATH + 1] = { L'\0' };
- if (!GetModuleFileNameW(nullptr, appPath, MAX_PATH)) {
- return -1;
- }
+ sIndeterminate = indeterminate;
+ if (!indeterminate)
+ {
+ // Only show the Progress UI if the process is taking a significant amount of
+ // time where a significant amount of time is defined as .5 seconds after
+ // ShowProgressUI is called sProgress is less than 70.
+ Sleep(500);
+
+ if (sQuit || sProgress > 70.0f)
+ return 0;
+ }
- if (wcslen(appPath) + wcslen(L".Local") >= MAX_PATH) {
- return -1;
- }
+ // Don't load the UI if there's an <exe_name>.Local directory for redirection.
+ WCHAR appPath[MAX_PATH + 1] = { L'\0' };
+ if (!GetModuleFileNameW(nullptr, appPath, MAX_PATH))
+ {
+ return -1;
+ }
- wcscat(appPath, L".Local");
+ if (wcslen(appPath) + wcslen(L".Local") >= MAX_PATH)
+ {
+ return -1;
+ }
- if (!_waccess(appPath, 04)) {
- return -1;
- }
+ wcscat(appPath, L".Local");
- // Don't load the UI if the strings for the UI are not provided.
- if (initUIStrings && InitProgressUIStrings() == -1) {
- return -1;
- }
-
- if (!GetModuleFileNameW(nullptr, appPath, MAX_PATH)) {
- return -1;
- }
+ if (!_waccess(appPath, 04))
+ {
+ return -1;
+ }
- // Use an activation context that supports visual styles for the controls.
- ACTCTXW actx = {0};
- actx.cbSize = sizeof(ACTCTXW);
- actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
- actx.hModule = GetModuleHandle(NULL); // Use the embedded manifest
- // This is needed only for Win XP but doesn't cause a problem with other
- // versions of Windows.
- actx.lpSource = appPath;
- actx.lpResourceName = MAKEINTRESOURCE(IDR_COMCTL32_MANIFEST);
-
- HANDLE hactx = CreateActCtxW(&actx);
- ULONG_PTR actxCookie = NULL;
- if (hactx != INVALID_HANDLE_VALUE) {
- // Push the specified activation context to the top of the activation stack.
- ActivateActCtx(hactx, &actxCookie);
- }
+ // Don't load the UI if the strings for the UI are not provided.
+ if (initUIStrings && InitProgressUIStrings() == -1)
+ {
+ return -1;
+ }
- INITCOMMONCONTROLSEX icc = {
- sizeof(INITCOMMONCONTROLSEX),
- ICC_PROGRESS_CLASS
- };
- InitCommonControlsEx(&icc);
+ if (!GetModuleFileNameW(nullptr, appPath, MAX_PATH))
+ {
+ return -1;
+ }
- DialogBox(GetModuleHandle(nullptr),
- MAKEINTRESOURCE(IDD_DIALOG), nullptr,
- (DLGPROC) DialogProc);
+ // Use an activation context that supports visual styles for the controls.
+ ACTCTXW actx = {0};
+ actx.cbSize = sizeof(ACTCTXW);
+ actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
+ actx.hModule = GetModuleHandle(NULL); // Use the embedded manifest
+ // This is needed only for Win XP but doesn't cause a problem with other
+ // versions of Windows.
+ actx.lpSource = appPath;
+ actx.lpResourceName = MAKEINTRESOURCE(IDR_COMCTL32_MANIFEST);
+
+ HANDLE hactx = CreateActCtxW(&actx);
+ ULONG_PTR actxCookie = NULL;
+ if (hactx != INVALID_HANDLE_VALUE)
+ {
+ // Push the specified activation context to the top of the activation stack.
+ ActivateActCtx(hactx, &actxCookie);
+ }
- if (hactx != INVALID_HANDLE_VALUE) {
- // Deactivate the context now that the comctl32.dll is loaded.
- DeactivateActCtx(0, actxCookie);
- }
+ INITCOMMONCONTROLSEX icc =
+ {
+ sizeof(INITCOMMONCONTROLSEX),
+ ICC_PROGRESS_CLASS
+ };
+ InitCommonControlsEx(&icc);
+
+ DialogBox(GetModuleHandle(nullptr),
+ MAKEINTRESOURCE(IDD_DIALOG), nullptr,
+ (DLGPROC) DialogProc);
+
+ if (hactx != INVALID_HANDLE_VALUE)
+ {
+ // Deactivate the context now that the comctl32.dll is loaded.
+ DeactivateActCtx(0, actxCookie);
+ }
- return 0;
+ return 0;
}
void
QuitProgressUI()
{
- sQuit = TRUE;
+ sQuit = TRUE;
}
void
UpdateProgressUI(float progress)
{
- sProgress = progress; // 32-bit writes are atomic
+ sProgress = progress; // 32-bit writes are atomic
}
#endif // WNT
diff --git a/onlineupdate/source/update/updater/secondaryCert.h b/onlineupdate/source/update/updater/secondaryCert.h
index 7453f27135dc..66e684bd133b 100644
--- a/onlineupdate/source/update/updater/secondaryCert.h
+++ b/onlineupdate/source/update/updater/secondaryCert.h
@@ -1,3 +1,4 @@
-const uint8_t secondaryCertData[] = {
+const uint8_t secondaryCertData[] =
+{
0x30, 0x82, 0x02, 0xc3, 0x30, 0x82, 0x01, 0xab, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xa7, 0x67, 0xe2, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x33, 0x30, 0x30, 0x30, 0x33, 0x31, 0x30, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x33, 0x30, 0x30, 0x30, 0x33, 0x31, 0x30, 0x35, 0x5a, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0x63, 0x91, 0x44, 0xf6, 0xf1, 0xd7, 0x7f, 0xc9, 0x3d, 0xee, 0x39, 0x44, 0xba, 0xd5, 0x1b, 0x68, 0x10, 0xfd, 0x2e, 0xb3, 0xe9, 0x17, 0xd8, 0x78, 0x18, 0xff, 0xbb, 0x63, 0x6f, 0x21, 0xd9, 0xb3, 0x55, 0x83, 0xe2, 0x90, 0x18, 0xba, 0x1e, 0x3b, 0x57, 0xbb, 0x4a, 0xc7, 0x4a, 0x3b, 0x49, 0x14, 0x1b, 0xe0, 0xc5, 0x01, 0x8e, 0xb3, 0xfc, 0xe0, 0x31, 0x21, 0xea, 0x6b, 0xc6, 0x5f, 0x70, 0x3c, 0x1f, 0x40, 0x9e, 0x6f, 0xf1, 0x37, 0xa0, 0x74, 0xc5, 0x55, 0xc7, 0x4d, 0x9c, 0xdd, 0x6b, 0xb4, 0xd3, 0x17, 0x22, 0x9e, 0x27, 0xea, 0x57, 0x45, 0x58, 0x19, 0x39, 0x18, 0x42, 0x37, 0x94, 0x8d, 0x11, 0xa1, 0xa9, 0xcb, 0xdd, 0x45, 0x7e, 0x82, 0xbf, 0x93, 0x75, 0xcc, 0x8d, 0x95, 0x04, 0x74, 0xc0, 0x84, 0x2e, 0x7d, 0xbc, 0x56, 0x2d, 0xd1, 0x0e, 0x2e, 0xbf, 0x0e, 0x52, 0x22, 0x0c, 0x65, 0xb2, 0x7a, 0x12, 0x14, 0x27, 0x0b, 0xc9, 0x37, 0x30, 0x48, 0xbc, 0xf0, 0xb8, 0x6d, 0x6f, 0x38, 0xda, 0x98, 0xd0, 0x1c, 0x87, 0xfe, 0x69, 0xc4, 0xc7, 0x73, 0xed, 0x78, 0x01, 0xa5, 0xea, 0x48, 0x08, 0x28, 0xcc, 0x0e, 0x52, 0x20, 0x1f, 0x46, 0x42, 0x83, 0x2e, 0xa6, 0xfd, 0x30, 0xc6, 0x48, 0x55, 0x78, 0xff, 0xd6, 0xac, 0xdd, 0x61, 0xd3, 0xb9, 0xdb, 0x49, 0x6b, 0x93, 0x5a, 0x5b, 0x37, 0xf5, 0xcb, 0x09, 0x4a, 0x6c, 0xa3, 0x85, 0x1f, 0xeb, 0x33, 0x3f, 0xd0, 0xda, 0x55, 0xc3, 0xb2, 0x56, 0x7d, 0x13, 0x16, 0x23, 0x2b, 0x1c, 0x3f, 0xdd, 0x1a, 0xf9, 0x90, 0xf7, 0x43, 0x63, 0x80, 0xa5, 0x71, 0xce, 0x23, 0x56, 0x1b, 0xbf, 0x51, 0x3a, 0xfe, 0x6b, 0x48, 0xfd, 0x42, 0x50, 0xc0, 0x09, 0x30, 0x32, 0x27, 0x20, 0x0d, 0xda, 0x32, 0x02, 0x23, 0x92, 0x10, 0x85, 0xbf, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0xb2, 0x3f, 0x45, 0x2c, 0xf5, 0x75, 0xeb, 0x20, 0x2f, 0x76, 0x6f, 0x18, 0x06, 0x42, 0x20, 0x83, 0x39, 0x50, 0x64, 0x07, 0xbb, 0xb1, 0x38, 0x74, 0xbe, 0xbb, 0xf4, 0x25, 0x11, 0x72, 0xf9, 0x4a, 0xf0, 0x9a, 0x0b, 0xe7, 0x45, 0x22, 0x59, 0x04, 0x7b, 0xa4, 0xe8, 0x46, 0xe5, 0x67, 0xdb, 0x9a, 0x9e, 0x27, 0x94, 0x5e, 0x60, 0x8b, 0xf5, 0xb1, 0x3f, 0xf2, 0xab, 0x1c, 0x54, 0xc8, 0xbc, 0x2b, 0x83, 0xf9, 0xa7, 0x18, 0x02, 0xb6, 0x95, 0xfa, 0xde, 0x16, 0x49, 0xca, 0xbd, 0x2e, 0xfc, 0xb6, 0x36, 0x9a, 0x9a, 0x7a, 0x1f, 0xc8, 0x91, 0xce, 0x30, 0xe2, 0x89, 0x58, 0x05, 0xee, 0xf3, 0xd1, 0xed, 0x79, 0x45, 0x20, 0xbd, 0x84, 0x48, 0xb0, 0x56, 0x8e, 0x04, 0xc8, 0xb7, 0x7e, 0x46, 0x2a, 0x2e, 0xb3, 0xca, 0xc1, 0xb6, 0x0b, 0xd4, 0x31, 0x6e, 0x83, 0x13, 0xe9, 0xa5, 0xbd, 0x17, 0x0e, 0x47, 0x34, 0x99, 0xc9, 0x5b, 0xb2, 0x53, 0x73, 0x57, 0xeb, 0x30, 0x0d, 0x2d, 0xaa, 0x25, 0xbb, 0xab, 0xac, 0xe8, 0xda, 0xf0, 0xf1, 0xd7, 0x2d, 0x17, 0x70, 0x9e, 0x30, 0x3c, 0x38, 0x59, 0xbf, 0x40, 0x3f, 0x6e, 0xe4, 0x22, 0x84, 0x94, 0x59, 0xf6, 0x32, 0xc1, 0xcb, 0x9c, 0x56, 0x52, 0x04, 0xeb, 0xf6, 0xa3, 0x75, 0xf8, 0xcb, 0xed, 0xaf, 0x17, 0x57, 0x8f, 0x98, 0x56, 0xa4, 0x9d, 0x85, 0x16, 0xc8, 0xf7, 0xd6, 0x97, 0xed, 0xab, 0xe0, 0x4c, 0x1a, 0x44, 0x5c, 0x68, 0x30, 0x26, 0x40, 0x6b, 0xe9, 0x88, 0x6a, 0x37, 0x1e, 0xbf, 0x25, 0x38, 0x55, 0xd9, 0x84, 0x8d, 0x55, 0x08, 0xe6, 0x18, 0xc3, 0xd7, 0x96, 0xfa, 0xd0, 0x2f, 0x17, 0x9b, 0xb6, 0x40, 0xc3, 0x47, 0xb3, 0x30, 0x01, 0x59, 0xec, 0x7c, 0x8d, 0x7e, 0x0a, 0x0d, 0xeb, 0xc4, 0x3b, 0x06, 0x4e, 0x97, 0x41, 0x5e
};
diff --git a/onlineupdate/source/update/updater/updater.cxx b/onlineupdate/source/update/updater/updater.cxx
index 3a44d2bb0fa8..18cf8b2cc966 100644
--- a/onlineupdate/source/update/updater/updater.cxx
+++ b/onlineupdate/source/update/updater/updater.cxx
@@ -125,8 +125,8 @@ struct UpdateServerThreadArgs
#endif
BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra);
BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer,
- LPCWSTR siblingFilePath,
- LPCWSTR newFileName);
+ LPCWSTR siblingFilePath,
+ LPCWSTR newFileName);
#include "updatehelper.h"
// Closes the handle if valid and if the updater is elevated returns with the
@@ -177,26 +177,31 @@ class AutoFile
{
public:
explicit AutoFile(FILE* file = nullptr)
- : mFile(file) {
- }
+ : mFile(file)
+ {
+ }
- ~AutoFile() {
+ ~AutoFile()
+ {
if (mFile != nullptr)
fclose(mFile);
}
- AutoFile &operator=(FILE* file) {
+ AutoFile &operator=(FILE* file)
+ {
if (mFile != 0)
fclose(mFile);
mFile = file;
return *this;
}
- operator FILE*() {
+ operator FILE*()
+ {
return mFile;
}
- FILE* get() {
+ FILE* get()
+ {
return mFile;
}
@@ -204,7 +209,8 @@ private:
FILE* mFile;
};
-struct MARChannelStringTable {
+struct MARChannelStringTable
+{
MARChannelStringTable()
{
MARChannelID[0] = '\0';
@@ -239,7 +245,8 @@ static const NS_tchar kQuote[] = NS_T("\"");
static NS_tchar*
mstrtok(const NS_tchar *delims, NS_tchar **str)
{
- if (!*str || !**str) {
+ if (!*str || !**str)
+ {
*str = nullptr;
return nullptr;
}
@@ -247,31 +254,40 @@ mstrtok(const NS_tchar *delims, NS_tchar **str)
// skip leading "whitespace"
NS_tchar *ret = *str;
const NS_tchar *d;
- do {
- for (d = delims; *d != NS_T('\0'); ++d) {
- if (*ret == *d) {
+ do
+ {
+ for (d = delims; *d != NS_T('\0'); ++d)
+ {
+ if (*ret == *d)
+ {
++ret;
break;
}
}
- } while (*d);
+ }
+ while (*d);
- if (!*ret) {
+ if (!*ret)
+ {
*str = ret;
return nullptr;
}
NS_tchar *i = ret;
- do {
- for (d = delims; *d != NS_T('\0'); ++d) {
- if (*i == *d) {
+ do
+ {
+ for (d = delims; *d != NS_T('\0'); ++d)
+ {
+ if (*i == *d)
+ {
*i = NS_T('\0');
*str = ++i;
return ret;
}
}
++i;
- } while (*i);
+ }
+ while (*i);
*str = nullptr;
return ret;
@@ -300,7 +316,8 @@ get_full_path(const NS_tchar *relpath)
size_t lendestpath = NS_tstrlen(destpath);
size_t lenrelpath = NS_tstrlen(relpath);
NS_tchar *s = new NS_tchar[lendestpath + lenrelpath + 2];
- if (!s) {
+ if (!s)
+ {
return nullptr;
}
@@ -330,9 +347,11 @@ get_relative_path(const NS_tchar *fullpath)
{
// If the path isn't absolute, just return it as-is.
#ifdef _WIN32
- if (fullpath[1] != ':' && fullpath[2] != '\\') {
+ if (fullpath[1] != ':' && fullpath[2] != '\\')
+ {
#else
- if (fullpath[0] != '/') {
+ if (fullpath[0] != '/')
+ {
#endif
return fullpath;
}
@@ -340,7 +359,8 @@ get_relative_path(const NS_tchar *fullpath)
NS_tchar *prefix = sStagedUpdate ? gWorkingDirPath : gInstallDirPath;
// If the path isn't long enough to be absolute, return it as-is.
- if (NS_tstrlen(fullpath) <= NS_tstrlen(prefix)) {
+ if (NS_tstrlen(fullpath) <= NS_tstrlen(prefix))
+ {
return fullpath;
}
@@ -361,30 +381,35 @@ static NS_tchar*
get_valid_path(NS_tchar **line, bool isdir = false)
{
NS_tchar *path = mstrtok(kQuote, line);
- if (!path) {
+ if (!path)
+ {
LOG(("get_valid_path: unable to determine path: " LOG_S, line));
return nullptr;
}
// All paths must be relative from the current working directory
- if (path[0] == NS_T('/')) {
+ if (path[0] == NS_T('/'))
+ {
LOG(("get_valid_path: path must be relative: " LOG_S, path));
return nullptr;
}
#ifdef _WIN32
// All paths must be relative from the current working directory
- if (path[0] == NS_T('\\') || path[1] == NS_T(':')) {
+ if (path[0] == NS_T('\\') || path[1] == NS_T(':'))
+ {
LOG(("get_valid_path: path must be relative: " LOG_S, path));
return nullptr;
}
#endif
- if (isdir) {
+ if (isdir)
+ {
// Directory paths must have a trailing forward slash.
- if (path[NS_tstrlen(path) - 1] != NS_T('/')) {
+ if (path[NS_tstrlen(path) - 1] != NS_T('/'))
+ {
LOG(("get_valid_path: directory paths must have a trailing forward " \
- "slash: " LOG_S, path));
+ "slash: " LOG_S, path));
return nullptr;
}
@@ -394,7 +419,8 @@ get_valid_path(NS_tchar **line, bool isdir = false)
}
// Don't allow relative paths that resolve to a parent directory.
- if (NS_tstrstr(path, NS_T("..")) != nullptr) {
+ if (NS_tstrstr(path, NS_T("..")) != nullptr)
+ {
LOG(("get_valid_path: paths must not contain '..': " LOG_S, path));
return nullptr;
}
@@ -431,7 +457,8 @@ static void ensure_write_permissions(const NS_tchar *path)
(void) _wchmod(path, _S_IREAD | _S_IWRITE);
#else
struct stat fs;
- if (!stat(path, &fs) && !(fs.st_mode & S_IWUSR)) {
+ if (!stat(path, &fs) && !(fs.st_mode & S_IWUSR))
+ {
(void)chmod(path, fs.st_mode | S_IWUSR);
}
#endif
@@ -443,23 +470,25 @@ static int ensure_remove(const NS_tchar *path)
int rv = NS_tremove(path);
if (rv)
LOG(("ensure_remove: failed to remove file: " LOG_S ", rv: %d, err: %d",
- path, rv, errno));
+ path, rv, errno));
return rv;
}
// Remove the directory pointed to by path and all of its files and sub-directories.
static int ensure_remove_recursive(const NS_tchar *path,
- bool continueEnumOnFailure = false)
+ bool continueEnumOnFailure = false)
{
// We use lstat rather than stat here so that we can successfully remove
// symlinks.
struct NS_tstat_t sInfo;
int rv = NS_tlstat(path, &sInfo);
- if (rv) {
+ if (rv)
+ {
// This error is benign
return rv;
}
- if (!S_ISDIR(sInfo.st_mode)) {
+ if (!S_ISDIR(sInfo.st_mode))
+ {
return ensure_remove(path);
}
@@ -467,20 +496,24 @@ static int ensure_remove_recursive(const NS_tchar *path,
NS_tdirent *entry;
dir = NS_topendir(path);
- if (!dir) {
+ if (!dir)
+ {
LOG(("ensure_remove_recursive: unable to open directory: " LOG_S
- ", rv: %d, err: %d", path, rv, errno));
+ ", rv: %d, err: %d", path, rv, errno));
return rv;
}
- while ((entry = NS_treaddir(dir)) != 0) {
+ while ((entry = NS_treaddir(dir)) != 0)
+ {
if (NS_tstrcmp(entry->d_name, NS_T(".")) &&
- NS_tstrcmp(entry->d_name, NS_T(".."))) {
+ NS_tstrcmp(entry->d_name, NS_T("..")))
+ {
NS_tchar childPath[MAXPATHLEN];
NS_tsnprintf(childPath, sizeof(childPath)/sizeof(childPath[0]),
- NS_T("%s/%s"), path, entry->d_name);
+ NS_T("%s/%s"), path, entry->d_name);
rv = ensure_remove_recursive(childPath);
- if (rv && !continueEnumOnFailure) {
+ if (rv && !continueEnumOnFailure)
+ {
break;
}
}
@@ -488,12 +521,14 @@ static int ensure_remove_recursive(const NS_tchar *path,
NS_tclosedir(dir);
- if (rv == OK) {
+ if (rv == OK)
+ {
ensure_write_permissions(path);
rv = NS_trmdir(path);
- if (rv) {
+ if (rv)
+ {
LOG(("ensure_remove_recursive: unable to remove directory: " LOG_S
- ", rv: %d, err: %d", path, rv, errno));
+ ", rv: %d, err: %d", path, rv, errno));
}
}
return rv;
@@ -524,20 +559,25 @@ static FILE* ensure_open(const NS_tchar *path, const NS_tchar *flags, unsigned i
{
ensure_write_permissions(path);
FILE* f = NS_tfopen(path, flags);
- if (is_read_only(flags)) {
+ if (is_read_only(flags))
+ {
// Don't attempt to modify the file permissions if the file is being opened
// in read-only mode.
return f;
}
- if (NS_tchmod(path, options) != 0) {
- if (f != nullptr) {
+ if (NS_tchmod(path, options) != 0)
+ {
+ if (f != nullptr)
+ {
fclose(f);
}
return nullptr;
}
struct NS_tstat_t ss;
- if (NS_tstat(path, &ss) != 0 || ss.st_mode != options) {
- if (f != nullptr) {
+ if (NS_tstat(path, &ss) != 0 || ss.st_mode != options)
+ {
+ if (f != nullptr)
+ {
fclose(f);
}
return nullptr;
@@ -551,18 +591,23 @@ static int ensure_parent_dir(const NS_tchar *path)
int rv = OK;
NS_tchar *slash = (NS_tchar *) NS_tstrrchr(path, NS_T('/'));
- if (slash) {
+ if (slash)
+ {
*slash = NS_T('\0');
rv = ensure_parent_dir(path);
// Only attempt to create the directory if we're not at the root
- if (rv == OK && *path) {
+ if (rv == OK && *path)
+ {
rv = NS_tmkdir(path, 0755);
// If the directory already exists, then ignore the error.
- if (rv < 0 && errno != EEXIST) {
+ if (rv < 0 && errno != EEXIST)
+ {
LOG(("ensure_parent_dir: failed to create directory: " LOG_S ", " \
- "err: %d", path, errno));
+ "err: %d", path, errno));
rv = WRITE_ERROR;
- } else {
+ }
+ else
+ {
rv = OK;
}
}
@@ -577,15 +622,17 @@ static int ensure_copy_symlink(const NS_tchar *path, const NS_tchar *dest)
// Copy symlinks by creating a new symlink to the same target
NS_tchar target[MAXPATHLEN + 1] = {NS_T('\0')};
int rv = readlink(path, target, MAXPATHLEN);
- if (rv == -1) {
+ if (rv == -1)
+ {
LOG(("ensure_copy_symlink: failed to read the link: " LOG_S ", err: %d",
- path, errno));
+ path, errno));
return READ_ERROR;
}
rv = symlink(target, dest);
- if (rv == -1) {
+ if (rv == -1)
+ {
LOG(("ensure_copy_symlink: failed to create the new link: " LOG_S ", target: " LOG_S " err: %d",
- dest, target, errno));
+ dest, target, errno));
return READ_ERROR;
}
return 0;
@@ -603,7 +650,8 @@ static int ensure_copy_symlink(const NS_tchar *path, const NS_tchar *dest)
static int
create_hard_link(const NS_tchar *srcFilename, const NS_tchar *destFilename)
{
- if (link(srcFilename, destFilename) < 0) {
+ if (link(srcFilename, destFilename) < 0)
+ {
LOG(("link(%s, %s) failed errno = %d", srcFilename, destFilename, errno));
return WRITE_ERROR;
}
@@ -617,30 +665,35 @@ static int ensure_copy(const NS_tchar *path, const NS_tchar *dest)
#ifdef _WIN32
// Fast path for Windows
bool result = CopyFileW(path, dest, false);
- if (!result) {
+ if (!result)
+ {
LOG(("ensure_copy: failed to copy the file " LOG_S " over to " LOG_S ", lasterr: %x",
- path, dest, GetLastError()));
+ path, dest, GetLastError()));
return WRITE_ERROR_FILE_COPY;
}
return OK;
#else
struct NS_tstat_t ss;
int rv = NS_tlstat(path, &ss);
- if (rv) {
+ if (rv)
+ {
LOG(("ensure_copy: failed to read file status info: " LOG_S ", err: %d",
- path, errno));
+ path, errno));
return READ_ERROR;
}
#ifdef UNIX
- if (S_ISLNK(ss.st_mode)) {
+ if (S_ISLNK(ss.st_mode))
+ {
return ensure_copy_symlink(path, dest);
}
#endif
#if MAYBE_USE_HARD_LINKS
- if (sUseHardLinks) {
- if (!create_hard_link(path, dest)) {
+ if (sUseHardLinks)
+ {
+ if (!create_hard_link(path, dest))
+ {
return OK;
}
// Since we failed to create the hard link, fall through and copy the file.
@@ -649,15 +702,17 @@ static int ensure_copy(const NS_tchar *path, const NS_tchar *dest)
#endif
AutoFile infile(ensure_open(path, NS_T("rb"), ss.st_mode));
- if (!infile) {
+ if (!infile)
+ {
LOG(("ensure_copy: failed to open the file for reading: " LOG_S ", err: %d",
- path, errno));
+ path, errno));
return READ_ERROR;
}
AutoFile outfile(ensure_open(dest, NS_T("wb"), ss.st_mode));
- if (!outfile) {
+ if (!outfile)
+ {
LOG(("ensure_copy: failed to open the file for writing: " LOG_S ", err: %d",
- dest, errno));
+ dest, errno));
return WRITE_ERROR;
}
@@ -669,22 +724,26 @@ static int ensure_copy(const NS_tchar *path, const NS_tchar *dest)
if (!buffer)
return UPDATER_MEM_ERROR;
- while (!feof(infile.get())) {
+ while (!feof(infile.get()))
+ {
size_t read = fread(buffer, 1, blockSize, infile);
- if (ferror(infile.get())) {
+ if (ferror(infile.get()))
+ {
LOG(("ensure_copy: failed to read the file: " LOG_S ", err: %d",
- path, errno));
+ path, errno));
free(buffer);
return READ_ERROR;
}
size_t written = 0;
- while (written < read) {
+ while (written < read)
+ {
size_t chunkWritten = fwrite(buffer, 1, read - written, outfile);
- if (chunkWritten <= 0) {
+ if (chunkWritten <= 0)
+ {
LOG(("ensure_copy: failed to write the file: " LOG_S ", err: %d",
- dest, errno));
+ dest, errno));
free(buffer);
return WRITE_ERROR_FILE_COPY;
}
@@ -701,16 +760,21 @@ static int ensure_copy(const NS_tchar *path, const NS_tchar *dest)
}
template <unsigned N>
-struct copy_recursive_skiplist {
+struct copy_recursive_skiplist
+{
NS_tchar paths[N][MAXPATHLEN];
- void append(unsigned index, const NS_tchar *path, const NS_tchar *suffix) {
+ void append(unsigned index, const NS_tchar *path, const NS_tchar *suffix)
+ {
NS_tsnprintf(paths[index], MAXPATHLEN, NS_T("%s/%s"), path, suffix);
}
- bool find(const NS_tchar *path) {
- for (int i = 0; i < static_cast<int>(N); ++i) {
- if (!NS_tstricmp(paths[i], path)) {
+ bool find(const NS_tchar *path)
+ {
+ for (int i = 0; i < static_cast<int>(N); ++i)
+ {
+ if (!NS_tstricmp(paths[i], path))
+ {
return true;
}
}
@@ -722,30 +786,34 @@ struct copy_recursive_skiplist {
// The path names in the skiplist will be skipped and will not be copied.
template <unsigned N>
static int ensure_copy_recursive(const NS_tchar *path, const NS_tchar *dest,
- copy_recursive_skiplist<N>& skiplist)
+ copy_recursive_skiplist<N>& skiplist)
{
struct NS_tstat_t sInfo;
int rv = NS_tlstat(path, &sInfo);
- if (rv) {
+ if (rv)
+ {
LOG(("ensure_copy_recursive: path doesn't exist: " LOG_S ", rv: %d, err: %d",
- path, rv, errno));
+ path, rv, errno));
return READ_ERROR;
}
#ifdef UNIX
- if (S_ISLNK(sInfo.st_mode)) {
+ if (S_ISLNK(sInfo.st_mode))
+ {
return ensure_copy_symlink(path, dest);
}
#endif
- if (!S_ISDIR(sInfo.st_mode)) {
+ if (!S_ISDIR(sInfo.st_mode))
+ {
return ensure_copy(path, dest);
}
rv = NS_tmkdir(dest, sInfo.st_mode);
- if (rv < 0 && errno != EEXIST) {
+ if (rv < 0 && errno != EEXIST)
+ {
LOG(("ensure_copy_recursive: could not create destination directory: " LOG_S ", rv: %d, err: %d",
- path, rv, errno));
+ path, rv, errno));
return WRITE_ERROR;
}
@@ -753,26 +821,31 @@ static int ensure_copy_recursive(const NS_tchar *path, const NS_tchar *dest,
NS_tdirent *entry;
dir = NS_topendir(path);
- if (!dir) {
+ if (!dir)
+ {
LOG(("ensure_copy_recursive: path is not a directory: " LOG_S ", rv: %d, err: %d",
- path, rv, errno));
+ path, rv, errno));
return READ_ERROR;
}
- while ((entry = NS_treaddir(dir)) != 0) {
+ while ((entry = NS_treaddir(dir)) != 0)
+ {
if (NS_tstrcmp(entry->d_name, NS_T(".")) &&
- NS_tstrcmp(entry->d_name, NS_T(".."))) {
+ NS_tstrcmp(entry->d_name, NS_T("..")))
+ {
NS_tchar childPath[MAXPATHLEN];
NS_tsnprintf(childPath, sizeof(childPath)/sizeof(childPath[0]),
- NS_T("%s/%s"), path, entry->d_name);
- if (skiplist.find(childPath)) {
+ NS_T("%s/%s"), path, entry->d_name);
+ if (skiplist.find(childPath))
+ {
continue;
}
NS_tchar childPathDest[MAXPATHLEN];
NS_tsnprintf(childPathDest, sizeof(childPathDest)/sizeof(childPathDest[0]),
- NS_T("%s/%s"), dest, entry->d_name);
+ NS_T("%s/%s"), dest, entry->d_name);
rv = ensure_copy_recursive(childPath, childPathDest, skiplist);
- if (rv) {
+ if (rv)
+ {
break;
}
}
@@ -784,7 +857,7 @@ static int ensure_copy_recursive(const NS_tchar *path, const NS_tchar *dest,
// Renames the specified file to the new file specified. If the destination file
// exists it is removed.
static int rename_file(const NS_tchar *spath, const NS_tchar *dpath,
- bool allowDirs = false)
+ bool allowDirs = false)
{
int rv = ensure_parent_dir(dpath);
if (rv)
@@ -792,33 +865,41 @@ static int rename_file(const NS_tchar *spath, const NS_tchar *dpath,
struct NS_tstat_t spathInfo;
rv = NS_tstat(spath, &spathInfo);
- if (rv) {
+ if (rv)
+ {
LOG(("rename_file: failed to read file status info: " LOG_S ", " \
- "err: %d", spath, errno));
+ "err: %d", spath, errno));
return READ_ERROR;
}
- if (!S_ISREG(spathInfo.st_mode)) {
- if (allowDirs && !S_ISDIR(spathInfo.st_mode)) {
+ if (!S_ISREG(spathInfo.st_mode))
+ {
+ if (allowDirs && !S_ISDIR(spathInfo.st_mode))
+ {
LOG(("rename_file: path present, but not a file: " LOG_S ", err: %d",
- spath, errno));
+ spath, errno));
return RENAME_ERROR_EXPECTED_FILE;
- } else {
+ }
+ else
+ {
LOG(("rename_file: proceeding to rename the directory"));
}
}
- if (!NS_taccess(dpath, F_OK)) {
- if (ensure_remove(dpath)) {
+ if (!NS_taccess(dpath, F_OK))
+ {
+ if (ensure_remove(dpath))
+ {
LOG(("rename_file: destination file exists and could not be " \
- "removed: " LOG_S, dpath));
+ "removed: " LOG_S, dpath));
return WRITE_ERROR_DELETE_FILE;
}
}
- if (NS_trename(spath, dpath) != 0) {
+ if (NS_trename(spath, dpath) != 0)
+ {
LOG(("rename_file: failed to rename file - src: " LOG_S ", " \
- "dst:" LOG_S ", err: %d", spath, dpath, errno));
+ "dst:" LOG_S ", err: %d", spath, dpath, errno));
return WRITE_ERROR;
}
@@ -833,22 +914,27 @@ static int remove_recursive_on_reboot(const NS_tchar *path, const NS_tchar *dele
{
struct NS_tstat_t sInfo;
int rv = NS_tlstat(path, &sInfo);
- if (rv) {
+ if (rv)
+ {
// This error is benign
return rv;
}
- if (!S_ISDIR(sInfo.st_mode)) {
+ if (!S_ISDIR(sInfo.st_mode))
+ {
NS_tchar tmpDeleteFile[MAXPATHLEN];
GetTempFileNameW(deleteDir, L"rep", 0, tmpDeleteFile);
NS_tremove(tmpDeleteFile);
rv = rename_file(path, tmpDeleteFile, false);
- if (MoveFileEx(rv ? path : tmpDeleteFile, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+ if (MoveFileEx(rv ? path : tmpDeleteFile, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT))
+ {
LOG(("remove_recursive_on_reboot: file will be removed on OS reboot: "
- LOG_S, rv ? path : tmpDeleteFile));
- } else {
+ LOG_S, rv ? path : tmpDeleteFile));
+ }
+ else
+ {
LOG(("remove_recursive_on_reboot: failed to schedule OS reboot removal of "
- "file: " LOG_S, rv ? path : tmpDeleteFile));
+ "file: " LOG_S, rv ? path : tmpDeleteFile));
}
return rv;
}
@@ -857,19 +943,22 @@ static int remove_recursive_on_reboot(const NS_tchar *path, const NS_tchar *dele
NS_tdirent *entry;
dir = NS_topendir(path);
- if (!dir) {
+ if (!dir)
+ {
LOG(("remove_recursive_on_reboot: unable to open directory: " LOG_S
- ", rv: %d, err: %d",
- path, rv, errno));
+ ", rv: %d, err: %d",
+ path, rv, errno));
return rv;
}
- while ((entry = NS_treaddir(dir)) != 0) {
+ while ((entry = NS_treaddir(dir)) != 0)
+ {
if (NS_tstrcmp(entry->d_name, NS_T(".")) &&
- NS_tstrcmp(entry->d_name, NS_T(".."))) {
+ NS_tstrcmp(entry->d_name, NS_T("..")))
+ {
NS_tchar childPath[MAXPATHLEN];
NS_tsnprintf(childPath, sizeof(childPath)/sizeof(childPath[0]),
- NS_T("%s/%s"), path, entry->d_name);
+ NS_T("%s/%s"), path, entry->d_name);
// There is no need to check the return value of this call since this
// function is only called after an update is successful and there is not
// much that can be done to recover if it isn't successful. There is also
@@ -880,12 +969,14 @@ static int remove_recursive_on_reboot(const NS_tchar *path, const NS_tchar *dele
NS_tclosedir(dir);
- if (rv == OK) {
+ if (rv == OK)
+ {
ensure_write_permissions(path);
rv = NS_trmdir(path);
- if (rv) {
+ if (rv)
+ {
LOG(("remove_recursive_on_reboot: unable to remove directory: " LOG_S
- ", rv: %d, err: %d", path, rv, errno));
+ ", rv: %d, err: %d", path, rv, errno));
}
}
return rv;
@@ -899,7 +990,7 @@ static int backup_create(const NS_tchar *path)
{
NS_tchar backup[MAXPATHLEN];
NS_tsnprintf(backup, sizeof(backup)/sizeof(backup[0]),
- NS_T("%s") BACKUP_EXT, path);
+ NS_T("%s") BACKUP_EXT, path);
return rename_file(path, backup);
}
@@ -910,13 +1001,14 @@ static int backup_restore(const NS_tchar *path, const NS_tchar *relPath)
{
NS_tchar backup[MAXPATHLEN];
NS_tsnprintf(backup, sizeof(backup)/sizeof(backup[0]),
- NS_T("%s") BACKUP_EXT, path);
+ NS_T("%s") BACKUP_EXT, path);
NS_tchar relBackup[MAXPATHLEN];
NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]),
- NS_T("%s") BACKUP_EXT, relPath);
+ NS_T("%s") BACKUP_EXT, relPath);
- if (NS_taccess(backup, F_OK)) {
+ if (NS_taccess(backup, F_OK))
+ {
LOG(("backup_restore: backup file doesn't exist: " LOG_S, relBackup));
return OK;
}
@@ -929,26 +1021,29 @@ static int backup_discard(const NS_tchar *path, const NS_tchar *relPath)
{
NS_tchar backup[MAXPATHLEN];
NS_tsnprintf(backup, sizeof(backup)/sizeof(backup[0]),
- NS_T("%s") BACKUP_EXT, path);
+ NS_T("%s") BACKUP_EXT, path);
NS_tchar relBackup[MAXPATHLEN];
NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]),
- NS_T("%s") BACKUP_EXT, relPath);
+ NS_T("%s") BACKUP_EXT, relPath);
// Nothing to discard
- if (NS_taccess(backup, F_OK)) {
+ if (NS_taccess(backup, F_OK))
+ {
return OK;
}
int rv = ensure_remove(backup);
#if defined(_WIN32)
- if (rv && !sStagedUpdate && !sReplaceRequest) {
+ if (rv && !sStagedUpdate && !sReplaceRequest)
+ {
LOG(("backup_discard: unable to remove: " LOG_S, relBackup));
NS_tchar path[MAXPATHLEN];
GetTempFileNameW(gDeleteDirPath, L"moz", 0, path);
- if (rename_file(backup, path)) {
+ if (rename_file(backup, path))
+ {
LOG(("backup_discard: failed to rename file:" LOG_S ", dst:" LOG_S,
- relBackup, relPath));
+ relBackup, relPath));
return WRITE_ERROR_DELETE_BACKUP;
}
// The MoveFileEx call to remove the file on OS reboot will fail if the
@@ -956,12 +1051,15 @@ static int backup_discard(const NS_tchar *path, const NS_tchar *relPath)
// but this is ok since the installer / uninstaller will delete the
// directory containing the file along with its contents after an update is
// applied, on reinstall, and on uninstall.
- if (MoveFileEx(path, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+ if (MoveFileEx(path, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT))
+ {
LOG(("backup_discard: file renamed and will be removed on OS " \
- "reboot: " LOG_S, relPath));
- } else {
+ "reboot: " LOG_S, relPath));
+ }
+ else
+ {
LOG(("backup_discard: failed to schedule OS reboot removal of " \
- "file: " LOG_S, relPath));
+ "file: " LOG_S, relPath));
}
}
#else
@@ -974,7 +1072,7 @@ static int backup_discard(const NS_tchar *path, const NS_tchar *relPath)
// Helper function for post-processing a temporary backup.
static void backup_finish(const NS_tchar *path, const NS_tchar *relPath,
- int status)
+ int status)
{
if (status == OK)
backup_discard(path, relPath);
@@ -1043,7 +1141,8 @@ RemoveFile::Parse(NS_tchar *line)
NS_tstrcpy(mRelPath.get(), validPath);
mFile.reset(get_full_path(validPath));
- if (!mFile) {
+ if (!mFile)
+ {
return PARSE_ERROR;
}
@@ -1055,7 +1154,8 @@ RemoveFile::Prepare()
{
// Skip the file if it already doesn't exist.
int rv = NS_taccess(mFile.get(), F_OK);
- if (rv) {
+ if (rv)
+ {
mSkip = 1;
mProgressCost = 0;
return OK;
@@ -1066,27 +1166,33 @@ RemoveFile::Prepare()
// Make sure that we're actually a file...
struct NS_tstat_t fileInfo;
rv = NS_tstat(mFile.get(), &fileInfo);
- if (rv) {
+ if (rv)
+ {
LOG(("failed to read file status info: " LOG_S ", err: %d", mFile.get(),
- errno));
+ errno));
return READ_ERROR;
}
- if (!S_ISREG(fileInfo.st_mode)) {
+ if (!S_ISREG(fileInfo.st_mode))
+ {
LOG(("path present, but not a file: " LOG_S, mFile.get()));
return DELETE_ERROR_EXPECTED_FILE;
}
NS_tchar *slash = (NS_tchar *) NS_tstrrchr(mFile.get(), NS_T('/'));
- if (slash) {
+ if (slash)
+ {
*slash = NS_T('\0');
rv = NS_taccess(mFile.get(), W_OK);
*slash = NS_T('/');
- } else {
+ }
+ else
+ {
rv = NS_taccess(NS_T("."), W_OK);
}
- if (rv) {
+ if (rv)
+ {
LOG(("access failed: %d", errno));
return WRITE_ERROR_FILE_ACCESS_DENIED;
}
@@ -1105,7 +1211,8 @@ RemoveFile::Execute()
// The file is checked for existence here and in Prepare since it might have
// been removed by a separate instruction: bug 311099.
int rv = NS_taccess(mFile.get(), F_OK);
- if (rv) {
+ if (rv)
+ {
LOG(("file cannot be removed because it does not exist; skipping"));
mSkip = 1;
return OK;
@@ -1113,7 +1220,8 @@ RemoveFile::Execute()
// Rename the old file. It will be removed in Finish.
rv = backup_create(mFile.get());
- if (rv) {
+ if (rv)
+ {
LOG(("backup_create failed: %d", rv));
return rv;
}
@@ -1160,7 +1268,8 @@ RemoveDir::Parse(NS_tchar *line)
NS_tstrcpy(mRelPath.get(), validPath);
mDir.reset(get_full_path(validPath));
- if (!mDir) {
+ if (!mDir)
+ {
return PARSE_ERROR;
}
@@ -1172,7 +1281,8 @@ RemoveDir::Prepare()
{
// We expect the directory to exist if we are to remove it.
int rv = NS_taccess(mDir.get(), F_OK);
- if (rv) {
+ if (rv)
+ {
mSkip = 1;
mProgressCost = 0;
return OK;
@@ -1183,19 +1293,22 @@ RemoveDir::Prepare()
// Make sure that we're actually a dir.
struct NS_tstat_t dirInfo;
rv = NS_tstat(mDir.get(), &dirInfo);
- if (rv) {
+ if (rv)
+ {
LOG(("failed to read directory status info: " LOG_S ", err: %d", mRelPath.get(),
- errno));
+ errno));
return READ_ERROR;
}
- if (!S_ISDIR(dirInfo.st_mode)) {
+ if (!S_ISDIR(dirInfo.st_mode))
+ {
LOG(("path present, but not a directory: " LOG_S, mRelPath.get()));
return DELETE_ERROR_EXPECTED_DIR;
}
rv = NS_taccess(mDir.get(), W_OK);
- if (rv) {
+ if (rv)
+ {
LOG(("access failed: %d, %d", rv, errno));
return WRITE_ERROR_DIR_ACCESS_DENIED;
}
@@ -1214,7 +1327,8 @@ RemoveDir::Execute()
// The directory is checked for existence at every step since it might have
// been removed by a separate instruction: bug 311099.
int rv = NS_taccess(mDir.get(), F_OK);
- if (rv) {
+ if (rv)
+ {
LOG(("directory no longer exists; skipping"));
mSkip = 1;
}
@@ -1233,16 +1347,19 @@ RemoveDir::Finish(int status)
// The directory is checked for existence at every step since it might have
// been removed by a separate instruction: bug 311099.
int rv = NS_taccess(mDir.get(), F_OK);
- if (rv) {
+ if (rv)
+ {
LOG(("directory no longer exists; skipping"));
return;
}
- if (status == OK) {
- if (NS_trmdir(mDir.get())) {
+ if (status == OK)
+ {
+ if (NS_trmdir(mDir.get()))
+ {
LOG(("non-fatal error removing directory: " LOG_S "/, rv: %d, err: %d",
- mRelPath.get(), rv, errno));
+ mRelPath.get(), rv, errno));
}
}
}
@@ -1277,7 +1394,8 @@ AddFile::Parse(NS_tchar *line)
NS_tstrcpy(mRelPath.get(), validPath);
mFile.reset(get_full_path(validPath));
- if (!mFile) {
+ if (!mFile)
+ {
return PARSE_ERROR;
}
@@ -1301,11 +1419,14 @@ AddFile::Execute()
// First make sure that we can actually get rid of any existing file.
rv = NS_taccess(mFile.get(), F_OK);
- if (rv == 0) {
+ if (rv == 0)
+ {
rv = backup_create(mFile.get());
if (rv)
return rv;
- } else {
+ }
+ else
+ {
rv = ensure_parent_dir(mFile.get());
if (rv)
return rv;
@@ -1314,7 +1435,8 @@ AddFile::Execute()
#ifdef _WIN32
char sourcefile[MAXPATHLEN];
if (!WideCharToMultiByte(CP_UTF8, 0, mRelPath.get(), -1, sourcefile,
- MAXPATHLEN, nullptr, nullptr)) {
+ MAXPATHLEN, nullptr, nullptr))
+ {
LOG(("error converting wchar to utf8: %d", GetLastError()));
return STRING_CONVERSION_ERROR;
}
@@ -1323,7 +1445,8 @@ AddFile::Execute()
#else
rv = gArchiveReader.ExtractFile(mRelPath.get(), mFile.get());
#endif
- if (!rv) {
+ if (!rv)
+ {
mAdded = true;
}
return rv;
@@ -1376,7 +1499,8 @@ PatchFile::~PatchFile()
// Normally this happens at the end of Execute, when we close the stream;
// this call is here in case Execute errors out.
#ifdef _WIN32
- if (mPatchStream) {
+ if (mPatchStream)
+ {
UnlockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), (DWORD)0, (DWORD)0, (DWORD)-1, (DWORD)-1);
}
#endif
@@ -1394,15 +1518,17 @@ PatchFile::LoadSourceFile(FILE* ofile)
{
struct stat os;
int rv = fstat(fileno((FILE *)ofile), &os);
- if (rv) {
+ if (rv)
+ {
LOG(("LoadSourceFile: unable to stat destination file: " LOG_S ", " \
- "err: %d", mFileRelPath.get(), errno));
+ "err: %d", mFileRelPath.get(), errno));
return READ_ERROR;
}
- if (uint32_t(os.st_size) != header.slen) {
+ if (uint32_t(os.st_size) != header.slen)
+ {
LOG(("LoadSourceFile: destination file size %d does not match expected size %d",
- uint32_t(os.st_size), header.slen));
+ uint32_t(os.st_size), header.slen));
return LOADSOURCE_ERROR_WRONG_SIZE;
}
@@ -1412,12 +1538,14 @@ PatchFile::LoadSourceFile(FILE* ofile)
size_t r = header.slen;
unsigned char *rb = buf;
- while (r) {
+ while (r)
+ {
const size_t count = std::min<size_t>(SSIZE_MAX, r);
size_t c = fread(rb, 1, count, ofile);
- if (c != count) {
+ if (c != count)
+ {
LOG(("LoadSourceFile: error reading destination file: " LOG_S,
- mFileRelPath.get()));
+ mFileRelPath.get()));
return READ_ERROR;
}
@@ -1429,9 +1557,10 @@ PatchFile::LoadSourceFile(FILE* ofile)
unsigned int crc = crc32(buf, header.slen);
- if (crc != header.scrc32) {
+ if (crc != header.scrc32)
+ {
LOG(("LoadSourceFile: destination file crc %d does not match expected " \
- "crc %d", crc, header.scrc32));
+ "crc %d", crc, header.scrc32));
return CRC_ERROR;
}
@@ -1460,7 +1589,8 @@ PatchFile::Parse(NS_tchar *line)
NS_tstrcpy(mFileRelPath.get(), validPath);
mFile.reset(get_full_path(validPath));
- if (!mFile) {
+ if (!mFile)
+ {
return PARSE_ERROR;
}
@@ -1476,7 +1606,7 @@ PatchFile::Prepare()
mPatchIndex = sPatchIndex++;
NS_tsnprintf(spath, sizeof(spath)/sizeof(spath[0]),
- NS_T("%s/updating/%d.patch"), gWorkingDirPath, mPatchIndex);
+ NS_T("%s/updating/%d.patch"), gWorkingDirPath, mPatchIndex);
NS_tremove(spath);
@@ -1487,14 +1617,16 @@ PatchFile::Prepare()
#ifdef _WIN32
// Lock the patch file, so it can't be messed with between
// when we're done creating it and when we go to apply it.
- if (!LockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), (DWORD)0, (DWORD)0, (DWORD)-1, (DWORD)-1)) {
+ if (!LockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), (DWORD)0, (DWORD)0, (DWORD)-1, (DWORD)-1))
+ {
LOG(("Couldn't lock patch file: %d", GetLastError()));
// TODO: moggi: fix the build problem with LOCK_ERROR_PATCH_FILE
return WRITE_ERROR; //return LOCK_ERROR_PATCH_FILE;
}
char sourcefile[MAXPATHLEN];
if (!WideCharToMultiByte(CP_UTF8, 0, mPatchFile, -1, sourcefile, MAXPATHLEN,
- nullptr, nullptr)) {
+ nullptr, nullptr))
+ {
LOG(("error converting wchar to utf8: %d", GetLastError()));
return STRING_CONVERSION_ERROR;
}
@@ -1520,26 +1652,31 @@ PatchFile::Execute()
FILE *origfile = nullptr;
#ifdef _WIN32
- if (NS_tstrcmp(mFileRelPath.get(), gCallbackRelPath) == 0) {
+ if (NS_tstrcmp(mFileRelPath.get(), gCallbackRelPath) == 0)
+ {
// Read from the copy of the callback when patching since the callback can't
// be opened for reading to prevent the application from being launched.
origfile = NS_tfopen(gCallbackBackupPath, NS_T("rb"));
- } else {
+ }
+ else
+ {
origfile = NS_tfopen(mFile.get(), NS_T("rb"));
}
#else
origfile = NS_tfopen(mFile.get(), NS_T("rb"));
#endif
- if (!origfile) {
+ if (!origfile)
+ {
LOG(("unable to open destination file: " LOG_S ", err: %d",
- mFileRelPath.get(), errno));
+ mFileRelPath.get(), errno));
return READ_ERROR;
}
rv = LoadSourceFile(origfile);
fclose(origfile);
- if (rv) {
+ if (rv)
+ {
LOG(("LoadSourceFile failed"));
return rv;
}
@@ -1548,9 +1685,10 @@ PatchFile::Execute()
// used to restore the file to its original state if there is an error.
struct NS_tstat_t ss;
rv = NS_tstat(mFile.get(), &ss);
- if (rv) {
+ if (rv)
+ {
LOG(("failed to read file status info: " LOG_S ", err: %d",
- mFileRelPath.get(), errno));
+ mFileRelPath.get(), errno));
return READ_ERROR;
}
@@ -1571,51 +1709,57 @@ PatchFile::Execute()
// not completely. There are also reports of _get_osfhandle failing on
// mingw.
HANDLE hfile = CreateFileW(mFile.get(),
- GENERIC_WRITE,
- 0,
- nullptr,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- nullptr);
-
- if (hfile != INVALID_HANDLE_VALUE) {
+ GENERIC_WRITE,
+ 0,
+ nullptr,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr);
+
+ if (hfile != INVALID_HANDLE_VALUE)
+ {
if (SetFilePointer(hfile, header.dlen,
- nullptr, FILE_BEGIN) != INVALID_SET_FILE_POINTER &&
- SetEndOfFile(hfile) != 0) {
+ nullptr, FILE_BEGIN) != INVALID_SET_FILE_POINTER &&
+ SetEndOfFile(hfile) != 0)
+ {
shouldTruncate = false;
}
CloseHandle(hfile);
}
AutoFile ofile(ensure_open(mFile.get(), shouldTruncate ? NS_T("wb+") : NS_T("rb+"),
- ss.st_mode));
+ ss.st_mode));
#elif defined(MACOSX)
AutoFile ofile(ensure_open(mFile.get(), NS_T("wb+"), ss.st_mode));
// Modified code from FileUtils.cpp
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, header.dlen};
// Try to get a continuous chunk of disk space
rv = fcntl(fileno((FILE *)ofile), F_PREALLOCATE, &store);
- if (rv == -1) {
+ if (rv == -1)
+ {
// OK, perhaps we are too fragmented, allocate non-continuous
store.fst_flags = F_ALLOCATEALL;
rv = fcntl(fileno((FILE *)ofile), F_PREALLOCATE, &store);
}
- if (rv != -1) {
+ if (rv != -1)
+ {
ftruncate(fileno((FILE *)ofile), header.dlen);
}
#else
AutoFile ofile(ensure_open(mFile.get(), NS_T("wb+"), ss.st_mode));
#endif
- if (ofile == nullptr) {
+ if (ofile == nullptr)
+ {
LOG(("unable to create new file: " LOG_S ", err: %d", mFileRelPath.get(),
- errno));
+ errno));
return WRITE_ERROR_OPEN_PATCH_FILE;
}
#ifdef _WIN32
- if (!shouldTruncate) {
+ if (!shouldTruncate)
+ {
fseek(ofile, 0, SEEK_SET);
}
#endif
@@ -1679,7 +1823,8 @@ int
AddIfFile::Prepare()
{
// If the test file does not exist, then skip this action.
- if (NS_taccess(mTestFile.get(), F_OK)) {
+ if (NS_taccess(mTestFile.get(), F_OK))
+ {
mTestFile = nullptr;
return OK;
}
@@ -1738,7 +1883,8 @@ int
AddIfNotFile::Prepare()
{
// If the test file exists, then skip this action.
- if (!NS_taccess(mTestFile.get(), F_OK)) {
+ if (!NS_taccess(mTestFile.get(), F_OK))
+ {
mTestFile = NULL;
return OK;
}
@@ -1797,7 +1943,8 @@ int
PatchIfFile::Prepare()
{
// If the test file does not exist, then skip this action.
- if (NS_taccess(mTestFile.get(), F_OK)) {
+ if (NS_taccess(mTestFile.get(), F_OK))
+ {
mTestFile = nullptr;
return OK;
}
@@ -1838,7 +1985,7 @@ PatchIfFile::Finish(int status)
*/
bool
LaunchWinPostProcess(const WCHAR *installationDir,
- const WCHAR *updateInfoDir)
+ const WCHAR *updateInfoDir)
{
WCHAR workingDirectory[MAX_PATH + 1] = { L'\0' };
wcsncpy(workingDirectory, installationDir, MAX_PATH);
@@ -1850,7 +1997,8 @@ LaunchWinPostProcess(const WCHAR *installationDir,
// modifications) for the update.
WCHAR inifile[MAX_PATH + 1] = { L'\0' };
wcsncpy(inifile, installationDir, MAX_PATH);
- if (!PathAppendSafe(inifile, L"updater.ini")) {
+ if (!PathAppendSafe(inifile, L"updater.ini"))
+ {
return false;
}
@@ -1859,48 +2007,56 @@ LaunchWinPostProcess(const WCHAR *installationDir,
WCHAR exeasync[10];
bool async = true;
if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", nullptr,
- exefile, MAX_PATH + 1, inifile)) {
+ exefile, MAX_PATH + 1, inifile))
+ {
return false;
}
if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeArg", nullptr, exearg,
- MAX_PATH + 1, inifile)) {
+ MAX_PATH + 1, inifile))
+ {
return false;
}
if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeAsync", L"TRUE",
- exeasync,
- sizeof(exeasync)/sizeof(exeasync[0]),
- inifile)) {
+ exeasync,
+ sizeof(exeasync)/sizeof(exeasync[0]),
+ inifile))
+ {
return false;
}
// Verify that exeFile doesn't contain relative paths
- if (wcsstr(exefile, L"..") != nullptr) {
+ if (wcsstr(exefile, L"..") != nullptr)
+ {
return false;
}
WCHAR exefullpath[MAX_PATH + 1] = { L'\0' };
wcsncpy(exefullpath, installationDir, MAX_PATH);
- if (!PathAppendSafe(exefullpath, exefile)) {
+ if (!PathAppendSafe(exefullpath, exefile))
+ {
return false;
}
#if !defined(TEST_UPDATER) && defined(MAINTENANCE_SERVICE)
if (sUsingService &&
- !DoesBinaryMatchAllowedCertificates(installationDir, exefullpath)) {
+ !DoesBinaryMatchAllowedCertificates(installationDir, exefullpath))
+ {
return false;
}
#endif
WCHAR dlogFile[MAX_PATH + 1];
- if (!PathGetSiblingFilePath(dlogFile, exefullpath, L"uninstall.update")) {
+ if (!PathGetSiblingFilePath(dlogFile, exefullpath, L"uninstall.update"))
+ {
return false;
}
WCHAR slogFile[MAX_PATH + 1] = { L'\0' };
wcsncpy(slogFile, updateInfoDir, MAX_PATH);
- if (!PathAppendSafe(slogFile, L"update.log")) {
+ if (!PathAppendSafe(slogFile, L"update.log"))
+ {
return false;
}
@@ -1909,7 +2065,8 @@ LaunchWinPostProcess(const WCHAR *installationDir,
size_t len = wcslen(exearg) + wcslen(dummyArg);
WCHAR *cmdline = (WCHAR *) malloc((len + 1) * sizeof(WCHAR));
- if (!cmdline) {
+ if (!cmdline)
+ {
return false;
}
@@ -1918,7 +2075,8 @@ LaunchWinPostProcess(const WCHAR *installationDir,
if (sUsingService ||
!_wcsnicmp(exeasync, L"false", 6) ||
- !_wcsnicmp(exeasync, L"0", 2)) {
+ !_wcsnicmp(exeasync, L"0", 2))
+ {
async = false;
}
@@ -1932,18 +2090,20 @@ LaunchWinPostProcess(const WCHAR *installationDir,
PROCESS_INFORMATION pi = {0};
bool ok = CreateProcessW(exefullpath,
- cmdline,
- nullptr, // no special security attributes
- nullptr, // no special thread attributes
- false, // don't inherit filehandles
- 0, // No special process creation flags
- nullptr, // inherit my environment
- workingDirectory,
- &si,
- &pi);
+ cmdline,
+ nullptr, // no special security attributes
+ nullptr, // no special thread attributes
+ false, // don't inherit filehandles
+ 0, // No special process creation flags
+ nullptr, // inherit my environment
+ workingDirectory,
+ &si,
+ &pi);
free(cmdline);
- if (ok) {
- if (!async) {
+ if (ok)
+ {
+ if (!async)
+ {
WaitForSingleObject(pi.hProcess, INFINITE);
}
CloseHandle(pi.hProcess);
@@ -1956,9 +2116,9 @@ LaunchWinPostProcess(const WCHAR *installationDir,
static void
LaunchCallbackApp(const NS_tchar *workingDir,
- int argc,
- NS_tchar **argv,
- bool usingService)
+ int argc,
+ NS_tchar **argv,
+ bool usingService)
{
putenv(const_cast<char*>("NO_EM_RESTART="));
putenv(const_cast<char*>("MOZ_LAUNCHED_CHILD=1"));
@@ -1966,19 +2126,22 @@ LaunchCallbackApp(const NS_tchar *workingDir,
// Run from the specified working directory (see bug 312360). This is not
// necessary on Windows CE since the application that launches the updater
// passes the working directory as an --environ: command line argument.
- if (NS_tchdir(workingDir) != 0) {
+ if (NS_tchdir(workingDir) != 0)
+ {
LOG(("Warning: chdir failed"));
}
#if defined(USE_EXECV)
- (void) argc; (void) usingService; // avoid warnings
+ (void) argc;
+ (void) usingService; // avoid warnings
execv(argv[0], argv);
#elif defined(MACOSX)
LaunchChild(argc, (const char**)argv);
#elif defined(WNT)
// Do not allow the callback to run when running an update through the
// service as session 0. The unelevated updater.exe will do the launching.
- if (!usingService) {
+ if (!usingService)
+ {
WinLaunchChild(argv[0], argc, argv, nullptr);
}
#else
@@ -1996,7 +2159,7 @@ WriteStatusFile(const char* aStatus)
GetTempFileNameW(gPatchDirPath, L"sta", 0, filename);
#else
NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
- NS_T("%s/update.status"), gPatchDirPath);
+ NS_T("%s/update.status"), gPatchDirPath);
#endif
// Make sure that the directory for the update status file exists
@@ -2007,11 +2170,13 @@ WriteStatusFile(const char* aStatus)
// move the temp file to the update.status file on Windows.
{
AutoFile file(NS_tfopen(filename, NS_T("wb+")));
- if (file == nullptr) {
+ if (file == nullptr)
+ {
return false;
}
- if (fwrite(aStatus, strlen(aStatus), 1, file) != 1) {
+ if (fwrite(aStatus, strlen(aStatus), 1, file) != 1)
+ {
return false;
}
}
@@ -2019,8 +2184,9 @@ WriteStatusFile(const char* aStatus)
#if defined(_WIN32)
NS_tchar dstfilename[MAXPATHLEN] = {NS_T('\0')};
NS_tsnprintf(dstfilename, sizeof(dstfilename)/sizeof(dstfilename[0]),
- NS_T("%s\\update.status"), gPatchDirPath);
- if (MoveFileExW(filename, dstfilename, MOVEFILE_REPLACE_EXISTING) == 0) {
+ NS_T("%s\\update.status"), gPatchDirPath);
+ if (MoveFileExW(filename, dstfilename, MOVEFILE_REPLACE_EXISTING) == 0)
+ {
return false;
}
#endif
@@ -2034,13 +2200,19 @@ WriteStatusFile(int status)
const char *text;
char buf[32];
- if (status == OK) {
- if (sStagedUpdate) {
+ if (status == OK)
+ {
+ if (sStagedUpdate)
+ {
text = "applied\n";
- } else {
+ }
+ else
+ {
text = "succeeded\n";
}
- } else {
+ }
+ else
+ {
snprintf(buf, sizeof(buf)/sizeof(buf[0]), "failed: %d\n", status);
text = buf;
}
@@ -2063,7 +2235,7 @@ IsUpdateStatusPendingService()
{
NS_tchar filename[MAXPATHLEN];
NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
- NS_T("%s/update.status"), gPatchDirPath);
+ NS_T("%s/update.status"), gPatchDirPath);
AutoFile file(NS_tfopen(filename, NS_T("rb")));
if (file == nullptr)
@@ -2076,9 +2248,9 @@ IsUpdateStatusPendingService()
const char kAppliedService[] = "applied-service";
return (strncmp(buf, kPendingService,
- sizeof(kPendingService) - 1) == 0) ||
- (strncmp(buf, kAppliedService,
- sizeof(kAppliedService) - 1) == 0);
+ sizeof(kPendingService) - 1) == 0) ||
+ (strncmp(buf, kAppliedService,
+ sizeof(kAppliedService) - 1) == 0);
}
#endif
@@ -2097,7 +2269,7 @@ IsUpdateStatusSucceeded(bool &isSucceeded)
isSucceeded = false;
NS_tchar filename[MAXPATHLEN];
NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
- NS_T("%s/update.status"), gPatchDirPath);
+ NS_T("%s/update.status"), gPatchDirPath);
AutoFile file(NS_tfopen(filename, NS_T("rb")));
if (file == nullptr)
@@ -2108,7 +2280,7 @@ IsUpdateStatusSucceeded(bool &isSucceeded)
const char kSucceeded[] = "succeeded";
isSucceeded = strncmp(buf, kSucceeded,
- sizeof(kSucceeded) - 1) == 0;
+ sizeof(kSucceeded) - 1) == 0;
return true;
}
#endif
@@ -2159,7 +2331,7 @@ ProcessReplaceRequest()
#ifdef MACOSX
NS_tchar destDir[MAXPATHLEN];
NS_tsnprintf(destDir, sizeof(destDir)/sizeof(destDir[0]),
- NS_T("%s/Contents"), gInstallDirPath);
+ NS_T("%s/Contents"), gInstallDirPath);
#elif defined(WNT)
// Windows preserves the case of the file/directory names. We use the
// GetLongPathName API in order to get the correct case for the directory
@@ -2167,7 +2339,8 @@ ProcessReplaceRequest()
// application, the installation directory's name does not change.
NS_tchar destDir[MAXPATHLEN];
if (!GetLongPathNameW(gInstallDirPath, destDir,
- sizeof(destDir)/sizeof(destDir[0]))) {
+ sizeof(destDir)/sizeof(destDir[0])))
+ {
return NO_INSTALLDIR_ERROR;
}
#else
@@ -2176,16 +2349,16 @@ ProcessReplaceRequest()
NS_tchar tmpDir[MAXPATHLEN];
NS_tsnprintf(tmpDir, sizeof(tmpDir)/sizeof(tmpDir[0]),
- NS_T("%s.bak"), destDir);
+ NS_T("%s.bak"), destDir);
NS_tchar newDir[MAXPATHLEN];
NS_tsnprintf(newDir, sizeof(newDir)/sizeof(newDir[0]),
#ifdef MACOSX
- NS_T("%s/Contents"),
- gWorkingDirPath);
+ NS_T("%s/Contents"),
+ gWorkingDirPath);
#else
- NS_T("%s.bak/updated"),
- gInstallDirPath);
+ NS_T("%s.bak/updated"),
+ gInstallDirPath);
#endif
// First try to remove the possibly existing temp directory, because if this
@@ -2195,7 +2368,7 @@ ProcessReplaceRequest()
ensure_remove_recursive(tmpDir);
LOG(("Begin moving destDir (" LOG_S ") to tmpDir (" LOG_S ")",
- destDir, tmpDir));
+ destDir, tmpDir));
int rv = rename_file(destDir, tmpDir, true);
#ifdef _WIN32
// On Windows, if Firefox is launched using the shortcut, it will hold a handle
@@ -2204,17 +2377,19 @@ ProcessReplaceRequest()
// If it's not released, we just fail to perform the replace request.
const int max_retries = 10;
int retries = 0;
- while (rv == WRITE_ERROR && (retries++ < max_retries)) {
+ while (rv == WRITE_ERROR && (retries++ < max_retries))
+ {
LOG(("PerformReplaceRequest: destDir rename attempt %d failed. " \
- "File: " LOG_S ". Last error: %d, err: %d", retries,
- destDir, GetLastError(), rv));
+ "File: " LOG_S ". Last error: %d, err: %d", retries,
+ destDir, GetLastError(), rv));
Sleep(100);
rv = rename_file(destDir, tmpDir, true);
}
#endif
- if (rv) {
+ if (rv)
+ {
// The status file will have 'pending' written to it so there is no value in
// returning an error specific for this failure.
LOG(("Moving destDir to tmpDir failed, err: %d", rv));
@@ -2222,22 +2397,25 @@ ProcessReplaceRequest()
}
LOG(("Begin moving newDir (" LOG_S ") to destDir (" LOG_S ")",
- newDir, destDir));
+ newDir, destDir));
rv = rename_file(newDir, destDir, true);
#ifdef MACOSX
- if (rv) {
+ if (rv)
+ {
LOG(("Moving failed. Begin copying newDir (" LOG_S ") to destDir (" LOG_S ")",
- newDir, destDir));
+ newDir, destDir));
copy_recursive_skiplist<0> skiplist;
rv = ensure_copy_recursive(newDir, destDir, skiplist);
}
#endif
- if (rv) {
+ if (rv)
+ {
LOG(("Moving newDir to destDir failed, err: %d", rv));
LOG(("Now, try to move tmpDir back to destDir"));
ensure_remove_recursive(destDir);
int rv2 = rename_file(tmpDir, destDir, true);
- if (rv2) {
+ if (rv2)
+ {
LOG(("Moving tmpDir back to destDir failed, err: %d", rv2));
}
// The status file will be have 'pending' written to it so there is no value
@@ -2251,11 +2429,12 @@ ProcessReplaceRequest()
// old installation directory to the new installation directory.
NS_tchar tmpLog[MAXPATHLEN];
NS_tsnprintf(tmpLog, sizeof(tmpLog)/sizeof(tmpLog[0]),
- NS_T("%s/updates/last-update.log"), tmpDir);
- if (!NS_taccess(tmpLog, F_OK)) {
+ NS_T("%s/updates/last-update.log"), tmpDir);
+ if (!NS_taccess(tmpLog, F_OK))
+ {
NS_tchar destLog[MAXPATHLEN];
NS_tsnprintf(destLog, sizeof(destLog)/sizeof(destLog[0]),
- NS_T("%s/updates/last-update.log"), destDir);
+ NS_T("%s/updates/last-update.log"), destDir);
NS_tremove(destLog);
NS_trename(tmpLog, destLog);
}
@@ -2263,16 +2442,18 @@ ProcessReplaceRequest()
LOG(("Now, remove the tmpDir"));
rv = ensure_remove_recursive(tmpDir, true);
- if (rv) {
+ if (rv)
+ {
LOG(("Removing tmpDir failed, err: %d", rv));
#ifdef _WIN32
NS_tchar deleteDir[MAXPATHLEN];
NS_tsnprintf(deleteDir, sizeof(deleteDir)/sizeof(deleteDir[0]),
- NS_T("%s\\%s"), destDir, DELETE_DIR);
+ NS_T("%s\\%s"), destDir, DELETE_DIR);
// Attempt to remove the tobedeleted directory and then recreate it if it
// was successfully removed.
_wrmdir(deleteDir);
- if (NS_taccess(deleteDir, F_OK)) {
+ if (NS_taccess(deleteDir, F_OK))
+ {
NS_tmkdir(deleteDir, 0755);
}
remove_recursive_on_reboot(tmpDir, deleteDir);
@@ -2284,7 +2465,7 @@ ProcessReplaceRequest()
// directory has been moved.
NS_tchar updatedAppDir[MAXPATHLEN];
NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir)/sizeof(updatedAppDir[0]),
- NS_T("%s/Updated.app"), gPatchDirPath);
+ NS_T("%s/Updated.app"), gPatchDirPath);
ensure_remove_recursive(updatedAppDir);
#endif
@@ -2322,7 +2503,7 @@ ReadMARChannelIDs(const NS_tchar *path, MARChannelStringTable *results)
char updater_strings[kNumStrings][MAX_TEXT_LEN];
int result = ReadStrings(path, kUpdaterKeys, kNumStrings,
- updater_strings, "Settings");
+ updater_strings, "Settings");
strncpy(results->MARChannelID, updater_strings[0], MAX_TEXT_LEN - 1);
results->MARChannelID[MAX_TEXT_LEN - 1] = 0;
@@ -2337,7 +2518,7 @@ GetUpdateFileName(NS_tchar *fileName, int maxChars)
// TODO: moggi: needs adaption for LibreOffice
// We would like to store the name inside of an ini file
NS_tsnprintf(fileName, maxChars,
- NS_T("%s/update.mar"), gPatchDirPath);
+ NS_T("%s/update.mar"), gPatchDirPath);
return OK;
}
@@ -2346,36 +2527,45 @@ UpdateThreadFunc(void * /*param*/)
{
// open ZIP archive and process...
int rv;
- if (sReplaceRequest) {
+ if (sReplaceRequest)
+ {
rv = ProcessReplaceRequest();
- } else {
+ }
+ else
+ {
NS_tchar dataFile[MAXPATHLEN];
rv = GetUpdateFileName(dataFile, sizeof(dataFile)/sizeof(dataFile[0]));
- if (rv == OK) {
+ if (rv == OK)
+ {
rv = gArchiveReader.Open(dataFile);
}
#ifdef VERIFY_MAR_SIGNATURE
- if (rv == OK) {
+ if (rv == OK)
+ {
#ifdef _WIN32
HKEY baseKey = nullptr;
wchar_t valueName[] = L"Image Path";
wchar_t rasenh[] = L"rsaenh.dll";
bool reset = false;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Microsoft Enhanced Cryptographic Provider v1.0",
- 0, KEY_READ | KEY_WRITE,
- &baseKey) == ERROR_SUCCESS) {
+ L"SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Microsoft Enhanced Cryptographic Provider v1.0",
+ 0, KEY_READ | KEY_WRITE,
+ &baseKey) == ERROR_SUCCESS)
+ {
wchar_t path[MAX_PATH + 1];
DWORD size = sizeof(path);
DWORD type;
if (RegQueryValueExW(baseKey, valueName, 0, &type,
- (LPBYTE)path, &size) == ERROR_SUCCESS) {
- if (type == REG_SZ && wcscmp(path, rasenh) == 0) {
+ (LPBYTE)path, &size) == ERROR_SUCCESS)
+ {
+ if (type == REG_SZ && wcscmp(path, rasenh) == 0)
+ {
wchar_t rasenhFullPath[] = L"%SystemRoot%\\System32\\rsaenh.dll";
if (RegSetValueExW(baseKey, valueName, 0, REG_SZ,
- (const BYTE*)rasenhFullPath,
- sizeof(rasenhFullPath)) == ERROR_SUCCESS) {
+ (const BYTE*)rasenhFullPath,
+ sizeof(rasenhFullPath)) == ERROR_SUCCESS)
+ {
reset = true;
}
}
@@ -2384,33 +2574,38 @@ UpdateThreadFunc(void * /*param*/)
#endif
rv = gArchiveReader.VerifySignature();
#ifdef _WIN32
- if (baseKey) {
- if (reset) {
+ if (baseKey)
+ {
+ if (reset)
+ {
RegSetValueExW(baseKey, valueName, 0, REG_SZ,
- (const BYTE*)rasenh,
- sizeof(rasenh));
+ (const BYTE*)rasenh,
+ sizeof(rasenh));
}
RegCloseKey(baseKey);
}
#endif
}
- if (rv == OK) {
- if (rv == OK) {
+ if (rv == OK)
+ {
+ if (rv == OK)
+ {
NS_tchar updateSettingsPath[MAX_TEXT_LEN];
// TODO: moggi: needs adaption for LibreOffice
// These paths need to be adapted for us.
NS_tsnprintf(updateSettingsPath,
- sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]),
+ sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]),
#ifdef MACOSX
- NS_T("%s/Contents/Resources/update-settings.ini"),
+ NS_T("%s/Contents/Resources/update-settings.ini"),
#else
- NS_T("%s/update-settings.ini"),
+ NS_T("%s/update-settings.ini"),
#endif
- gWorkingDirPath);
+ gWorkingDirPath);
MARChannelStringTable MARStrings;
- if (ReadMARChannelIDs(updateSettingsPath, &MARStrings) != OK) {
+ if (ReadMARChannelIDs(updateSettingsPath, &MARStrings) != OK)
+ {
// If we can't read from update-settings.ini then we shouldn't impose
// a MAR restriction. Some installations won't even include this file.
MARStrings.MARChannelID[0] = '\0';
@@ -2422,14 +2617,18 @@ UpdateThreadFunc(void * /*param*/)
}
#endif
- if (rv == OK && sStagedUpdate) {
+ if (rv == OK && sStagedUpdate)
+ {
#ifdef TEST_UPDATER
// The MOZ_TEST_SKIP_UPDATE_STAGE environment variable prevents copying
// the files in dist/bin in the test updater when staging an update since
// this can cause tests to timeout.
- if (EnvHasValue("MOZ_TEST_SKIP_UPDATE_STAGE")) {
+ if (EnvHasValue("MOZ_TEST_SKIP_UPDATE_STAGE"))
+ {
rv = OK;
- } else {
+ }
+ else
+ {
rv = CopyInstallDirToDestDir();
}
#else
@@ -2437,23 +2636,27 @@ UpdateThreadFunc(void * /*param*/)
#endif
}
- if (rv == OK) {
+ if (rv == OK)
+ {
rv = DoUpdate();
gArchiveReader.Close();
NS_tchar updatingDir[MAXPATHLEN];
NS_tsnprintf(updatingDir, sizeof(updatingDir)/sizeof(updatingDir[0]),
- NS_T("%s/updating"), gWorkingDirPath);
+ NS_T("%s/updating"), gWorkingDirPath);
ensure_remove_recursive(updatingDir);
}
}
- if (rv && (sReplaceRequest || sStagedUpdate)) {
+ if (rv && (sReplaceRequest || sStagedUpdate))
+ {
#ifdef _WIN32
// On Windows, the current working directory of the process should be changed
// so that it's not locked.
- if (sStagedUpdate) {
+ if (sStagedUpdate)
+ {
NS_tchar sysDir[MAX_PATH + 1] = { L'\0' };
- if (GetSystemDirectoryW(sysDir, MAX_PATH + 1)) {
+ if (GetSystemDirectoryW(sysDir, MAX_PATH + 1))
+ {
NS_tchdir(sysDir);
}
}
@@ -2466,24 +2669,33 @@ UpdateThreadFunc(void * /*param*/)
// startup path will see the pending status, and will start the
// updater application again in order to apply the update without
// staging.
- if (sReplaceRequest) {
+ if (sReplaceRequest)
+ {
WriteStatusFile(sUsingService ? "pending-service" : "pending");
- } else {
+ }
+ else
+ {
WriteStatusFile(rv);
}
#ifdef TEST_UPDATER
// Some tests need to use --test-process-updates again.
putenv(const_cast<char*>("MOZ_TEST_PROCESS_UPDATES="));
#endif
- } else {
- if (rv) {
+ }
+ else
+ {
+ if (rv)
+ {
LOG(("failed: %d", rv));
- } else {
+ }
+ else
+ {
#ifdef MACOSX
// If the update was successful we need to update the timestamp on the
// top-level Mac OS X bundle directory so that Mac OS X's Launch Services
// picks up any major changes when the bundle is updated.
- if (!sStagedUpdate && utimes(gInstallDirPath, nullptr) != 0) {
+ if (!sStagedUpdate && utimes(gInstallDirPath, nullptr) != 0)
+ {
LOG(("Couldn't set access/modification time on application bundle."));
}
#endif
@@ -2503,7 +2715,8 @@ ServeElevatedUpdateThreadFunc(void* param)
{
UpdateServerThreadArgs* threadArgs = (UpdateServerThreadArgs*)param;
gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv);
- if (!gSucceeded) {
+ if (!gSucceeded)
+ {
WriteStatusFile(ELEVATION_CANCELED);
}
QuitProgressUI();
@@ -2511,7 +2724,8 @@ ServeElevatedUpdateThreadFunc(void* param)
void freeArguments(int argc, char** argv)
{
- for (int i = 0; i < argc; i++) {
+ for (int i = 0; i < argc; i++)
+ {
free(argv[i]);
}
free(argv);
@@ -2519,19 +2733,22 @@ void freeArguments(int argc, char** argv)
#endif
int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv,
- int callbackIndex
+ int callbackIndex
#ifdef _WIN32
- , const WCHAR* elevatedLockFilePath
- , HANDLE updateLockFileHandle
+ , const WCHAR* elevatedLockFilePath
+ , HANDLE updateLockFileHandle
#elif defined(MACOSX)
- , bool isElevated
+ , bool isElevated
#endif
- )
+ )
{
- if (argc > callbackIndex) {
+ if (argc > callbackIndex)
+ {
#if defined(_WIN32)
- if (gSucceeded) {
- if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) {
+ if (gSucceeded)
+ {
+ if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath))
+ {
fprintf(stderr, "The post update process was not launched");
}
@@ -2542,27 +2759,30 @@ int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv,
// service if the service failed to apply the update. We want to update
// the service to a newer version in that case. If we are not running
// through the service, then USING_SERVICE will not exist.
- if (!sUsingService) {
+ if (!sUsingService)
+ {
StartServiceUpdate(gInstallDirPath);
}
}
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 0);
#elif defined(MACOSX)
- if (!isElevated) {
- if (gSucceeded) {
+ if (!isElevated)
+ {
+ if (gSucceeded)
+ {
LaunchMacPostProcess(gInstallDirPath);
}
#endif
- LaunchCallbackApp(argv[5],
- argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ LaunchCallbackApp(argv[5],
+ argc - callbackIndex,
+ argv + callbackIndex,
+ sUsingService);
#ifdef XP_MACOSX
- } // if (!isElevated)
+ } // if (!isElevated)
#endif /* XP_MACOSX */
- }
- return 0;
+}
+return 0;
}
int NS_main(int argc, NS_tchar **argv)
@@ -2576,8 +2796,10 @@ int NS_main(int argc, NS_tchar **argv)
// TODO: moggi: needs adaption for LibreOffice
bool isElevated =
strstr(argv[0], "/Library/PrivilegedHelperTools/org.mozilla.updater") != 0;
- if (isElevated) {
- if (!ObtainUpdaterArguments(&argc, &argv)) {
+ if (isElevated)
+ {
+ if (!ObtainUpdaterArguments(&argc, &argv))
+ {
// Won't actually get here because ObtainUpdaterArguments will terminate
// the current process on failure.
return 1;
@@ -2590,7 +2812,8 @@ int NS_main(int argc, NS_tchar **argv)
// need to initialize NSS at all there.
// Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS
// databases.
- if (NSS_NoDB_Init(NULL) != SECSuccess) {
+ if (NSS_NoDB_Init(NULL) != SECSuccess)
+ {
PRErrorCode error = PR_GetError();
fprintf(stderr, "Could not initialize NSS: %s (%d)",
PR_ErrorToName(error), (int) error);
@@ -2599,7 +2822,8 @@ int NS_main(int argc, NS_tchar **argv)
#endif
#ifdef MACOSX
- if (!isElevated) {
+ if (!isElevated)
+ {
#endif
InitProgressUI(&argc, &argv);
#ifdef MACOSX
@@ -2620,10 +2844,12 @@ int NS_main(int argc, NS_tchar **argv)
// arguments are provided whether the update was successful or not. All
// remaining arguments are optional and are passed to the callback when it is
// launched.
- if (argc < 4) {
+ if (argc < 4)
+ {
fprintf(stderr, "Usage: updater patch-dir install-dir apply-to-dir [wait-pid [callback-working-dir callback-path args...]]\n");
#ifdef MACOSX
- if (isElevated) {
+ if (isElevated)
+ {
freeArguments(argc, argv);
CleanupElevatedMacUpdate(true);
}
@@ -2641,7 +2867,8 @@ int NS_main(int argc, NS_tchar **argv)
NS_tstrncpy(gInstallDirPath, argv[2], MAXPATHLEN);
gInstallDirPath[MAXPATHLEN - 1] = NS_T('\0');
NS_tchar *slash = NS_tstrrchr(gInstallDirPath, NS_SLASH);
- if (slash && !slash[1]) {
+ if (slash && !slash[1])
+ {
*slash = NS_T('\0');
}
@@ -2665,13 +2892,14 @@ int NS_main(int argc, NS_tchar **argv)
// TODO: moggi: needs adaption for LibreOffice
HKEY hkApp = nullptr;
RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Classes\\Applications",
- 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr,
- &hkApp, nullptr);
+ 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr,
+ &hkApp, nullptr);
RegCloseKey(hkApp);
if (RegCreateKeyExW(HKEY_CURRENT_USER,
- L"Software\\Classes\\Applications\\updater.exe",
- 0, nullptr, REG_OPTION_VOLATILE, KEY_SET_VALUE, nullptr,
- &hkApp, nullptr) == ERROR_SUCCESS) {
+ L"Software\\Classes\\Applications\\updater.exe",
+ 0, nullptr, REG_OPTION_VOLATILE, KEY_SET_VALUE, nullptr,
+ &hkApp, nullptr) == ERROR_SUCCESS)
+ {
RegSetValueExW(hkApp, L"IsHostApp", 0, REG_NONE, 0, 0);
RegSetValueExW(hkApp, L"NoOpenWith", 0, REG_NONE, 0, 0);
RegSetValueExW(hkApp, L"NoStartPage", 0, REG_NONE, 0, 0);
@@ -2686,17 +2914,21 @@ int NS_main(int argc, NS_tchar **argv)
#else
int pid = 0;
#endif
- if (argc > 4) {
+ if (argc > 4)
+ {
#ifdef _WIN32
pid = _wtoi64(argv[4]);
#else
pid = atoi(argv[4]);
#endif
- if (pid == -1) {
+ if (pid == -1)
+ {
// This is a signal from the parent process that the updater should stage
// the update.
sStagedUpdate = true;
- } else if (NS_tstrstr(argv[4], NS_T("/replace"))) {
+ }
+ else if (NS_tstrstr(argv[4], NS_T("/replace")))
+ {
// We're processing a request to replace the application with a staged
// update.
sReplaceRequest = true;
@@ -2710,12 +2942,14 @@ int NS_main(int argc, NS_tchar **argv)
NS_tstrncpy(gWorkingDirPath, argv[3], MAXPATHLEN);
gWorkingDirPath[MAXPATHLEN - 1] = NS_T('\0');
slash = NS_tstrrchr(gWorkingDirPath, NS_SLASH);
- if (slash && !slash[1]) {
+ if (slash && !slash[1])
+ {
*slash = NS_T('\0');
}
#ifdef MACOSX
- if (!isElevated && !IsRecursivelyWritable(argv[2])) {
+ if (!isElevated && !IsRecursivelyWritable(argv[2]))
+ {
// If the app directory isn't recursively writeable, an elevated update is
// required.
UpdateServerThreadArgs threadArgs;
@@ -2723,7 +2957,8 @@ int NS_main(int argc, NS_tchar **argv)
threadArgs.argv = const_cast<const NS_tchar**>(argv);
Thread t1;
- if (t1.Run(ServeElevatedUpdateThreadFunc, &threadArgs) == 0) {
+ if (t1.Run(ServeElevatedUpdateThreadFunc, &threadArgs) == 0)
+ {
// Show an indeterminate progress bar while an elevated update is in
// progress.
ShowProgressUI(true);
@@ -2737,10 +2972,12 @@ int NS_main(int argc, NS_tchar **argv)
LogInit(gPatchDirPath, NS_T("update.log"));
- if (!WriteStatusFile("applying")) {
+ if (!WriteStatusFile("applying"))
+ {
LOG(("failed setting status to 'applying'"));
#ifdef MACOSX
- if (isElevated) {
+ if (isElevated)
+ {
freeArguments(argc, argv);
CleanupElevatedMacUpdate(true);
}
@@ -2748,9 +2985,12 @@ int NS_main(int argc, NS_tchar **argv)
return 1;
}
- if (sStagedUpdate) {
+ if (sStagedUpdate)
+ {
LOG(("Performing a staged update"));
- } else if (sReplaceRequest) {
+ }
+ else if (sReplaceRequest)
+ {
LOG(("Performing a replace request"));
}
@@ -2759,30 +2999,34 @@ int NS_main(int argc, NS_tchar **argv)
LOG(("WORKING DIRECTORY " LOG_S, gWorkingDirPath));
#ifdef _WIN32
- if (_wcsnicmp(gWorkingDirPath, gInstallDirPath, MAX_PATH) != 0) {
- if (!sStagedUpdate && !sReplaceRequest) {
+ if (_wcsnicmp(gWorkingDirPath, gInstallDirPath, MAX_PATH) != 0)
+ {
+ if (!sStagedUpdate && !sReplaceRequest)
+ {
WriteStatusFile(INVALID_APPLYTO_DIR_ERROR);
LOG(("Installation directory and working directory must be the same "
- "for non-staged updates. Exiting."));
+ "for non-staged updates. Exiting."));
LogFinish();
return 1;
}
NS_tchar workingDirParent[MAX_PATH];
NS_tsnprintf(workingDirParent,
- sizeof(workingDirParent) / sizeof(workingDirParent[0]),
- NS_T("%s"), gWorkingDirPath);
- if (!PathRemoveFileSpecW(workingDirParent)) {
+ sizeof(workingDirParent) / sizeof(workingDirParent[0]),
+ NS_T("%s"), gWorkingDirPath);
+ if (!PathRemoveFileSpecW(workingDirParent))
+ {
WriteStatusFile(REMOVE_FILE_SPEC_ERROR);
LOG(("Error calling PathRemoveFileSpecW: %d", GetLastError()));
LogFinish();
return 1;
}
- if (_wcsnicmp(workingDirParent, gInstallDirPath, MAX_PATH) != 0) {
+ if (_wcsnicmp(workingDirParent, gInstallDirPath, MAX_PATH) != 0)
+ {
WriteStatusFile(INVALID_APPLYTO_DIR_STAGED_ERROR);
LOG(("The apply-to directory must be the same as or "
- "a child of the installation directory! Exiting."));
+ "a child of the installation directory! Exiting."));
LogFinish();
return 1;
}
@@ -2791,12 +3035,14 @@ int NS_main(int argc, NS_tchar **argv)
#ifdef _WIN32
- if (pid > 0) {
+ if (pid > 0)
+ {
HANDLE parent = OpenProcess(SYNCHRONIZE, false, (DWORD) pid);
// May return nullptr if the parent process has already gone away.
// Otherwise, wait for the parent process to exit before starting the
// update.
- if (parent) {
+ if (parent)
+ {
DWORD waitTime = PARENT_WAIT;
DWORD result = WaitForSingleObject(parent, waitTime);
CloseHandle(parent);
@@ -2826,15 +3072,19 @@ int NS_main(int argc, NS_tchar **argv)
HANDLE updateLockFileHandle = INVALID_HANDLE_VALUE;
NS_tchar elevatedLockFilePath[MAXPATHLEN] = {NS_T('\0')};
if (!sUsingService &&
- (argc > callbackIndex || sStagedUpdate || sReplaceRequest)) {
+ (argc > callbackIndex || sStagedUpdate || sReplaceRequest))
+ {
NS_tchar updateLockFilePath[MAXPATHLEN];
- if (sStagedUpdate) {
+ if (sStagedUpdate)
+ {
// When staging an update, the lock file is:
// <install_dir>\updated.update_in_progress.lock
NS_tsnprintf(updateLockFilePath,
- sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
- NS_T("%s/updated.update_in_progress.lock"), gInstallDirPath);
- } else if (sReplaceRequest) {
+ sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
+ NS_T("%s/updated.update_in_progress.lock"), gInstallDirPath);
+ }
+ else if (sReplaceRequest)
+ {
// When processing a replace request, the lock file is:
// <install_dir>\..\moz_update_in_progress.lock
NS_tchar installDir[MAXPATHLEN];
@@ -2842,24 +3092,28 @@ int NS_main(int argc, NS_tchar **argv)
NS_tchar *slash = (NS_tchar *) NS_tstrrchr(installDir, NS_SLASH);
*slash = NS_T('\0');
NS_tsnprintf(updateLockFilePath,
- sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
- NS_T("%s\\moz_update_in_progress.lock"), installDir);
- } else {
+ sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
+ NS_T("%s\\moz_update_in_progress.lock"), installDir);
+ }
+ else
+ {
// In the non-staging update case, the lock file is:
// <install_dir>\<app_name>.exe.update_in_progress.lock
NS_tsnprintf(updateLockFilePath,
- sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
- NS_T("%s.update_in_progress.lock"), argv[callbackIndex]);
+ sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
+ NS_T("%s.update_in_progress.lock"), argv[callbackIndex]);
}
// The update_in_progress.lock file should only exist during an update. In
// case it exists attempt to remove it and exit if that fails to prevent
// simultaneous updates occurring.
if (!_waccess(updateLockFilePath, F_OK) &&
- NS_tremove(updateLockFilePath) != 0) {
+ NS_tremove(updateLockFilePath) != 0)
+ {
// Try to fall back to the old way of doing updates if a staged
// update fails.
- if (sStagedUpdate || sReplaceRequest) {
+ if (sStagedUpdate || sReplaceRequest)
+ {
// Note that this could fail, but if it does, there isn't too much we
// can do in order to recover anyways.
WriteStatusFile("pending");
@@ -2869,16 +3123,16 @@ int NS_main(int argc, NS_tchar **argv)
}
updateLockFileHandle = CreateFileW(updateLockFilePath,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- nullptr,
- OPEN_ALWAYS,
- FILE_FLAG_DELETE_ON_CLOSE,
- nullptr);
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ nullptr,
+ OPEN_ALWAYS,
+ FILE_FLAG_DELETE_ON_CLOSE,
+ nullptr);
NS_tsnprintf(elevatedLockFilePath,
- sizeof(elevatedLockFilePath)/sizeof(elevatedLockFilePath[0]),
- NS_T("%s/update_elevated.lock"), gPatchDirPath);
+ sizeof(elevatedLockFilePath)/sizeof(elevatedLockFilePath[0]),
+ NS_T("%s/update_elevated.lock"), gPatchDirPath);
// Even if a file has no sharing access, you can still get its attributes
bool startedFromUnelevatedUpdater =
@@ -2890,36 +3144,41 @@ int NS_main(int argc, NS_tchar **argv)
// updater, then we drop the permissions here. We do not drop the
// permissions on the originally called updater because we use its token
// to start the callback application.
- if (startedFromUnelevatedUpdater) {
+ if (startedFromUnelevatedUpdater)
+ {
// Disable every privilege we don't need. Processes started using
// CreateProcess will use the same token as this process.
UACHelper::DisablePrivileges(nullptr);
}
if (updateLockFileHandle == INVALID_HANDLE_VALUE ||
- (useService && testOnlyFallbackKeyExists && noServiceFallback)) {
+ (useService && testOnlyFallbackKeyExists && noServiceFallback))
+ {
if (!_waccess(elevatedLockFilePath, F_OK) &&
- NS_tremove(elevatedLockFilePath) != 0) {
+ NS_tremove(elevatedLockFilePath) != 0)
+ {
fprintf(stderr, "Unable to create elevated lock file! Exiting\n");
return 1;
}
HANDLE elevatedFileHandle;
elevatedFileHandle = CreateFileW(elevatedLockFilePath,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- nullptr,
- OPEN_ALWAYS,
- FILE_FLAG_DELETE_ON_CLOSE,
- nullptr);
-
- if (elevatedFileHandle == INVALID_HANDLE_VALUE) {
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ nullptr,
+ OPEN_ALWAYS,
+ FILE_FLAG_DELETE_ON_CLOSE,
+ nullptr);
+
+ if (elevatedFileHandle == INVALID_HANDLE_VALUE)
+ {
LOG(("Unable to create elevated lock file! Exiting"));
return 1;
}
wchar_t *cmdLine = MakeCommandLine(argc - 1, argv + 1);
- if (!cmdLine) {
+ if (!cmdLine)
+ {
CloseHandle(elevatedFileHandle);
return 1;
}
@@ -2927,7 +3186,8 @@ int NS_main(int argc, NS_tchar **argv)
// Make sure the path to the updater to use for the update is on local.
// We do this check to make sure that file locking is available for
// race condition security checks.
- if (useService) {
+ if (useService)
+ {
BOOL isLocal = FALSE;
useService = IsLocalFile(argv[0], isLocal) && isLocal;
}
@@ -2938,36 +3198,46 @@ int NS_main(int argc, NS_tchar **argv)
// Windows 8 provides a user interface so users can configure this
// behavior and it can be configured in the registry in all Windows
// versions that support UAC.
- if (useService) {
+ if (useService)
+ {
BOOL unpromptedElevation;
- if (IsUnpromptedElevation(unpromptedElevation)) {
+ if (IsUnpromptedElevation(unpromptedElevation))
+ {
useService = !unpromptedElevation;
}
}
// Make sure the service registry entries for the installation path
// are available. If not don't use the service.
- if (useService) {
+ if (useService)
+ {
WCHAR maintenanceServiceKey[MAX_PATH + 1];
// TODO: moggi: needs adaption for LibreOffice
// Most likely the registry part is not correct yet
if (CalculateRegistryPathFromFilePath(gInstallDirPath,
- maintenanceServiceKey)) {
+ maintenanceServiceKey))
+ {
HKEY baseKey = nullptr;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- maintenanceServiceKey, 0,
- KEY_READ | KEY_WOW64_64KEY,
- &baseKey) == ERROR_SUCCESS) {
+ maintenanceServiceKey, 0,
+ KEY_READ | KEY_WOW64_64KEY,
+ &baseKey) == ERROR_SUCCESS)
+ {
RegCloseKey(baseKey);
- } else {
+ }
+ else
+ {
#ifdef TEST_UPDATER
useService = testOnlyFallbackKeyExists;
#endif
- if (!useService) {
+ if (!useService)
+ {
lastFallbackError = FALLBACKKEY_NOKEY_ERROR;
}
}
- } else {
+ }
+ else
+ {
useService = false;
lastFallbackError = FALLBACKKEY_REGPATH_ERROR;
}
@@ -2981,16 +3251,19 @@ int NS_main(int argc, NS_tchar **argv)
// If we still want to use the service try to launch the service
// comamnd for the update.
- if (useService) {
+ if (useService)
+ {
// If the update couldn't be started, then set useService to false so
// we do the update the old way.
DWORD ret = LaunchServiceSoftwareUpdateCommand(argc, (LPCWSTR *)argv);
useService = (ret == ERROR_SUCCESS);
// If the command was launched then wait for the service to be done.
- if (useService) {
+ if (useService)
+ {
bool showProgressUI = false;
// Never show the progress UI when staging updates.
- if (!sStagedUpdate) {
+ if (!sStagedUpdate)
+ {
// We need to call this separately instead of allowing ShowProgressUI
// to initialize the strings because the service will move the
// ini file out of the way when running updater.
@@ -3000,22 +3273,27 @@ int NS_main(int argc, NS_tchar **argv)
// Wait for the service to stop for 5 seconds. If the service
// has still not stopped then show an indeterminate progress bar.
DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
- if (lastState != SERVICE_STOPPED) {
+ if (lastState != SERVICE_STOPPED)
+ {
std::thread waitThread(WaitForServiceFinishThread, nullptr);
- if (showProgressUI) {
+ if (showProgressUI)
+ {
ShowProgressUI(true, false);
}
waitThread.join();
}
lastState = WaitForServiceStop(SVC_NAME, 1);
- if (lastState != SERVICE_STOPPED) {
+ if (lastState != SERVICE_STOPPED)
+ {
// If the service doesn't stop after 10 minutes there is
// something seriously wrong.
lastFallbackError = FALLBACKKEY_SERVICE_NO_STOP_ERROR;
useService = false;
}
- } else {
+ }
+ else
+ {
lastFallbackError = FALLBACKKEY_LAUNCH_ERROR;
}
}
@@ -3023,8 +3301,10 @@ int NS_main(int argc, NS_tchar **argv)
// If the service can't be used when staging and update, make sure that
// the UAC prompt is not shown! In this case, just set the status to
// pending and the update will be applied during the next startup.
- if (!useService && sStagedUpdate) {
- if (updateLockFileHandle != INVALID_HANDLE_VALUE) {
+ if (!useService && sStagedUpdate)
+ {
+ if (updateLockFileHandle != INVALID_HANDLE_VALUE)
+ {
CloseHandle(updateLockFileHandle);
}
WriteStatusFile("pending");
@@ -3038,11 +3318,14 @@ int NS_main(int argc, NS_tchar **argv)
// current process is running as.
// Note that we don't need to do this if we're just staging the update,
// as the PostUpdate step runs when performing the replacing in that case.
- if (useService && !sStagedUpdate) {
+ if (useService && !sStagedUpdate)
+ {
bool updateStatusSucceeded = false;
if (IsUpdateStatusSucceeded(updateStatusSucceeded) &&
- updateStatusSucceeded) {
- if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) {
+ updateStatusSucceeded)
+ {
+ if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath))
+ {
fprintf(stderr, "The post update process which runs as the user"
" for service update could not be launched.");
}
@@ -3056,13 +3339,14 @@ int NS_main(int argc, NS_tchar **argv)
// write access all along because in that case the only reason we're
// using the service is because we are testing.
if (!useService && !noServiceFallback &&
- updateLockFileHandle == INVALID_HANDLE_VALUE) {
+ updateLockFileHandle == INVALID_HANDLE_VALUE)
+ {
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
sinfo.fMask = SEE_MASK_FLAG_NO_UI |
- SEE_MASK_FLAG_DDEWAIT |
- SEE_MASK_NOCLOSEPROCESS;
+ SEE_MASK_FLAG_DDEWAIT |
+ SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = nullptr;
sinfo.lpFile = argv[0];
sinfo.lpParameters = cmdLine;
@@ -3072,35 +3356,45 @@ int NS_main(int argc, NS_tchar **argv)
bool result = ShellExecuteEx(&sinfo);
free(cmdLine);
- if (result) {
+ if (result)
+ {
WaitForSingleObject(sinfo.hProcess, INFINITE);
CloseHandle(sinfo.hProcess);
- } else {
+ }
+ else
+ {
WriteStatusFile(ELEVATION_CANCELED);
}
}
- if (argc > callbackIndex) {
+ if (argc > callbackIndex)
+ {
LaunchCallbackApp(argv[5], argc - callbackIndex,
- argv + callbackIndex, sUsingService);
+ argv + callbackIndex, sUsingService);
}
CloseHandle(elevatedFileHandle);
if (!useService && !noServiceFallback &&
- INVALID_HANDLE_VALUE == updateLockFileHandle) {
+ INVALID_HANDLE_VALUE == updateLockFileHandle)
+ {
// We didn't use the service and we did run the elevated updater.exe.
// The elevated updater.exe is responsible for writing out the
// update.status file.
return 0;
- } else if (useService) {
+ }
+ else if (useService)
+ {
// The service command was launched. The service is responsible for
// writing out the update.status file.
- if (updateLockFileHandle != INVALID_HANDLE_VALUE) {
+ if (updateLockFileHandle != INVALID_HANDLE_VALUE)
+ {
CloseHandle(updateLockFileHandle);
}
return 0;
- } else {
+ }
+ else
+ {
// Otherwise the service command was not launched at all.
// We are only reaching this code path because we had write access
// all along to the directory and a fallback key existed, and we
@@ -3114,17 +3408,21 @@ int NS_main(int argc, NS_tchar **argv)
}
#endif
- if (sStagedUpdate) {
+ if (sStagedUpdate)
+ {
// When staging updates, blow away the old installation directory and create
// it from scratch.
ensure_remove_recursive(gWorkingDirPath);
}
- if (!sReplaceRequest) {
+ if (!sReplaceRequest)
+ {
// Try to create the destination directory if it doesn't exist
int rv = NS_tmkdir(gWorkingDirPath, 0755);
- if (rv != OK && errno != EEXIST) {
+ if (rv != OK && errno != EEXIST)
+ {
#ifdef MACOSX
- if (isElevated) {
+ if (isElevated)
+ {
freeArguments(argc, argv);
CleanupElevatedMacUpdate(true);
}
@@ -3136,7 +3434,8 @@ int NS_main(int argc, NS_tchar **argv)
#ifdef _WIN32
// For replace requests, we don't need to do any real updates, so this is not
// necessary.
- if (!sReplaceRequest) {
+ if (!sReplaceRequest)
+ {
// Allocate enough space for the length of the path an optional additional
// trailing slash and null termination.
NS_tchar *destpath = (NS_tchar *) malloc((NS_tstrlen(gWorkingDirPath) + 2) * sizeof(NS_tchar));
@@ -3147,7 +3446,8 @@ int NS_main(int argc, NS_tchar **argv)
NS_tstrcpy(c, gWorkingDirPath);
c += NS_tstrlen(gWorkingDirPath);
if (gWorkingDirPath[NS_tstrlen(gWorkingDirPath) - 1] != NS_T('/') &&
- gWorkingDirPath[NS_tstrlen(gWorkingDirPath) - 1] != NS_T('\\')) {
+ gWorkingDirPath[NS_tstrlen(gWorkingDirPath) - 1] != NS_T('\\'))
+ {
NS_tstrcat(c, NS_T("/"));
c += NS_tstrlen(NS_T("/"));
}
@@ -3159,20 +3459,23 @@ int NS_main(int argc, NS_tchar **argv)
NS_tchar applyDirLongPath[MAXPATHLEN];
if (!GetLongPathNameW(gWorkingDirPath, applyDirLongPath,
- sizeof(applyDirLongPath)/sizeof(applyDirLongPath[0]))) {
+ sizeof(applyDirLongPath)/sizeof(applyDirLongPath[0])))
+ {
LOG(("NS_main: unable to find apply to dir: " LOG_S, gWorkingDirPath));
LogFinish();
WriteStatusFile(WRITE_ERROR_APPLY_DIR_PATH);
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
- if (argc > callbackIndex) {
+ if (argc > callbackIndex)
+ {
LaunchCallbackApp(argv[5], argc - callbackIndex,
- argv + callbackIndex, sUsingService);
+ argv + callbackIndex, sUsingService);
}
return 1;
}
HANDLE callbackFile = INVALID_HANDLE_VALUE;
- if (argc > callbackIndex) {
+ if (argc > callbackIndex)
+ {
// If the callback executable is specified it must exist for a successful
// update. It is important we null out the whole buffer here because later
// we make the assumption that the callback application is inside the
@@ -3183,12 +3486,13 @@ int NS_main(int argc, NS_tchar **argv)
NS_tchar *targetPath = argv[callbackIndex];
NS_tchar buffer[MAXPATHLEN * 2] = { NS_T('\0') };
size_t bufferLeft = MAXPATHLEN * 2;
- if (sReplaceRequest) {
+ if (sReplaceRequest)
+ {
// In case of replace requests, we should look for the callback file in
// the destination directory.
size_t commonPrefixLength = PathCommonPrefixW(argv[callbackIndex],
- gInstallDirPath,
- nullptr);
+ gInstallDirPath,
+ nullptr);
NS_tchar *p = buffer;
NS_tstrncpy(p, argv[callbackIndex], commonPrefixLength);
p += commonPrefixLength;
@@ -3205,29 +3509,32 @@ int NS_main(int argc, NS_tchar **argv)
NS_tchar installDir[MAXPATHLEN];
NS_tstrcpy(installDir, gInstallDirPath);
size_t callbackPrefixLength = PathCommonPrefixW(argv[callbackIndex],
- installDir,
- nullptr);
+ installDir,
+ nullptr);
NS_tstrncpy(p, argv[callbackIndex] + std::max(callbackPrefixLength,
commonPrefixLength), bufferLeft);
targetPath = buffer;
}
if (!GetLongPathNameW(targetPath, callbackLongPath,
- sizeof(callbackLongPath)/sizeof(callbackLongPath[0]))) {
+ sizeof(callbackLongPath)/sizeof(callbackLongPath[0])))
+ {
LOG(("NS_main: unable to find callback file: " LOG_S, targetPath));
LogFinish();
WriteStatusFile(WRITE_ERROR_CALLBACK_PATH);
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
- if (argc > callbackIndex) {
+ if (argc > callbackIndex)
+ {
LaunchCallbackApp(argv[5],
- argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ argc - callbackIndex,
+ argv + callbackIndex,
+ sUsingService);
}
return 1;
}
// Doing this is only necessary when we're actually applying a patch.
- if (!sReplaceRequest) {
+ if (!sReplaceRequest)
+ {
int len = NS_tstrlen(applyDirLongPath);
NS_tchar *s = callbackLongPath;
NS_tchar *d = gCallbackRelPath;
@@ -3239,160 +3546,182 @@ int NS_main(int argc, NS_tchar **argv)
// Copy the string and replace backslashes with forward slashes along the
// way.
- do {
+ do
+ {
if (*s == NS_T('\\'))
*d = NS_T('/');
else
*d = *s;
++s;
++d;
- } while (*s);
+ }
+ while (*s);
*d = NS_T('\0');
++d;
// Make a copy of the callback executable so it can be read when patching.
NS_tsnprintf(gCallbackBackupPath,
- sizeof(gCallbackBackupPath)/sizeof(gCallbackBackupPath[0]),
- NS_T("%s" CALLBACK_BACKUP_EXT), argv[callbackIndex]);
+ sizeof(gCallbackBackupPath)/sizeof(gCallbackBackupPath[0]),
+ NS_T("%s" CALLBACK_BACKUP_EXT), argv[callbackIndex]);
NS_tremove(gCallbackBackupPath);
- if(!CopyFileW(argv[callbackIndex], gCallbackBackupPath, true)) {
+ if (!CopyFileW(argv[callbackIndex], gCallbackBackupPath, true))
+ {
DWORD copyFileError = GetLastError();
LOG(("NS_main: failed to copy callback file " LOG_S
- " into place at " LOG_S, argv[callbackIndex], gCallbackBackupPath));
+ " into place at " LOG_S, argv[callbackIndex], gCallbackBackupPath));
LogFinish();
- if (copyFileError == ERROR_ACCESS_DENIED) {
+ if (copyFileError == ERROR_ACCESS_DENIED)
+ {
WriteStatusFile(WRITE_ERROR_ACCESS_DENIED);
- } else {
+ }
+ else
+ {
+ WriteStatusFile(WRITE_ERROR_CALLBACK_APP);
+ }
+
+ EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
+ LaunchCallbackApp(argv[callbackIndex],
+ argc - callbackIndex,
+ argv + callbackIndex,
+ sUsingService);
+ return 1;
+ }
+
+ // Since the process may be signaled as exited by WaitForSingleObject before
+ // the release of the executable image try to lock the main executable file
+ // multiple times before giving up. If we end up giving up, we won't
+ // fail the update.
+ const int max_retries = 10;
+ int retries = 1;
+ DWORD lastWriteError = 0;
+ do
+ {
+ // By opening a file handle wihout FILE_SHARE_READ to the callback
+ // executable, the OS will prevent launching the process while it is
+ // being updated.
+ callbackFile = CreateFileW(targetPath,
+ DELETE | GENERIC_WRITE,
+ // allow delete, rename, and write
+ FILE_SHARE_DELETE | FILE_SHARE_WRITE,
+ nullptr, OPEN_EXISTING, 0, nullptr);
+ if (callbackFile != INVALID_HANDLE_VALUE)
+ break;
+
+ lastWriteError = GetLastError();
+ LOG(("NS_main: callback app file open attempt %d failed. " \
+ "File: " LOG_S ". Last error: %d", retries,
+ targetPath, lastWriteError));
+
+ Sleep(100);
+ }
+ while (++retries <= max_retries);
+
+ // CreateFileW will fail if the callback executable is already in use.
+ if (callbackFile == INVALID_HANDLE_VALUE)
+ {
+ // Only fail the update if the last error was not a sharing violation.
+ if (lastWriteError != ERROR_SHARING_VIOLATION)
+ {
+ LOG(("NS_main: callback app file in use, failed to exclusively open " \
+ "executable file: " LOG_S, argv[callbackIndex]));
+ LogFinish();
+ if (lastWriteError == ERROR_ACCESS_DENIED)
+ {
+ WriteStatusFile(WRITE_ERROR_ACCESS_DENIED);
+ }
+ else
+ {
WriteStatusFile(WRITE_ERROR_CALLBACK_APP);
}
+ NS_tremove(gCallbackBackupPath);
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
- LaunchCallbackApp(argv[callbackIndex],
- argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ LaunchCallbackApp(argv[5],
+ argc - callbackIndex,
+ argv + callbackIndex,
+ sUsingService);
return 1;
}
-
- // Since the process may be signaled as exited by WaitForSingleObject before
- // the release of the executable image try to lock the main executable file
- // multiple times before giving up. If we end up giving up, we won't
- // fail the update.
- const int max_retries = 10;
- int retries = 1;
- DWORD lastWriteError = 0;
- do {
- // By opening a file handle wihout FILE_SHARE_READ to the callback
- // executable, the OS will prevent launching the process while it is
- // being updated.
- callbackFile = CreateFileW(targetPath,
- DELETE | GENERIC_WRITE,
- // allow delete, rename, and write
- FILE_SHARE_DELETE | FILE_SHARE_WRITE,
- nullptr, OPEN_EXISTING, 0, nullptr);
- if (callbackFile != INVALID_HANDLE_VALUE)
- break;
-
- lastWriteError = GetLastError();
- LOG(("NS_main: callback app file open attempt %d failed. " \
- "File: " LOG_S ". Last error: %d", retries,
- targetPath, lastWriteError));
-
- Sleep(100);
- } while (++retries <= max_retries);
-
- // CreateFileW will fail if the callback executable is already in use.
- if (callbackFile == INVALID_HANDLE_VALUE) {
- // Only fail the update if the last error was not a sharing violation.
- if (lastWriteError != ERROR_SHARING_VIOLATION) {
- LOG(("NS_main: callback app file in use, failed to exclusively open " \
- "executable file: " LOG_S, argv[callbackIndex]));
- LogFinish();
- if (lastWriteError == ERROR_ACCESS_DENIED) {
- WriteStatusFile(WRITE_ERROR_ACCESS_DENIED);
- } else {
- WriteStatusFile(WRITE_ERROR_CALLBACK_APP);
- }
-
- NS_tremove(gCallbackBackupPath);
- EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
- LaunchCallbackApp(argv[5],
- argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
- return 1;
- }
- LOG(("NS_main: callback app file in use, continuing without " \
- "exclusive access for executable file: " LOG_S,
- argv[callbackIndex]));
- }
+ LOG(("NS_main: callback app file in use, continuing without " \
+ "exclusive access for executable file: " LOG_S,
+ argv[callbackIndex]));
}
}
+ }
- // DELETE_DIR is not required when performing a staged update or replace
- // request; it can be used during a replace request but then it doesn't
- // use gDeleteDirPath.
- if (!sStagedUpdate && !sReplaceRequest) {
- // The directory to move files that are in use to on Windows. This directory
- // will be deleted after the update is finished, on OS reboot using
- // MoveFileEx if it contains files that are in use, or by the post update
- // process after the update finishes. On Windows when performing a normal
- // update (e.g. the update is not a staged update and is not a replace
- // request) gWorkingDirPath is the same as gInstallDirPath and
- // gWorkingDirPath is used because it is the destination directory.
- NS_tsnprintf(gDeleteDirPath,
- sizeof(gDeleteDirPath) / sizeof(gDeleteDirPath[0]),
- NS_T("%s/%s"), gWorkingDirPath, DELETE_DIR);
-
- if (NS_taccess(gDeleteDirPath, F_OK)) {
- NS_tmkdir(gDeleteDirPath, 0755);
- }
+ // DELETE_DIR is not required when performing a staged update or replace
+ // request; it can be used during a replace request but then it doesn't
+ // use gDeleteDirPath.
+ if (!sStagedUpdate && !sReplaceRequest)
+ {
+ // The directory to move files that are in use to on Windows. This directory
+ // will be deleted after the update is finished, on OS reboot using
+ // MoveFileEx if it contains files that are in use, or by the post update
+ // process after the update finishes. On Windows when performing a normal
+ // update (e.g. the update is not a staged update and is not a replace
+ // request) gWorkingDirPath is the same as gInstallDirPath and
+ // gWorkingDirPath is used because it is the destination directory.
+ NS_tsnprintf(gDeleteDirPath,
+ sizeof(gDeleteDirPath) / sizeof(gDeleteDirPath[0]),
+ NS_T("%s/%s"), gWorkingDirPath, DELETE_DIR);
+
+ if (NS_taccess(gDeleteDirPath, F_OK))
+ {
+ NS_tmkdir(gDeleteDirPath, 0755);
}
+ }
#endif /* _WIN32 */
- // Run update process on a background thread. ShowProgressUI may return
- // before QuitProgressUI has been called, so wait for UpdateThreadFunc to
- // terminate. Avoid showing the progress UI when staging an update, or if this
- // is an elevated process on OSX.
- std::thread t(UpdateThreadFunc, nullptr);
- if (!sStagedUpdate && !sReplaceRequest
+ // Run update process on a background thread. ShowProgressUI may return
+ // before QuitProgressUI has been called, so wait for UpdateThreadFunc to
+ // terminate. Avoid showing the progress UI when staging an update, or if this
+ // is an elevated process on OSX.
+ std::thread t(UpdateThreadFunc, nullptr);
+ if (!sStagedUpdate && !sReplaceRequest
#ifdef XP_MACOSX
- && !isElevated
+ && !isElevated
#endif
- ) {
- ShowProgressUI();
- }
- t.join();
+ )
+ {
+ ShowProgressUI();
+ }
+ t.join();
#ifdef _WIN32
- if (argc > callbackIndex && !sReplaceRequest) {
- if (callbackFile != INVALID_HANDLE_VALUE) {
- CloseHandle(callbackFile);
- }
- // Remove the copy of the callback executable.
- NS_tremove(gCallbackBackupPath);
+ if (argc > callbackIndex && !sReplaceRequest)
+ {
+ if (callbackFile != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(callbackFile);
}
+ // Remove the copy of the callback executable.
+ NS_tremove(gCallbackBackupPath);
+ }
- if (!sStagedUpdate && !sReplaceRequest && _wrmdir(gDeleteDirPath)) {
- LOG(("NS_main: unable to remove directory: " LOG_S ", err: %d",
- DELETE_DIR, errno));
- // The directory probably couldn't be removed due to it containing files
- // that are in use and will be removed on OS reboot. The call to remove the
- // directory on OS reboot is done after the calls to remove the files so the
- // files are removed first on OS reboot since the directory must be empty
- // for the directory removal to be successful. The MoveFileEx call to remove
- // the directory on OS reboot will fail if the process doesn't have write
- // access to the HKEY_LOCAL_MACHINE registry key but this is ok since the
- // installer / uninstaller will delete the directory along with its contents
- // after an update is applied, on reinstall, and on uninstall.
- if (MoveFileEx(gDeleteDirPath, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
- LOG(("NS_main: directory will be removed on OS reboot: " LOG_S,
- DELETE_DIR));
- } else {
- LOG(("NS_main: failed to schedule OS reboot removal of " \
- "directory: " LOG_S, DELETE_DIR));
- }
+ if (!sStagedUpdate && !sReplaceRequest && _wrmdir(gDeleteDirPath))
+ {
+ LOG(("NS_main: unable to remove directory: " LOG_S ", err: %d",
+ DELETE_DIR, errno));
+ // The directory probably couldn't be removed due to it containing files
+ // that are in use and will be removed on OS reboot. The call to remove the
+ // directory on OS reboot is done after the calls to remove the files so the
+ // files are removed first on OS reboot since the directory must be empty
+ // for the directory removal to be successful. The MoveFileEx call to remove
+ // the directory on OS reboot will fail if the process doesn't have write
+ // access to the HKEY_LOCAL_MACHINE registry key but this is ok since the
+ // installer / uninstaller will delete the directory along with its contents
+ // after an update is applied, on reinstall, and on uninstall.
+ if (MoveFileEx(gDeleteDirPath, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT))
+ {
+ LOG(("NS_main: directory will be removed on OS reboot: " LOG_S,
+ DELETE_DIR));
}
+ else
+ {
+ LOG(("NS_main: failed to schedule OS reboot removal of " \
+ "directory: " LOG_S, DELETE_DIR));
+ }
+ }
#endif /* WNT */
@@ -3401,45 +3730,55 @@ int NS_main(int argc, NS_tchar **argv)
// the application bundle and move the distribution directory from
// Contents/MacOS to Contents/Resources and if both exist delete the
// directory under Contents/MacOS (see Bug 1068439).
- if (gSucceeded && !sStagedUpdate) {
+ if (gSucceeded && !sStagedUpdate)
+ {
NS_tchar oldPrecomplete[MAXPATHLEN];
NS_tsnprintf(oldPrecomplete, sizeof(oldPrecomplete)/sizeof(oldPrecomplete[0]),
- NS_T("%s/precomplete"), gInstallDirPath);
+ NS_T("%s/precomplete"), gInstallDirPath);
NS_tremove(oldPrecomplete);
NS_tchar oldDistDir[MAXPATHLEN];
NS_tsnprintf(oldDistDir, sizeof(oldDistDir)/sizeof(oldDistDir[0]),
- NS_T("%s/Contents/MacOS/distribution"), gInstallDirPath);
+ NS_T("%s/Contents/MacOS/distribution"), gInstallDirPath);
int rv = NS_taccess(oldDistDir, F_OK);
- if (!rv) {
+ if (!rv)
+ {
NS_tchar newDistDir[MAXPATHLEN];
NS_tsnprintf(newDistDir, sizeof(newDistDir)/sizeof(newDistDir[0]),
- NS_T("%s/Contents/Resources/distribution"), gInstallDirPath);
+ NS_T("%s/Contents/Resources/distribution"), gInstallDirPath);
rv = NS_taccess(newDistDir, F_OK);
- if (!rv) {
+ if (!rv)
+ {
LOG(("New distribution directory already exists... removing old " \
- "distribution directory: " LOG_S, oldDistDir));
+ "distribution directory: " LOG_S, oldDistDir));
rv = ensure_remove_recursive(oldDistDir);
- if (rv) {
+ if (rv)
+ {
LOG(("Removing old distribution directory failed - err: %d", rv));
}
- } else {
+ }
+ else
+ {
LOG(("Moving old distribution directory to new location. src: " LOG_S \
- ", dst:" LOG_S, oldDistDir, newDistDir));
+ ", dst:" LOG_S, oldDistDir, newDistDir));
rv = rename_file(oldDistDir, newDistDir, true);
- if (rv) {
+ if (rv)
+ {
LOG(("Moving old distribution directory to new location failed - " \
- "err: %d", rv));
+ "err: %d", rv));
}
}
}
}
- if (isElevated) {
+ if (isElevated)
+ {
SetGroupOwnershipAndPermissions(gInstallDirPath);
freeArguments(argc, argv);
CleanupElevatedMacUpdate(false);
- } else if (IsOwnedByGroupAdmin(gInstallDirPath)) {
+ }
+ else if (IsOwnedByGroupAdmin(gInstallDirPath))
+ {
// If the group ownership of the Firefox .app bundle was set to the "admin"
// group during a previous elevated update, we need to ensure that all files
// in the bundle have group ownership of "admin" as well as write permission
@@ -3452,12 +3791,12 @@ int NS_main(int argc, NS_tchar **argv)
int retVal = LaunchCallbackAndPostProcessApps(argc, argv, callbackIndex
#ifdef _WIN32
- , elevatedLockFilePath
- , updateLockFileHandle
+ , elevatedLockFilePath
+ , updateLockFileHandle
#elif defined(MACOSX)
- , isElevated
+ , isElevated
#endif
- );
+ );
return retVal ? retVal : (gSucceeded ? 0 : 1);
}
@@ -3482,7 +3821,8 @@ private:
ActionList::~ActionList()
{
Action* a = mFirst;
- while (a) {
+ while (a)
+ {
Action *b = a;
a = a->mNext;
delete b;
@@ -3507,14 +3847,16 @@ ActionList::Prepare()
// If the action list is empty then we should fail in order to signal that
// something has gone wrong. Otherwise we report success when nothing is
// actually done. See bug 327140.
- if (mCount == 0) {
+ if (mCount == 0)
+ {
LOG(("empty action list"));
return MAR_ERROR_EMPTY_ACTION_LIST;
}
Action *a = mFirst;
int i = 0;
- while (a) {
+ while (a)
+ {
int rv = a->Prepare();
if (rv)
return rv;
@@ -3533,15 +3875,18 @@ ActionList::Execute()
{
int currentProgress = 0, maxProgress = 0;
Action *a = mFirst;
- while (a) {
+ while (a)
+ {
maxProgress += a->mProgressCost;
a = a->mNext;
}
a = mFirst;
- while (a) {
+ while (a)
+ {
int rv = a->Execute();
- if (rv) {
+ if (rv)
+ {
LOG(("### execution failed"));
return rv;
}
@@ -3549,7 +3894,7 @@ ActionList::Execute()
currentProgress += a->mProgressCost;
float percent = float(currentProgress) / float(maxProgress);
UpdateProgressUI(PROGRESS_PREPARE_SIZE +
- PROGRESS_EXECUTE_SIZE * percent);
+ PROGRESS_EXECUTE_SIZE * percent);
a = a->mNext;
}
@@ -3562,13 +3907,14 @@ ActionList::Finish(int status)
{
Action *a = mFirst;
int i = 0;
- while (a) {
+ while (a)
+ {
a->Finish(status);
float percent = float(++i) / float(mCount);
UpdateProgressUI(PROGRESS_PREPARE_SIZE +
- PROGRESS_EXECUTE_SIZE +
- PROGRESS_FINISH_SIZE * percent);
+ PROGRESS_EXECUTE_SIZE +
+ PROGRESS_FINISH_SIZE * percent);
a = a->mNext;
}
@@ -3588,29 +3934,35 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
NS_tchar foundpath[MAXPATHLEN];
NS_tsnprintf(searchspec, sizeof(searchspec)/sizeof(searchspec[0]),
- NS_T("%s*"), dirpath);
+ NS_T("%s*"), dirpath);
std::unique_ptr<const NS_tchar> pszSpec(get_full_path(searchspec));
hFindFile = FindFirstFileW(pszSpec.get(), &finddata);
- if (hFindFile != INVALID_HANDLE_VALUE) {
- do {
+ if (hFindFile != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
// Don't process the current or parent directory.
if (NS_tstrcmp(finddata.cFileName, NS_T(".")) == 0 ||
NS_tstrcmp(finddata.cFileName, NS_T("..")) == 0)
continue;
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s%s"), dirpath, finddata.cFileName);
- if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ NS_T("%s%s"), dirpath, finddata.cFileName);
+ if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s/"), foundpath);
+ NS_T("%s/"), foundpath);
// Recurse into the directory.
rv = add_dir_entries(foundpath, list);
- if (rv) {
+ if (rv)
+ {
LOG(("add_dir_entries error: " LOG_S ", err: %d", foundpath, rv));
return rv;
}
- } else {
+ }
+ else
+ {
// Add the file to be removed to the ActionList.
NS_tchar *quotedpath = get_quoted_path(foundpath);
if (!quotedpath)
@@ -3618,16 +3970,18 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
Action *action = new RemoveFile();
rv = action->Parse(quotedpath);
- if (rv) {
+ if (rv)
+ {
LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d",
- quotedpath, rv));
+ quotedpath, rv));
return rv;
}
free(quotedpath);
list->Append(action);
}
- } while (FindNextFileW(hFindFile, &finddata) != 0);
+ }
+ while (FindNextFileW(hFindFile, &finddata) != 0);
FindClose(hFindFile);
{
@@ -3640,7 +3994,7 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
rv = action->Parse(quotedpath);
if (rv)
LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d",
- quotedpath, rv));
+ quotedpath, rv));
else
list->Append(action);
free(quotedpath);
@@ -3655,7 +4009,8 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
{
int rv = OK;
NS_tchar foundpath[MAXPATHLEN];
- struct {
+ struct
+ {
dirent dent_buffer;
char chars[MAXNAMLEN];
} ent_buf;
@@ -3663,48 +4018,57 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
std::unique_ptr<NS_tchar> searchpath(get_full_path(dirpath));
DIR* dir = opendir(searchpath.get());
- if (!dir) {
+ if (!dir)
+ {
LOG(("add_dir_entries error on opendir: " LOG_S ", err: %d", searchpath.get(),
- errno));
+ errno));
return UNEXPECTED_FILE_OPERATION_ERROR;
}
- while (readdir_r(dir, (dirent *)&ent_buf, &ent) == 0 && ent) {
+ while (readdir_r(dir, (dirent *)&ent_buf, &ent) == 0 && ent)
+ {
if ((strcmp(ent->d_name, ".") == 0) ||
(strcmp(ent->d_name, "..") == 0))
continue;
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s%s"), searchpath.get(), ent->d_name);
+ NS_T("%s%s"), searchpath.get(), ent->d_name);
struct stat64 st_buf;
int test = stat64(foundpath, &st_buf);
- if (test) {
+ if (test)
+ {
closedir(dir);
return UNEXPECTED_FILE_OPERATION_ERROR;
}
- if (S_ISDIR(st_buf.st_mode)) {
+ if (S_ISDIR(st_buf.st_mode))
+ {
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s/"), foundpath);
+ NS_T("%s/"), foundpath);
// Recurse into the directory.
rv = add_dir_entries(foundpath, list);
- if (rv) {
+ if (rv)
+ {
LOG(("add_dir_entries error: " LOG_S ", err: %d", foundpath, rv));
closedir(dir);
return rv;
}
- } else {
+ }
+ else
+ {
// Add the file to be removed to the ActionList.
NS_tchar *quotedpath = get_quoted_path(get_relative_path(foundpath));
- if (!quotedpath) {
+ if (!quotedpath)
+ {
closedir(dir);
return PARSE_ERROR;
}
Action *action = new RemoveFile();
rv = action->Parse(quotedpath);
- if (rv) {
+ if (rv)
+ {
LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d",
- quotedpath, rv));
+ quotedpath, rv));
closedir(dir);
return rv;
}
@@ -3721,11 +4085,13 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
Action *action = new RemoveDir();
rv = action->Parse(quotedpath);
- if (rv) {
+ if (rv)
+ {
LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d",
- quotedpath, rv));
+ quotedpath, rv));
}
- else {
+ else
+ {
list->Append(action);
}
@@ -3749,32 +4115,35 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
// FTS_NOCHDIR is used so relative paths from the destination directory are
// returned.
if (!(ftsdir = fts_open(pathargv,
- FTS_PHYSICAL | FTS_NOSTAT | FTS_XDEV | FTS_NOCHDIR,
- nullptr)))
+ FTS_PHYSICAL | FTS_NOSTAT | FTS_XDEV | FTS_NOCHDIR,
+ nullptr)))
return UNEXPECTED_FILE_OPERATION_ERROR;
- while ((ftsdirEntry = fts_read(ftsdir)) != nullptr) {
+ while ((ftsdirEntry = fts_read(ftsdir)) != nullptr)
+ {
NS_tchar foundpath[MAXPATHLEN];
NS_tchar *quotedpath = nullptr;
Action *action = nullptr;
- switch (ftsdirEntry->fts_info) {
+ switch (ftsdirEntry->fts_info)
+ {
// Filesystem objects that shouldn't be in the application's directories
case FTS_SL:
case FTS_SLNONE:
case FTS_DEFAULT:
LOG(("add_dir_entries: found a non-standard file: " LOG_S,
- ftsdirEntry->fts_path));
- // Fall through and try to remove as a file
+ ftsdirEntry->fts_path));
+ // Fall through and try to remove as a file
- // Files
+ // Files
case FTS_F:
case FTS_NSOK:
// Add the file to be removed to the ActionList.
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s"), ftsdirEntry->fts_accpath);
+ NS_T("%s"), ftsdirEntry->fts_accpath);
quotedpath = get_quoted_path(get_relative_path(foundpath));
- if (!quotedpath) {
+ if (!quotedpath)
+ {
rv = UPDATER_QUOTED_PATH_MEM_ERROR;
break;
}
@@ -3783,16 +4152,17 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
free(quotedpath);
if (!rv)
list->Append(action);
- break;
+ break;
// Directories
case FTS_DP:
rv = OK;
// Add the directory to be removed to the ActionList.
NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]),
- NS_T("%s/"), ftsdirEntry->fts_accpath);
+ NS_T("%s/"), ftsdirEntry->fts_accpath);
quotedpath = get_quoted_path(get_relative_path(foundpath));
- if (!quotedpath) {
+ if (!quotedpath)
+ {
rv = UPDATER_QUOTED_PATH_MEM_ERROR;
break;
}
@@ -3802,7 +4172,7 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
free(quotedpath);
if (!rv)
list->Append(action);
- break;
+ break;
// Errors
case FTS_DNR:
@@ -3810,28 +4180,29 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list)
// ENOENT is an acceptable error for FTS_DNR and FTS_NS and means that
// we're racing with ourselves. Though strange, the entry will be
// removed anyway.
- if (ENOENT == ftsdirEntry->fts_errno) {
+ if (ENOENT == ftsdirEntry->fts_errno)
+ {
rv = OK;
break;
}
- // Fall through
+ // Fall through
case FTS_ERR:
rv = UNEXPECTED_FILE_OPERATION_ERROR;
LOG(("add_dir_entries: fts_read() error: " LOG_S ", err: %d",
- ftsdirEntry->fts_path, ftsdirEntry->fts_errno));
- break;
+ ftsdirEntry->fts_path, ftsdirEntry->fts_errno));
+ break;
case FTS_DC:
rv = UNEXPECTED_FILE_OPERATION_ERROR;
LOG(("add_dir_entries: fts_read() returned FT_DC: " LOG_S,
- ftsdirEntry->fts_path));
- break;
+ ftsdirEntry->fts_path));
+ break;
default:
// FTS_D is ignored and FTS_DP is used instead (post-order).
rv = OK;
- break;
+ break;
}
if (rv != OK)
@@ -3848,14 +4219,16 @@ static NS_tchar*
GetManifestContents(const NS_tchar *manifest)
{
AutoFile mfile(NS_tfopen(manifest, NS_T("rb")));
- if (mfile == nullptr) {
+ if (mfile == nullptr)
+ {
LOG(("GetManifestContents: error opening manifest file: " LOG_S, manifest));
return nullptr;
}
struct stat ms;
int rv = fstat(fileno((FILE *)mfile), &ms);
- if (rv) {
+ if (rv)
+ {
LOG(("GetManifestContents: error stating manifest file: " LOG_S, manifest));
return nullptr;
}
@@ -3866,10 +4239,12 @@ GetManifestContents(const NS_tchar *manifest)
size_t r = ms.st_size;
char *rb = mbuf;
- while (r) {
+ while (r)
+ {
const size_t count = std::min<size_t>(SSIZE_MAX, r);
size_t c = fread(rb, 1, count, mfile);
- if (c != count) {
+ if (c != count)
+ {
LOG(("GetManifestContents: error reading manifest file: " LOG_S, manifest));
free(mbuf);
return nullptr;
@@ -3885,13 +4260,15 @@ GetManifestContents(const NS_tchar *manifest)
return rb;
#else
NS_tchar *wrb = (NS_tchar *) malloc((ms.st_size + 1) * sizeof(NS_tchar));
- if (!wrb) {
+ if (!wrb)
+ {
free(mbuf);
return nullptr;
}
if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, rb, -1, wrb,
- ms.st_size + 1)) {
+ ms.st_size + 1))
+ {
LOG(("GetManifestContents: error converting utf8 to utf16le: %d", GetLastError()));
free(mbuf);
free(wrb);
@@ -3907,16 +4284,17 @@ int AddPreCompleteActions(ActionList *list)
{
#ifdef MACOSX
std::unique_ptr<NS_tchar> manifestPath(get_full_path(
- NS_T("Contents/Resources/precomplete")));
+ NS_T("Contents/Resources/precomplete")));
#else
std::unique_ptr<NS_tchar> manifestPath(get_full_path(
- NS_T("precomplete")));
+ NS_T("precomplete")));
#endif
NS_tchar *rb = GetManifestContents(manifestPath.get());
- if (rb == nullptr) {
+ if (rb == nullptr)
+ {
LOG(("AddPreCompleteActions: error getting contents of precomplete " \
- "manifest"));
+ "manifest"));
// Applications aren't required to have a precomplete manifest. The mar
// generation scripts enforce the presence of a precomplete manifest.
return OK;
@@ -3924,28 +4302,34 @@ int AddPreCompleteActions(ActionList *list)
int rv;
NS_tchar *line;
- while((line = mstrtok(kNL, &rb)) != 0) {
+ while ((line = mstrtok(kNL, &rb)) != 0)
+ {
// skip comments
if (*line == NS_T('#'))
continue;
NS_tchar *token = mstrtok(kWhitespace, &line);
- if (!token) {
+ if (!token)
+ {
LOG(("AddPreCompleteActions: token not found in manifest"));
return PARSE_ERROR;
}
Action *action = nullptr;
- if (NS_tstrcmp(token, NS_T("remove")) == 0) { // rm file
+ if (NS_tstrcmp(token, NS_T("remove")) == 0) // rm file
+ {
action = new RemoveFile();
}
- else if (NS_tstrcmp(token, NS_T("remove-cc")) == 0) { // no longer supported
+ else if (NS_tstrcmp(token, NS_T("remove-cc")) == 0) // no longer supported
+ {
continue;
}
- else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) { // rmdir if empty
+ else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) // rmdir if empty
+ {
action = new RemoveDir();
}
- else {
+ else
+ {
LOG(("AddPreCompleteActions: unknown token: " LOG_S, token));
return PARSE_ERROR;
}
@@ -3967,16 +4351,18 @@ int DoUpdate()
{
NS_tchar manifest[MAXPATHLEN];
NS_tsnprintf(manifest, sizeof(manifest)/sizeof(manifest[0]),
- NS_T("%s/updating/update.manifest"), gWorkingDirPath);
+ NS_T("%s/updating/update.manifest"), gWorkingDirPath);
ensure_parent_dir(manifest);
// extract the manifest
// TODO: moggi: needs adaption for LibreOffice
// Why would we need the manifest? Even if we need it why would we need 2?
int rv = gArchiveReader.ExtractFile("updatev3.manifest", manifest);
- if (rv) {
+ if (rv)
+ {
rv = gArchiveReader.ExtractFile("updatev2.manifest", manifest);
- if (rv) {
+ if (rv)
+ {
LOG(("DoUpdate: error extracting manifest file"));
return rv;
}
@@ -3984,7 +4370,8 @@ int DoUpdate()
NS_tchar *rb = GetManifestContents(manifest);
NS_tremove(manifest);
- if (rb == nullptr) {
+ if (rb == nullptr)
+ {
LOG(("DoUpdate: error opening manifest file: " LOG_S, manifest));
return READ_ERROR;
}
@@ -3994,25 +4381,30 @@ int DoUpdate()
NS_tchar *line;
bool isFirstAction = true;
- while((line = mstrtok(kNL, &rb)) != 0) {
+ while ((line = mstrtok(kNL, &rb)) != 0)
+ {
// skip comments
if (*line == NS_T('#'))
continue;
NS_tchar *token = mstrtok(kWhitespace, &line);
- if (!token) {
+ if (!token)
+ {
LOG(("DoUpdate: token not found in manifest"));
return PARSE_ERROR;
}
- if (isFirstAction) {
+ if (isFirstAction)
+ {
isFirstAction = false;
// The update manifest isn't required to have a type declaration. The mar
// generation scripts enforce the presence of the type declaration.
- if (NS_tstrcmp(token, NS_T("type")) == 0) {
+ if (NS_tstrcmp(token, NS_T("type")) == 0)
+ {
const NS_tchar *type = mstrtok(kQuote, &line);
LOG(("UPDATE TYPE " LOG_S, type));
- if (NS_tstrcmp(type, NS_T("complete")) == 0) {
+ if (NS_tstrcmp(type, NS_T("complete")) == 0)
+ {
rv = AddPreCompleteActions(&list);
if (rv)
return rv;
@@ -4022,13 +4414,16 @@ int DoUpdate()
}
Action *action = nullptr;
- if (NS_tstrcmp(token, NS_T("remove")) == 0) { // rm file
+ if (NS_tstrcmp(token, NS_T("remove")) == 0) // rm file
+ {
action = new RemoveFile();
}
- else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) { // rmdir if empty
+ else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) // rmdir if empty
+ {
action = new RemoveDir();
}
- else if (NS_tstrcmp(token, NS_T("rmrfdir")) == 0) { // rmdir recursive
+ else if (NS_tstrcmp(token, NS_T("rmrfdir")) == 0) // rmdir recursive
+ {
const NS_tchar *reldirpath = mstrtok(kQuote, &line);
if (!reldirpath)
return PARSE_ERROR;
@@ -4042,22 +4437,28 @@ int DoUpdate()
continue;
}
- else if (NS_tstrcmp(token, NS_T("add")) == 0) {
+ else if (NS_tstrcmp(token, NS_T("add")) == 0)
+ {
action = new AddFile();
}
- else if (NS_tstrcmp(token, NS_T("patch")) == 0) {
+ else if (NS_tstrcmp(token, NS_T("patch")) == 0)
+ {
action = new PatchFile();
}
- else if (NS_tstrcmp(token, NS_T("add-if")) == 0) { // Add if exists
+ else if (NS_tstrcmp(token, NS_T("add-if")) == 0) // Add if exists
+ {
action = new AddIfFile();
}
- else if (NS_tstrcmp(token, NS_T("add-if-not")) == 0) { // Add if not exists
+ else if (NS_tstrcmp(token, NS_T("add-if-not")) == 0) // Add if not exists
+ {
action = new AddIfNotFile();
}
- else if (NS_tstrcmp(token, NS_T("patch-if")) == 0) { // Patch if exists
+ else if (NS_tstrcmp(token, NS_T("patch-if")) == 0) // Patch if exists
+ {
action = new PatchIfFile();
}
- else {
+ else
+ {
LOG(("DoUpdate: unknown token: " LOG_S, token));
return PARSE_ERROR;
}
diff --git a/onlineupdate/source/update/updater/win_dirent.cxx b/onlineupdate/source/update/updater/win_dirent.cxx
index d7bf872194f6..2368613ee42b 100644
--- a/onlineupdate/source/update/updater/win_dirent.cxx
+++ b/onlineupdate/source/update/updater/win_dirent.cxx
@@ -16,64 +16,74 @@
static dirent gDirEnt;
DIR::DIR(const WCHAR* path)
- : findHandle(INVALID_HANDLE_VALUE)
+ : findHandle(INVALID_HANDLE_VALUE)
{
- memset(name, 0, sizeof(name));
- wcsncpy(name, path, sizeof(name)/sizeof(name[0]));
- wcsncat(name, L"\\*", sizeof(name)/sizeof(name[0]) - wcslen(name) - 1);
+ memset(name, 0, sizeof(name));
+ wcsncpy(name, path, sizeof(name)/sizeof(name[0]));
+ wcsncat(name, L"\\*", sizeof(name)/sizeof(name[0]) - wcslen(name) - 1);
}
DIR::~DIR()
{
- if (findHandle != INVALID_HANDLE_VALUE) {
- FindClose(findHandle);
- }
+ if (findHandle != INVALID_HANDLE_VALUE)
+ {
+ FindClose(findHandle);
+ }
}
dirent::dirent()
{
- d_name[0] = L'\0';
+ d_name[0] = L'\0';
}
DIR*
opendir(const WCHAR* path)
{
- return new DIR(path);
+ return new DIR(path);
}
int
closedir(DIR* dir)
{
- delete dir;
- return 0;
+ delete dir;
+ return 0;
}
dirent* readdir(DIR* dir)
{
- WIN32_FIND_DATAW data;
- if (dir->findHandle != INVALID_HANDLE_VALUE) {
- BOOL result = FindNextFileW(dir->findHandle, &data);
- if (!result) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- errno = ENOENT;
- }
- return 0;
+ WIN32_FIND_DATAW data;
+ if (dir->findHandle != INVALID_HANDLE_VALUE)
+ {
+ BOOL result = FindNextFileW(dir->findHandle, &data);
+ if (!result)
+ {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ {
+ errno = ENOENT;
+ }
+ return 0;
+ }
}
- } else {
- // Reading the first directory entry
- dir->findHandle = FindFirstFileW(dir->name, &data);
- if (dir->findHandle == INVALID_HANDLE_VALUE) {
- if (GetLastError() == ERROR_FILE_NOT_FOUND) {
- errno = ENOENT;
- } else {
- errno = EBADF;
- }
- return 0;
+ else
+ {
+ // Reading the first directory entry
+ dir->findHandle = FindFirstFileW(dir->name, &data);
+ if (dir->findHandle == INVALID_HANDLE_VALUE)
+ {
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ {
+ errno = ENOENT;
+ }
+ else
+ {
+ errno = EBADF;
+ }
+ return 0;
+ }
}
- }
- memset(gDirEnt.d_name, 0, sizeof(gDirEnt.d_name));
- wcsncpy(gDirEnt.d_name, data.cFileName,
- sizeof(gDirEnt.d_name)/sizeof(gDirEnt.d_name[0]));
- return &gDirEnt;
+ memset(gDirEnt.d_name, 0, sizeof(gDirEnt.d_name));
+ wcsncpy(gDirEnt.d_name, data.cFileName,
+ sizeof(gDirEnt.d_name)/sizeof(gDirEnt.d_name[0]));
+ return &gDirEnt;
}
#endif
diff --git a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx
index a543aed09915..33c058982caf 100644
--- a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx
+++ b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx
@@ -20,33 +20,33 @@ template <class T>
inline const T&
XPCOM_MIN(const T& aA, const T& aB)
{
- return aB < aA ? aB : aA;
+ return aB < aA ? aB : aA;
}
#endif
struct VersionPart
{
- int32_t numA;
+ int32_t numA;
- const char* strB; // NOT null-terminated, can be a null pointer
- uint32_t strBlen;
+ const char* strB; // NOT null-terminated, can be a null pointer
+ uint32_t strBlen;
- int32_t numC;
+ int32_t numC;
- char* extraD; // null-terminated
+ char* extraD; // null-terminated
};
#ifdef _WIN32
struct VersionPartW
{
- int32_t numA;
+ int32_t numA;
- wchar_t* strB; // NOT null-terminated, can be a null pointer
- uint32_t strBlen;
+ wchar_t* strB; // NOT null-terminated, can be a null pointer
+ uint32_t strBlen;
- int32_t numC;
+ int32_t numC;
- wchar_t* extraD; // null-terminated
+ wchar_t* extraD; // null-terminated
};
#endif
@@ -59,64 +59,81 @@ struct VersionPartW
static char*
ParseVP(char* aPart, VersionPart& aResult)
{
- char* dot;
-
- aResult.numA = 0;
- aResult.strB = nullptr;
- aResult.strBlen = 0;
- aResult.numC = 0;
- aResult.extraD = nullptr;
-
- if (!aPart) {
- return aPart;
- }
-
- dot = strchr(aPart, '.');
- if (dot) {
- *dot = '\0';
- }
-
- if (aPart[0] == '*' && aPart[1] == '\0') {
- aResult.numA = INT32_MAX;
- aResult.strB = "";
- } else {
- aResult.numA = strtol(aPart, const_cast<char**>(&aResult.strB), 10);
- }
-
- if (!*aResult.strB) {
+ char* dot;
+
+ aResult.numA = 0;
aResult.strB = nullptr;
aResult.strBlen = 0;
- } else {
- if (aResult.strB[0] == '+') {
- static const char kPre[] = "pre";
-
- ++aResult.numA;
- aResult.strB = kPre;
- aResult.strBlen = sizeof(kPre) - 1;
- } else {
- const char* numstart = strpbrk(aResult.strB, "0123456789+-");
- if (!numstart) {
- aResult.strBlen = strlen(aResult.strB);
- } else {
- aResult.strBlen = numstart - aResult.strB;
-
- aResult.numC = strtol(numstart, &aResult.extraD, 10);
- if (!*aResult.extraD) {
- aResult.extraD = nullptr;
+ aResult.numC = 0;
+ aResult.extraD = nullptr;
+
+ if (!aPart)
+ {
+ return aPart;
+ }
+
+ dot = strchr(aPart, '.');
+ if (dot)
+ {
+ *dot = '\0';
+ }
+
+ if (aPart[0] == '*' && aPart[1] == '\0')
+ {
+ aResult.numA = INT32_MAX;
+ aResult.strB = "";
+ }
+ else
+ {
+ aResult.numA = strtol(aPart, const_cast<char**>(&aResult.strB), 10);
+ }
+
+ if (!*aResult.strB)
+ {
+ aResult.strB = nullptr;
+ aResult.strBlen = 0;
+ }
+ else
+ {
+ if (aResult.strB[0] == '+')
+ {
+ static const char kPre[] = "pre";
+
+ ++aResult.numA;
+ aResult.strB = kPre;
+ aResult.strBlen = sizeof(kPre) - 1;
+ }
+ else
+ {
+ const char* numstart = strpbrk(aResult.strB, "0123456789+-");
+ if (!numstart)
+ {
+ aResult.strBlen = strlen(aResult.strB);
+ }
+ else
+ {
+ aResult.strBlen = numstart - aResult.strB;
+
+ aResult.numC = strtol(numstart, &aResult.extraD, 10);
+ if (!*aResult.extraD)
+ {
+ aResult.extraD = nullptr;
+ }
+ }
}
- }
}
- }
- if (dot) {
- ++dot;
+ if (dot)
+ {
+ ++dot;
- if (!*dot) {
- dot = nullptr;
+ if (!*dot)
+ {
+ dot = nullptr;
+ }
}
- }
- return dot;
+ return dot;
}
@@ -130,64 +147,81 @@ static wchar_t*
ParseVP(wchar_t* aPart, VersionPartW& aResult)
{
- wchar_t* dot;
+ wchar_t* dot;
- aResult.numA = 0;
- aResult.strB = nullptr;
- aResult.strBlen = 0;
- aResult.numC = 0;
- aResult.extraD = nullptr;
+ aResult.numA = 0;
+ aResult.strB = nullptr;
+ aResult.strBlen = 0;
+ aResult.numC = 0;
+ aResult.extraD = nullptr;
- if (!aPart) {
- return aPart;
- }
+ if (!aPart)
+ {
+ return aPart;
+ }
- dot = wcschr(aPart, '.');
- if (dot) {
- *dot = '\0';
- }
+ dot = wcschr(aPart, '.');
+ if (dot)
+ {
+ *dot = '\0';
+ }
- if (aPart[0] == '*' && aPart[1] == '\0') {
- aResult.numA = INT32_MAX;
- aResult.strB = L"";
- } else {
- aResult.numA = wcstol(aPart, const_cast<wchar_t**>(&aResult.strB), 10);
- }
+ if (aPart[0] == '*' && aPart[1] == '\0')
+ {
+ aResult.numA = INT32_MAX;
+ aResult.strB = L"";
+ }
+ else
+ {
+ aResult.numA = wcstol(aPart, const_cast<wchar_t**>(&aResult.strB), 10);
+ }
- if (!*aResult.strB) {
- aResult.strB = nullptr;
- aResult.strBlen = 0;
- } else {
- if (aResult.strB[0] == '+') {
- static wchar_t kPre[] = L"pre";
-
- ++aResult.numA;
- aResult.strB = kPre;
- aResult.strBlen = sizeof(kPre) - 1;
- } else {
- const wchar_t* numstart = wcspbrk(aResult.strB, L"0123456789+-");
- if (!numstart) {
- aResult.strBlen = wcslen(aResult.strB);
- } else {
- aResult.strBlen = numstart - aResult.strB;
-
- aResult.numC = wcstol(numstart, &aResult.extraD, 10);
- if (!*aResult.extraD) {
- aResult.extraD = nullptr;
+ if (!*aResult.strB)
+ {
+ aResult.strB = nullptr;
+ aResult.strBlen = 0;
+ }
+ else
+ {
+ if (aResult.strB[0] == '+')
+ {
+ static wchar_t kPre[] = L"pre";
+
+ ++aResult.numA;
+ aResult.strB = kPre;
+ aResult.strBlen = sizeof(kPre) - 1;
+ }
+ else
+ {
+ const wchar_t* numstart = wcspbrk(aResult.strB, L"0123456789+-");
+ if (!numstart)
+ {
+ aResult.strBlen = wcslen(aResult.strB);
+ }
+ else
+ {
+ aResult.strBlen = numstart - aResult.strB;
+
+ aResult.numC = wcstol(numstart, &aResult.extraD, 10);
+ if (!*aResult.extraD)
+ {
+ aResult.extraD = nullptr;
+ }
+ }
}
- }
}
- }
- if (dot) {
- ++dot;
+ if (dot)
+ {
+ ++dot;
- if (!*dot) {
- dot = nullptr;
+ if (!*dot)
+ {
+ dot = nullptr;
+ }
}
- }
- return dot;
+ return dot;
}
#endif
@@ -195,16 +229,18 @@ ParseVP(wchar_t* aPart, VersionPartW& aResult)
static int32_t
ns_strcmp(const char* aStr1, const char* aStr2)
{
- // any string is *before* no string
- if (!aStr1) {
- return aStr2 != 0;
- }
+ // any string is *before* no string
+ if (!aStr1)
+ {
+ return aStr2 != 0;
+ }
- if (!aStr2) {
- return -1;
- }
+ if (!aStr2)
+ {
+ return -1;
+ }
- return strcmp(aStr1, aStr2);
+ return strcmp(aStr1, aStr2);
}
// compare two length-specified string, which may be null pointers
@@ -212,41 +248,48 @@ static int32_t
ns_strnncmp(const char* aStr1, uint32_t aLen1,
const char* aStr2, uint32_t aLen2)
{
- // any string is *before* no string
- if (!aStr1) {
- return aStr2 != 0;
- }
-
- if (!aStr2) {
- return -1;
- }
+ // any string is *before* no string
+ if (!aStr1)
+ {
+ return aStr2 != 0;
+ }
- for (; aLen1 && aLen2; --aLen1, --aLen2, ++aStr1, ++aStr2) {
- if (*aStr1 < *aStr2) {
- return -1;
+ if (!aStr2)
+ {
+ return -1;
}
- if (*aStr1 > *aStr2) {
- return 1;
+ for (; aLen1 && aLen2; --aLen1, --aLen2, ++aStr1, ++aStr2)
+ {
+ if (*aStr1 < *aStr2)
+ {
+ return -1;
+ }
+
+ if (*aStr1 > *aStr2)
+ {
+ return 1;
+ }
}
- }
- if (aLen1 == 0) {
- return aLen2 == 0 ? 0 : -1;
- }
+ if (aLen1 == 0)
+ {
+ return aLen2 == 0 ? 0 : -1;
+ }
- return 1;
+ return 1;
}
// compare two int32_t
static int32_t
ns_cmp(int32_t aNum1, int32_t aNum2)
{
- if (aNum1 < aNum2) {
- return -1;
- }
+ if (aNum1 < aNum2)
+ {
+ return -1;
+ }
- return aNum1 != aNum2;
+ return aNum1 != aNum2;
}
/**
@@ -255,22 +298,25 @@ ns_cmp(int32_t aNum1, int32_t aNum2)
static int32_t
CompareVP(VersionPart& aVer1, VersionPart& aVer2)
{
- int32_t r = ns_cmp(aVer1.numA, aVer2.numA);
- if (r) {
- return r;
- }
-
- r = ns_strnncmp(aVer1.strB, aVer1.strBlen, aVer2.strB, aVer2.strBlen);
- if (r) {
- return r;
- }
-
- r = ns_cmp(aVer1.numC, aVer2.numC);
- if (r) {
- return r;
- }
-
- return ns_strcmp(aVer1.extraD, aVer2.extraD);
+ int32_t r = ns_cmp(aVer1.numA, aVer2.numA);
+ if (r)
+ {
+ return r;
+ }
+
+ r = ns_strnncmp(aVer1.strB, aVer1.strBlen, aVer2.strB, aVer2.strBlen);
+ if (r)
+ {
+ return r;
+ }
+
+ r = ns_cmp(aVer1.numC, aVer2.numC);
+ if (r)
+ {
+ return r;
+ }
+
+ return ns_strcmp(aVer1.extraD, aVer2.extraD);
}
/**
@@ -280,30 +326,35 @@ CompareVP(VersionPart& aVer1, VersionPart& aVer2)
static int32_t
CompareVP(VersionPartW& aVer1, VersionPartW& aVer2)
{
- int32_t r = ns_cmp(aVer1.numA, aVer2.numA);
- if (r) {
- return r;
- }
-
- r = wcsncmp(aVer1.strB, aVer2.strB, XPCOM_MIN(aVer1.strBlen, aVer2.strBlen));
- if (r) {
- return r;
- }
-
- r = ns_cmp(aVer1.numC, aVer2.numC);
- if (r) {
- return r;
- }
-
- if (!aVer1.extraD) {
- return aVer2.extraD != 0;
- }
-
- if (!aVer2.extraD) {
- return -1;
- }
-
- return wcscmp(aVer1.extraD, aVer2.extraD);
+ int32_t r = ns_cmp(aVer1.numA, aVer2.numA);
+ if (r)
+ {
+ return r;
+ }
+
+ r = wcsncmp(aVer1.strB, aVer2.strB, XPCOM_MIN(aVer1.strBlen, aVer2.strBlen));
+ if (r)
+ {
+ return r;
+ }
+
+ r = ns_cmp(aVer1.numC, aVer2.numC);
+ if (r)
+ {
+ return r;
+ }
+
+ if (!aVer1.extraD)
+ {
+ return aVer2.extraD != 0;
+ }
+
+ if (!aVer2.extraD)
+ {
+ return -1;
+ }
+
+ return wcscmp(aVer1.extraD, aVer2.extraD);
}
#endif
@@ -313,76 +364,86 @@ namespace mozilla {
int32_t
CompareVersions(const wchar_t* aStrA, const wchar_t* aStrB)
{
- wchar_t* A2 = wcsdup(aStrA);
- if (!A2) {
- return 1;
- }
+ wchar_t* A2 = wcsdup(aStrA);
+ if (!A2)
+ {
+ return 1;
+ }
- wchar_t* B2 = wcsdup(aStrB);
- if (!B2) {
- free(A2);
- return 1;
- }
+ wchar_t* B2 = wcsdup(aStrB);
+ if (!B2)
+ {
+ free(A2);
+ return 1;
+ }
- int32_t result;
- wchar_t* a = A2;
- wchar_t* b = B2;
+ int32_t result;
+ wchar_t* a = A2;
+ wchar_t* b = B2;
- do {
- VersionPartW va, vb;
+ do
+ {
+ VersionPartW va, vb;
- a = ParseVP(a, va);
- b = ParseVP(b, vb);
+ a = ParseVP(a, va);
+ b = ParseVP(b, vb);
- result = CompareVP(va, vb);
- if (result) {
- break;
- }
+ result = CompareVP(va, vb);
+ if (result)
+ {
+ break;
+ }
- } while (a || b);
+ }
+ while (a || b);
- free(A2);
- free(B2);
+ free(A2);
+ free(B2);
- return result;
+ return result;
}
#endif
int32_t
CompareVersions(const char* aStrA, const char* aStrB)
{
- char* A2 = strdup(aStrA);
- if (!A2) {
- return 1;
- }
+ char* A2 = strdup(aStrA);
+ if (!A2)
+ {
+ return 1;
+ }
- char* B2 = strdup(aStrB);
- if (!B2) {
- free(A2);
- return 1;
- }
+ char* B2 = strdup(aStrB);
+ if (!B2)
+ {
+ free(A2);
+ return 1;
+ }
- int32_t result;
- char* a = A2;
- char* b = B2;
+ int32_t result;
+ char* a = A2;
+ char* b = B2;
- do {
- VersionPart va, vb;
+ do
+ {
+ VersionPart va, vb;
- a = ParseVP(a, va);
- b = ParseVP(b, vb);
+ a = ParseVP(a, va);
+ b = ParseVP(b, vb);
- result = CompareVP(va, vb);
- if (result) {
- break;
- }
+ result = CompareVP(va, vb);
+ if (result)
+ {
+ break;
+ }
- } while (a || b);
+ }
+ while (a || b);
- free(A2);
- free(B2);
+ free(A2);
+ free(B2);
- return result;
+ return result;
}
} // namespace mozilla
diff --git a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h
index 0d4d7bb54b87..d793e345eb86 100644
--- a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h
+++ b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h
@@ -51,120 +51,120 @@ int32_t CompareVersions(const wchar_t* aStrA, const wchar_t* aStrB);
struct Version
{
- explicit Version(const char* aVersionString)
- {
- versionContent = strdup(aVersionString);
- }
-
- const char* ReadContent() const
- {
- return versionContent;
- }
-
- ~Version()
- {
- free(versionContent);
- }
-
- bool operator<(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) == -1;
- }
- bool operator<=(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) < 1;
- }
- bool operator>(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) == 1;
- }
- bool operator>=(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) > -1;
- }
- bool operator==(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) == 0;
- }
- bool operator!=(const Version& aRhs) const
- {
- return CompareVersions(versionContent, aRhs.ReadContent()) != 0;
- }
- bool operator<(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) == -1;
- }
- bool operator<=(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) < 1;
- }
- bool operator>(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) == 1;
- }
- bool operator>=(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) > -1;
- }
- bool operator==(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) == 0;
- }
- bool operator!=(const char* aRhs) const
- {
- return CompareVersions(versionContent, aRhs) != 0;
- }
+ explicit Version(const char* aVersionString)
+ {
+ versionContent = strdup(aVersionString);
+ }
+
+ const char* ReadContent() const
+ {
+ return versionContent;
+ }
+
+ ~Version()
+ {
+ free(versionContent);
+ }
+
+ bool operator<(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) == -1;
+ }
+ bool operator<=(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) < 1;
+ }
+ bool operator>(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) == 1;
+ }
+ bool operator>=(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) > -1;
+ }
+ bool operator==(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) == 0;
+ }
+ bool operator!=(const Version& aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs.ReadContent()) != 0;
+ }
+ bool operator<(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) == -1;
+ }
+ bool operator<=(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) < 1;
+ }
+ bool operator>(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) == 1;
+ }
+ bool operator>=(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) > -1;
+ }
+ bool operator==(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) == 0;
+ }
+ bool operator!=(const char* aRhs) const
+ {
+ return CompareVersions(versionContent, aRhs) != 0;
+ }
private:
- char* versionContent;
+ char* versionContent;
};
#ifdef _WIN32
struct VersionW
{
- explicit VersionW(const wchar_t* aVersionStringW)
- {
- versionContentW =
- reinterpret_cast<wchar_t*>(wcsdup(aVersionStringW));
- }
-
- const wchar_t* ReadContentW() const
- {
- return versionContentW;
- }
-
- ~VersionW()
- {
- free(versionContentW);
- }
-
- bool operator<(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) == -1;
- }
- bool operator<=(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) < 1;
- }
- bool operator>(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) == 1;
- }
- bool operator>=(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) > -1;
- }
- bool operator==(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) == 0;
- }
- bool operator!=(const VersionW& aRhs) const
- {
- return CompareVersions(versionContentW, aRhs.ReadContentW()) != 0;
- }
+ explicit VersionW(const wchar_t* aVersionStringW)
+ {
+ versionContentW =
+ reinterpret_cast<wchar_t*>(wcsdup(aVersionStringW));
+ }
+
+ const wchar_t* ReadContentW() const
+ {
+ return versionContentW;
+ }
+
+ ~VersionW()
+ {
+ free(versionContentW);
+ }
+
+ bool operator<(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) == -1;
+ }
+ bool operator<=(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) < 1;
+ }
+ bool operator>(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) == 1;
+ }
+ bool operator>=(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) > -1;
+ }
+ bool operator==(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) == 0;
+ }
+ bool operator!=(const VersionW& aRhs) const
+ {
+ return CompareVersions(versionContentW, aRhs.ReadContentW()) != 0;
+ }
private:
- wchar_t* versionContentW;
+ wchar_t* versionContentW;
};
#endif
diff --git a/onlineupdate/source/winhelper/windowsStart.cxx b/onlineupdate/source/winhelper/windowsStart.cxx
index 7237e06da58b..1c782d7a289f 100644
--- a/onlineupdate/source/winhelper/windowsStart.cxx
+++ b/onlineupdate/source/winhelper/windowsStart.cxx
@@ -19,34 +19,41 @@
*/
static int ArgStrLen(const wchar_t *s)
{
- int backslashes = 0;
- int i = wcslen(s);
- BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
- // Only add doublequotes if the string contains a space or a tab
- BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
-
- if (addDoubleQuotes) {
- i += 2; // initial and final duoblequote
- }
-
- if (hasDoubleQuote) {
- while (*s) {
- if (*s == '\\') {
- ++backslashes;
- } else {
- if (*s == '"') {
- // Escape the doublequote and all backslashes preceding the doublequote
- i += backslashes + 1;
- }
-
- backslashes = 0;
- }
+ int backslashes = 0;
+ int i = wcslen(s);
+ BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
+ // Only add doublequotes if the string contains a space or a tab
+ BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
+
+ if (addDoubleQuotes)
+ {
+ i += 2; // initial and final duoblequote
+ }
- ++s;
+ if (hasDoubleQuote)
+ {
+ while (*s)
+ {
+ if (*s == '\\')
+ {
+ ++backslashes;
+ }
+ else
+ {
+ if (*s == '"')
+ {
+ // Escape the doublequote and all backslashes preceding the doublequote
+ i += backslashes + 1;
+ }
+
+ backslashes = 0;
+ }
+
+ ++s;
+ }
}
- }
- return i;
+ return i;
}
/**
@@ -60,47 +67,59 @@ static int ArgStrLen(const wchar_t *s)
*/
static wchar_t* ArgToString(wchar_t *d, const wchar_t *s)
{
- int backslashes = 0;
- BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
- // Only add doublequotes if the string contains a space or a tab
- BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
-
- if (addDoubleQuotes) {
- *d = '"'; // initial doublequote
- ++d;
- }
+ int backslashes = 0;
+ BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
+ // Only add doublequotes if the string contains a space or a tab
+ BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
+
+ if (addDoubleQuotes)
+ {
+ *d = '"'; // initial doublequote
+ ++d;
+ }
- if (hasDoubleQuote) {
- int i;
- while (*s) {
- if (*s == '\\') {
- ++backslashes;
- } else {
- if (*s == '"') {
- // Escape the doublequote and all backslashes preceding the doublequote
- for (i = 0; i <= backslashes; ++i) {
- *d = '\\';
+ if (hasDoubleQuote)
+ {
+ int i;
+ while (*s)
+ {
+ if (*s == '\\')
+ {
+ ++backslashes;
+ }
+ else
+ {
+ if (*s == '"')
+ {
+ // Escape the doublequote and all backslashes preceding the doublequote
+ for (i = 0; i <= backslashes; ++i)
+ {
+ *d = '\\';
+ ++d;
+ }
+ }
+
+ backslashes = 0;
+ }
+
+ *d = *s;
++d;
- }
+ ++s;
}
-
- backslashes = 0;
- }
-
- *d = *s;
- ++d; ++s;
}
- } else {
- wcscpy(d, s);
- d += wcslen(s);
- }
+ else
+ {
+ wcscpy(d, s);
+ d += wcslen(s);
+ }
- if (addDoubleQuotes) {
- *d = '"'; // final doublequote
- ++d;
- }
+ if (addDoubleQuotes)
+ {
+ *d = '"'; // final doublequote
+ ++d;
+ }
- return d;
+ return d;
}
/**
@@ -112,33 +131,35 @@ static wchar_t* ArgToString(wchar_t *d, const wchar_t *s)
wchar_t*
MakeCommandLine(int argc, wchar_t **argv)
{
- int i;
- int len = 0;
-
- // The + 1 of the last argument handles the allocation for null termination
- for (i = 0; i < argc; ++i)
- len += ArgStrLen(argv[i]) + 1;
-
- // Protect against callers that pass 0 arguments
- if (len == 0)
- len = 1;
-
- wchar_t *s = (wchar_t*) malloc(len * sizeof(wchar_t));
- if (!s)
- return nullptr;
-
- wchar_t *c = s;
- for (i = 0; i < argc; ++i) {
- c = ArgToString(c, argv[i]);
- if (i + 1 != argc) {
- *c = ' ';
- ++c;
+ int i;
+ int len = 0;
+
+ // The + 1 of the last argument handles the allocation for null termination
+ for (i = 0; i < argc; ++i)
+ len += ArgStrLen(argv[i]) + 1;
+
+ // Protect against callers that pass 0 arguments
+ if (len == 0)
+ len = 1;
+
+ wchar_t *s = (wchar_t*) malloc(len * sizeof(wchar_t));
+ if (!s)
+ return nullptr;
+
+ wchar_t *c = s;
+ for (i = 0; i < argc; ++i)
+ {
+ c = ArgToString(c, argv[i]);
+ if (i + 1 != argc)
+ {
+ *c = ' ';
+ ++c;
+ }
}
- }
- *c = '\0';
+ *c = '\0';
- return s;
+ return s;
}
/**
@@ -159,79 +180,91 @@ WinLaunchChild(const wchar_t *exePath,
HANDLE userToken,
HANDLE *hProcess)
{
- wchar_t *cl;
- BOOL ok;
-
- cl = MakeCommandLine(argc, argv);
- if (!cl) {
- return FALSE;
- }
-
- STARTUPINFOW si = {0};
- si.cb = sizeof(STARTUPINFOW);
- si.lpDesktop = L"winsta0\\Default";
- PROCESS_INFORMATION pi = {0};
-
- if (userToken == nullptr) {
- ok = CreateProcessW(exePath,
- cl,
- nullptr, // no special security attributes
- nullptr, // no special thread attributes
- FALSE, // don't inherit filehandles
- 0, // creation flags
- nullptr, // inherit my environment
- nullptr, // use my current directory
- &si,
- &pi);
- } else {
- // Create an environment block for the process we're about to start using
- // the user's token.
- LPVOID environmentBlock = nullptr;
- if (!CreateEnvironmentBlock(&environmentBlock, userToken, TRUE)) {
- environmentBlock = nullptr;
+ wchar_t *cl;
+ BOOL ok;
+
+ cl = MakeCommandLine(argc, argv);
+ if (!cl)
+ {
+ return FALSE;
}
- ok = CreateProcessAsUserW(userToken,
- exePath,
- cl,
- nullptr, // no special security attributes
- nullptr, // no special thread attributes
- FALSE, // don't inherit filehandles
- 0, // creation flags
- environmentBlock,
- nullptr, // use my current directory
- &si,
- &pi);
-
- if (environmentBlock) {
- DestroyEnvironmentBlock(environmentBlock);
+ STARTUPINFOW si = {0};
+ si.cb = sizeof(STARTUPINFOW);
+ si.lpDesktop = L"winsta0\\Default";
+ PROCESS_INFORMATION pi = {0};
+
+ if (userToken == nullptr)
+ {
+ ok = CreateProcessW(exePath,
+ cl,
+ nullptr, // no special security attributes
+ nullptr, // no special thread attributes
+ FALSE, // don't inherit filehandles
+ 0, // creation flags
+ nullptr, // inherit my environment
+ nullptr, // use my current directory
+ &si,
+ &pi);
}
- }
+ else
+ {
+ // Create an environment block for the process we're about to start using
+ // the user's token.
+ LPVOID environmentBlock = nullptr;
+ if (!CreateEnvironmentBlock(&environmentBlock, userToken, TRUE))
+ {
+ environmentBlock = nullptr;
+ }
- if (ok) {
- if (hProcess) {
- *hProcess = pi.hProcess; // the caller now owns the HANDLE
- } else {
- CloseHandle(pi.hProcess);
+ ok = CreateProcessAsUserW(userToken,
+ exePath,
+ cl,
+ nullptr, // no special security attributes
+ nullptr, // no special thread attributes
+ FALSE, // don't inherit filehandles
+ 0, // creation flags
+ environmentBlock,
+ nullptr, // use my current directory
+ &si,
+ &pi);
+
+ if (environmentBlock)
+ {
+ DestroyEnvironmentBlock(environmentBlock);
+ }
}
- CloseHandle(pi.hThread);
- } else {
- LPVOID lpMsgBuf = nullptr;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0,
- nullptr);
- wprintf(L"Error restarting: %s\n", lpMsgBuf ? lpMsgBuf : L"(null)");
- if (lpMsgBuf)
- LocalFree(lpMsgBuf);
- }
-
- free(cl);
-
- return ok;
+
+ if (ok)
+ {
+ if (hProcess)
+ {
+ *hProcess = pi.hProcess; // the caller now owns the HANDLE
+ }
+ else
+ {
+ CloseHandle(pi.hProcess);
+ }
+ CloseHandle(pi.hThread);
+ }
+ else
+ {
+ LPVOID lpMsgBuf = nullptr;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ nullptr);
+ wprintf(L"Error restarting: %s\n", lpMsgBuf ? lpMsgBuf : L"(null)");
+ if (lpMsgBuf)
+ LocalFree(lpMsgBuf);
+ }
+
+ free(cl);
+
+ return ok;
}