summaryrefslogtreecommitdiff
path: root/onlineupdate
diff options
context:
space:
mode:
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;
}