diff options
138 files changed, 736 insertions, 20791 deletions
diff --git a/Makefile.fetch b/Makefile.fetch index d445898c94c6..3956cd4d2af0 100644 --- a/Makefile.fetch +++ b/Makefile.fetch @@ -207,6 +207,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk $(SRCDIR)/download.lst $(S $(call fetch_Optional,NSS,NSS_TARBALL) \ $(call fetch_Optional_pack,NUMBERTEXT_EXTENSION_PACK) \ $(call fetch_Optional,ODFGEN,ODFGEN_TARBALL) \ + $(call fetch_Optional,ONLINEUPDATE,ONLINEUPDATE_TARBALL) \ $(call fetch_Optional,OPENLDAP,OPENLDAP_TARBALL) \ $(call fetch_Optional,OPENSSL,OPENSSL_TARBALL) \ $(call fetch_Optional,ORCUS,ORCUS_TARBALL) \ diff --git a/RepositoryModule_host.mk b/RepositoryModule_host.mk index 2fbee39dc610..b25350ee2c3e 100644 --- a/RepositoryModule_host.mk +++ b/RepositoryModule_host.mk @@ -112,7 +112,6 @@ $(eval $(call gb_Module_add_moduledirs,libreoffice,\ $(call gb_Helper_optional,ODK,odk) \ offapi \ officecfg \ - onlineupdate \ oovbaapi \ oox \ $(call gb_Helper_optional,OPENCL,opencl) \ diff --git a/bin/find-german-comments b/bin/find-german-comments index 175af6f22420..f4ad23d9d2c1 100755 --- a/bin/find-german-comments +++ b/bin/find-german-comments @@ -304,7 +304,6 @@ class Parser: "o3tl" : 1, "odk" : 1, "officecfg" : 1, - "onlineupdate" : 1, "opencl" : 1, "oox" : 1, "package" : 1, diff --git a/bin/find-headers-to-move-inside-modules.py b/bin/find-headers-to-move-inside-modules.py index 9ec0f623128d..67060ee29fbd 100755 --- a/bin/find-headers-to-move-inside-modules.py +++ b/bin/find-headers-to-move-inside-modules.py @@ -21,8 +21,6 @@ with a.stdout as txt: if header.startswith(b"sal/"): continue if header.startswith(b"salhelper/"): continue if header.startswith(b"uno/"): continue - # these are direct copies of mozilla code - if header.startswith(b"onlineupdate/mozilla/"): continue headerSet.add(header) headerSetUnused = headerSet.copy() diff --git a/configure.ac b/configure.ac index 80ec8eca5be3..151f68f7bb22 100644 --- a/configure.ac +++ b/configure.ac @@ -13647,6 +13647,7 @@ AC_MSG_CHECKING([whether to enable mar online update]) ENABLE_ONLINE_UPDATE_MAR= if test "$enable_online_update_mar" = yes; then AC_MSG_RESULT([yes]) + BUILD_TYPE="$BUILD_TYPE ONLINEUPDATE" ENABLE_ONLINE_UPDATE_MAR="TRUE" AC_DEFINE(HAVE_FEATURE_UPDATE_MAR) else diff --git a/download.lst b/download.lst index bb9ff13fd2d3..14171f07c1f7 100644 --- a/download.lst +++ b/download.lst @@ -493,6 +493,11 @@ OFFICEOTRON_JAR := 8249374c274932a21846fa7629c2aa9b-officeotron-0.7.4-master.jar # three static lines # so that git cherry-pick # will not run into conflicts +ONLINEUPDATE_SHA256SUM := cfd00948425424d7934f5f3e26c830eda9ebbf2d18e13656bd20e4f6cd99e4ac +ONLINEUPDATE_TARBALL := onlineupdate-c003be8b9727672e7d30972983b375f4c200233f.tar.xz +# three static lines +# so that git cherry-pick +# will not run into conflicts OPENLDAP_SHA256SUM := 082e998cf542984d43634442dbe11da860759e510907152ea579bdc42fe39ea0 OPENLDAP_TARBALL := openldap-2.6.6.tgz # three static lines diff --git a/external/Module_external.mk b/external/Module_external.mk index 11588c51dcf0..4d505991822a 100644 --- a/external/Module_external.mk +++ b/external/Module_external.mk @@ -85,6 +85,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\ $(call gb_Helper_optional,OPENSSL,openssl) \ $(call gb_Helper_optional,ORCUS,liborcus) \ $(call gb_Helper_optional,PAGEMAKER,libpagemaker) \ + $(if $(ENABLE_ONLINE_UPDATE_MAR),onlineupdate) \ $(call gb_Helper_optional,PDFIUM,pdfium) \ $(call gb_Helper_optional,POPPLER,poppler) \ $(call gb_Helper_optional,POSTGRESQL,postgresql) \ diff --git a/onlineupdate/CustomTarget_generated.mk b/external/onlineupdate/CustomTarget_generated.mk index 94bf2a9e317e..dba8274497e6 100644 --- a/onlineupdate/CustomTarget_generated.mk +++ b/external/onlineupdate/CustomTarget_generated.mk @@ -7,9 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -$(eval $(call gb_CustomTarget_CustomTarget,onlineupdate/generated)) +$(eval $(call gb_CustomTarget_CustomTarget,external/onlineupdate/generated)) -onlineupdate_INC := $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/onlineupdate +onlineupdate_INC := $(call gb_CustomTarget_get_workdir,external/onlineupdate/generated)/onlineupdate # For debug purposes, ONLINEUPDATE_MAR_CERTIFICATEDER can be empty, but gen_cert_header.py always # expects an existing certificate-der=... pathname, so as a hack fall back to the generated @@ -20,22 +20,22 @@ $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini: | \ printf '[Updater]\ncertificate-der=%s\n' '$(or $(ONLINEUPDATE_MAR_CERTIFICATEDER),$@)' > $@ $(onlineupdate_INC)/primaryCert.h : \ - $(SRCDIR)/onlineupdate/source/update/updater/gen_cert_header.py \ $(call gb_ExternalExecutable_get_dependencies,python) \ - $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini + $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini \ + | $(call gb_UnpackedTarball_get_target,onlineupdate) $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),build,,1) mkdir -p $(dir $@) - $(call gb_ExternalExecutable_get_command,python) $(SRCDIR)/onlineupdate/source/update/updater/gen_cert_header.py "primaryCertData" $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini > $(onlineupdate_INC)/primaryCert.h + $(call gb_ExternalExecutable_get_command,python) $(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/gen_cert_header.py "primaryCertData" $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini > $(onlineupdate_INC)/primaryCert.h $(onlineupdate_INC)/secondaryCert.h : \ - $(SRCDIR)/onlineupdate/source/update/updater/gen_cert_header.py \ $(call gb_ExternalExecutable_get_dependencies,python) \ - $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini + $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini \ + | $(call gb_UnpackedTarball_get_target,onlineupdate) $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),build,,1) mkdir -p $(dir $@) - $(call gb_ExternalExecutable_get_command,python) $(SRCDIR)/onlineupdate/source/update/updater/gen_cert_header.py "secondaryCertData" $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini > $(onlineupdate_INC)/secondaryCert.h + $(call gb_ExternalExecutable_get_command,python) $(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/gen_cert_header.py "secondaryCertData" $(call gb_CustomTarget_get_workdir,onlineupdate/generated)/update.ini > $(onlineupdate_INC)/secondaryCert.h -$(call gb_CustomTarget_get_target,onlineupdate/generated) : \ +$(call gb_CustomTarget_get_target,external/onlineupdate/generated) : \ $(onlineupdate_INC)/primaryCert.h \ $(onlineupdate_INC)/secondaryCert.h \ diff --git a/external/onlineupdate/Executable_mar.mk b/external/onlineupdate/Executable_mar.mk new file mode 100644 index 000000000000..bcfd2f4a7f97 --- /dev/null +++ b/external/onlineupdate/Executable_mar.mk @@ -0,0 +1,63 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Executable_Executable,mar)) + +$(eval $(call gb_Executable_use_unpacked,mar,onlineupdate)) + +$(eval $(call gb_Executable_set_include,mar,\ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/src/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/verify/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/sign/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_Executable_use_static_libraries,mar,\ + libmar \ + libmarverify \ +)) + +ifeq ($(OS),WNT) + +$(eval $(call gb_Executable_add_defs,mar,\ + -DXP_WIN \ +)) + +$(eval $(call gb_Executable_add_libs,mar,\ + ws2_32.lib \ + Crypt32.lib \ +)) + +endif + +$(eval $(call gb_Executable_use_externals,mar,\ + nss3 \ +)) + +$(eval $(call gb_Executable_add_defs,mar,\ + -DMAR_NSS \ +)) + +$(eval $(call gb_Executable_add_defs,mar,\ + -DMOZ_APP_VERSION=\"$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\" \ + -DMAR_CHANNEL_ID=\"LOOnlineUpdater\" \ +)) + +$(eval $(call gb_Executable_add_generated_cobjects,mar,\ + UnpackedTarball/onlineupdate/nsprpub/lib/libc/src/strdup \ + UnpackedTarball/onlineupdate/nsprpub/lib/libc/src/strlen \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/sign/nss_secutil \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/sign/mar_sign \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/tool/mar \ +)) + +$(eval $(call gb_Executable_set_warnings_disabled,mar)) + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Executable_mbsdiff.mk b/external/onlineupdate/Executable_mbsdiff.mk index 9c528a58b9ff..a41729909586 100644 --- a/onlineupdate/Executable_mbsdiff.mk +++ b/external/onlineupdate/Executable_mbsdiff.mk @@ -9,8 +9,11 @@ $(eval $(call gb_Executable_Executable,mbsdiff)) +$(eval $(call gb_Executable_use_unpacked,mbsdiff,onlineupdate)) + $(eval $(call gb_Executable_set_include,mbsdiff,\ - -I$(SRCDIR)/onlineupdate/inc \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/inc \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/updater \ $$(INCLUDE) \ )) @@ -20,13 +23,21 @@ $(eval $(call gb_Executable_use_externals,mbsdiff,\ ifeq ($(OS),WNT) + +$(eval $(call gb_Executable_add_defs,mbsdiff, \ + -DXP_WIN \ +)) + $(eval $(call gb_Executable_add_libs,mbsdiff,\ ws2_32.lib \ )) + endif -$(eval $(call gb_Executable_add_cxxobjects,mbsdiff,\ - onlineupdate/source/mbsdiff/bsdiff \ +$(eval $(call gb_Executable_add_generated_cobjects,mbsdiff,\ + UnpackedTarball/onlineupdate/onlineupdate/source/mbsdiff/bsdiff \ )) +$(eval $(call gb_Executable_set_warnings_disabled,mbsdiff)) + # vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Executable_test_updater_dialog.mk b/external/onlineupdate/Executable_test_updater_dialog.mk index 1f95c21e20d1..9c9c0038c8da 100644 --- a/onlineupdate/Executable_test_updater_dialog.mk +++ b/external/onlineupdate/Executable_test_updater_dialog.mk @@ -9,11 +9,16 @@ $(eval $(call gb_Executable_Executable,test_updater_dialog)) +$(eval $(call gb_Executable_use_unpacked,test_updater_dialog,onlineupdate)) + $(eval $(call gb_Executable_set_include,test_updater_dialog,\ - -I$(SRCDIR)/onlineupdate/inc \ - -I$(SRCDIR)/onlineupdate/source/update/common \ - -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ - -I$(SRCDIR)/onlineupdate/source/update/updater \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/inc \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/xpcom/glue \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/common \ $$(INCLUDE) \ $(if $(filter-out WNT,$(OS)),$$(GTK3_CFLAGS) ) \ )) @@ -23,6 +28,11 @@ $(eval $(call gb_Executable_use_static_libraries,test_updater_dialog,\ )) ifeq ($(OS),WNT) + +$(eval $(call gb_Executable_add_defs,test_updater_dialog, \ + -DXP_WIN \ +)) + $(eval $(call gb_Executable_add_libs,test_updater_dialog,\ Ws2_32.lib \ Gdi32.lib \ @@ -57,9 +67,12 @@ $(eval $(call gb_Executable_add_libs,test_updater_dialog,\ endif $(eval $(call gb_Executable_add_exception_objects,test_updater_dialog,\ - onlineupdate/workben/test_dialog \ + external/onlineupdate/workben/test_dialog \ )) +# external/onlineupdate/workben/test_dialog.cxx #include's lots of external .cpp code: +$(eval $(call gb_Executable_set_warnings_not_errors,test_updater_dialog)) + ifeq ($(OS),WNT) $(eval $(call gb_Executable_add_defs,test_updater_dialog,-DUNICODE)) endif diff --git a/external/onlineupdate/Executable_update_service.mk b/external/onlineupdate/Executable_update_service.mk new file mode 100644 index 000000000000..2fe188bbc024 --- /dev/null +++ b/external/onlineupdate/Executable_update_service.mk @@ -0,0 +1,81 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Executable_Executable,update_service)) + +$(eval $(call gb_Executable_use_unpacked,update_service,onlineupdate)) + +$(eval $(call gb_Executable_set_targettype_gui,update_service,YES)) + +$(eval $(call gb_Executable_set_include,update_service,\ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/inc \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/src/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/verify/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/sign/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/xre \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/xpcom/base \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/xpcom/string \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_Executable_use_static_libraries,update_service,\ + updatehelper \ + windows_process \ +)) + +$(eval $(call gb_Executable_add_libs,update_service,\ + ws2_32.lib \ + Crypt32.lib \ + shell32.lib \ + wintrust.lib \ + version.lib \ + wtsapi32.lib \ + userenv.lib \ + shlwapi.lib \ + ole32.lib \ + rpcrt4.lib \ + comctl32.lib \ + shlwapi.lib \ + kernel32.lib \ + advapi32.lib \ +)) + +$(eval $(call gb_Executable_add_ldflags,update_service,\ + /ENTRY:wmainCRTStartup \ +)) + +$(eval $(call gb_Executable_set_generated_cxx_suffix,update_service,cpp)) + +$(eval $(call gb_Executable_add_generated_exception_objects,update_service,\ + UnpackedTarball/onlineupdate/onlineupdate/source/service/maintenanceservice \ + UnpackedTarball/onlineupdate/onlineupdate/source/service/servicebase \ + UnpackedTarball/onlineupdate/onlineupdate/source/service/serviceinstall \ + UnpackedTarball/onlineupdate/onlineupdate/source/service/workmonitor \ +)) + +$(eval $(call gb_Executable_add_cxxflags,update_service,-Zc:strictStrings-)) + +$(eval $(call gb_Executable_add_defs,update_service, \ + -DMOZ_MAINTENANCE_SERVICE \ + -DNS_NO_XPCOM \ + -DUNICODE \ + -DXP_WIN \ + $(if $(filter AARCH64 INTEL X86_64,$(CPUNAME)),-D__BYTE_ORDER__=1234) \ + -D__ORDER_BIG_ENDIAN__=4321 \ + -D__ORDER_LITTLE_ENDIAN__=1234 \ + -U_WIN32_WINNT \ +)) + +$(eval $(call gb_Executable_set_warnings_disabled,update_service)) + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/external/onlineupdate/Executable_updater.mk b/external/onlineupdate/Executable_updater.mk new file mode 100644 index 000000000000..0aa0bbe2c9b3 --- /dev/null +++ b/external/onlineupdate/Executable_updater.mk @@ -0,0 +1,140 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Executable_Executable,updater)) + +$(eval $(call gb_Executable_use_unpacked,updater,onlineupdate)) + +$(eval $(call gb_Executable_set_include,updater,\ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/inc \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/xpcom/glue \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/service \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/modules/xz-embedded/src \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/updater \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/xre \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/xpcom/base \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/xpcom/string \ + $$(INCLUDE) \ + $(if $(filter-out WNT,$(OS)),$$(GTK3_CFLAGS) ) \ +)) + +$(eval $(call gb_Executable_use_custom_headers,updater,external/onlineupdate/generated)) + +$(eval $(call gb_Executable_use_static_libraries,updater,\ + libmar \ + libmarverify \ + updatehelper \ + $(if $(filter WNT,$(OS)), \ + windows_process )\ +)) + +$(eval $(call gb_Executable_use_externals,updater,\ + bzip2 \ +)) + +ifeq ($(OS),WNT) +$(eval $(call gb_Executable_add_libs,updater,\ + Ws2_32.lib \ + Gdi32.lib \ + Comctl32.lib \ + Shell32.lib \ + Shlwapi.lib \ + Crypt32.lib \ + Ole32.lib \ + Rpcrt4.lib \ + wintrust.lib \ +)) + +$(eval $(call gb_Executable_set_targettype_gui,updater,YES)) + +$(eval $(call gb_Executable_add_nativeres,updater,updaterres)) + +$(eval $(call gb_Executable_add_ldflags,updater,\ + /ENTRY:wmainCRTStartup \ +)) + +$(eval $(call gb_Executable_add_defs,updater,\ + -DVERIFY_MAR_SIGNATURE \ + -DNS_NO_XPCOM \ + -DMOZ_MAINTENANCE_SERVICE \ + -DXP_WIN \ + -DXZ_USE_CRC64 \ + -DXZ_DEC_X86 \ + -DXZ_DEC_POWERPC \ + -DXZ_DEC_IA64 \ + -DXZ_DEC_ARM \ + -DXZ_DEC_ARMTHUMB \ + -DXZ_DEC_SPARC \ + $(if $(filter AARCH64 INTEL X86_64,$(CPUNAME)),-D__BYTE_ORDER__=1234) \ + -D__ORDER_BIG_ENDIAN__=4321 \ + -D__ORDER_LITTLE_ENDIAN__=1234 \ + -U_WIN32_WINNT \ +)) + +else + +$(eval $(call gb_Executable_add_defs,updater,\ + -DVERIFY_MAR_SIGNATURE \ + -DNSS3 \ + -DNS_NO_XPCOM \ + -DXP_UNIX \ + -DXZ_USE_CRC64 \ + -DXZ_DEC_X86 \ + -DXZ_DEC_POWERPC \ + -DXZ_DEC_IA64 \ + -DXZ_DEC_ARM \ + -DXZ_DEC_ARMTHUMB \ + -DXZ_DEC_SPARC \ +)) + +$(eval $(call gb_Executable_use_externals,updater,\ + nss3 \ +)) + +$(eval $(call gb_Executable_add_libs,updater,\ + $(GTK3_LIBS) \ +)) + +endif + +$(eval $(call gb_Executable_set_generated_cxx_suffix,updater,cpp)) + +$(eval $(call gb_Executable_add_generated_exception_objects,updater,\ + UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/archivereader \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/bspatch \ + $(if $(filter-out WNT,$(OS)),UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/progressui_gtk) \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/updater \ + $(if $(filter WNT,$(OS)),\ + UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/loaddlls \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/updater/progressui_win )\ +)) + +$(eval $(call gb_Executable_add_generated_cobjects,updater, \ + UnpackedTarball/onlineupdate/modules/xz-embedded/src/xz_crc32 \ + UnpackedTarball/onlineupdate/modules/xz-embedded/src/xz_crc64 \ + UnpackedTarball/onlineupdate/modules/xz-embedded/src/xz_dec_bcj \ + UnpackedTarball/onlineupdate/modules/xz-embedded/src/xz_dec_lzma2 \ + UnpackedTarball/onlineupdate/modules/xz-embedded/src/xz_dec_stream \ +)) + +$(eval $(call gb_Executable_set_warnings_disabled,updater)) + +ifeq ($(OS),WNT) + +$(eval $(call gb_Executable_add_cxxflags,updater,-Zc:strictStrings-)) + +$(eval $(call gb_Executable_add_defs,updater,-DUNICODE)) + +endif + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Makefile b/external/onlineupdate/Makefile index 0997e628485b..569ad8a0ba7a 100644 --- a/onlineupdate/Makefile +++ b/external/onlineupdate/Makefile @@ -9,6 +9,6 @@ module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) -include $(module_directory)/../solenv/gbuild/partial_build.mk +include $(module_directory)/../../solenv/gbuild/partial_build.mk # vim: set noet sw=4 ts=4: diff --git a/onlineupdate/Module_onlineupdate.mk b/external/onlineupdate/Module_onlineupdate.mk index 58e1d3de4531..8b5a09efc0ae 100644 --- a/onlineupdate/Module_onlineupdate.mk +++ b/external/onlineupdate/Module_onlineupdate.mk @@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,onlineupdate)) ifneq ($(ENABLE_ONLINE_UPDATE_MAR),) $(eval $(call gb_Module_add_targets,onlineupdate,\ + UnpackedTarball_onlineupdate \ StaticLibrary_libmar \ StaticLibrary_libmarverify \ StaticLibrary_updatehelper \ diff --git a/onlineupdate/README.md b/external/onlineupdate/README.md index 0162776a618c..ac4a7e65ba3d 100644 --- a/onlineupdate/README.md +++ b/external/onlineupdate/README.md @@ -2,11 +2,8 @@ Online update implementation based on Mozilla's MAR format + update mechanism -Parts of this code are copied from the mozilla repository, and adapted to -LibreOffice needs: - -`firefox/modules/libmar` -> `onlineupdate/source/libmar` -`firefox/toolkit/mozapps/update` -> `onlineupdate/source/update` +The source code has been extracted from <https://github.com/mozilla/gecko-dev> with +external/onlineupdate/generate-sources.sh. The source/service directory contains the code for the silent windows updater that avoids the repeated administrator check for an update. diff --git a/external/onlineupdate/StaticLibrary_libmar.mk b/external/onlineupdate/StaticLibrary_libmar.mk new file mode 100644 index 000000000000..836b50038784 --- /dev/null +++ b/external/onlineupdate/StaticLibrary_libmar.mk @@ -0,0 +1,45 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_StaticLibrary_StaticLibrary,libmar)) + +$(eval $(call gb_StaticLibrary_use_unpacked,libmar,onlineupdate)) + +$(eval $(call gb_StaticLibrary_set_include,libmar,\ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/src/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/other-licenses/nsis/Contrib/CityHash/cityhash \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,libmar,cpp)) + +$(eval $(call gb_StaticLibrary_add_generated_cobjects,libmar,\ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/src/mar_create \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/src/mar_extract \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/src/mar_read \ +)) + +$(eval $(call gb_StaticLibrary_add_generated_exception_objects,libmar, \ + UnpackedTarball/onlineupdate/other-licenses/nsis/Contrib/CityHash/cityhash/city \ +)) + +$(eval $(call gb_StaticLibrary_use_static_libraries,\ + libmarverify \ +)) + +$(eval $(call gb_StaticLibrary_set_warnings_disabled,libmar)) + +ifeq ($(OS),WNT) +$(eval $(call gb_StaticLibrary_add_defs,libmar, \ + -DXP_WIN \ +)) +endif + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/StaticLibrary_libmarverify.mk b/external/onlineupdate/StaticLibrary_libmarverify.mk index 62e13b686a33..9915fcb66256 100644 --- a/onlineupdate/StaticLibrary_libmarverify.mk +++ b/external/onlineupdate/StaticLibrary_libmarverify.mk @@ -9,12 +9,22 @@ $(eval $(call gb_StaticLibrary_StaticLibrary,libmarverify)) +$(eval $(call gb_StaticLibrary_use_unpacked,libmarverify,onlineupdate)) + $(eval $(call gb_StaticLibrary_set_include,libmarverify,\ - -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/libmar/src/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ $$(INCLUDE) \ )) -ifneq ($(OS),WNT) +ifeq ($(OS),WNT) + +$(eval $(call gb_StaticLibrary_add_defs,libmarverify, \ + -DXP_WIN \ +)) + +else + $(eval $(call gb_StaticLibrary_add_defs,libmarverify,\ -DMAR_NSS \ )) @@ -22,13 +32,14 @@ $(eval $(call gb_StaticLibrary_add_defs,libmarverify,\ $(eval $(call gb_StaticLibrary_use_externals,libmarverify,\ nss3 \ )) + endif -$(eval $(call gb_StaticLibrary_add_cobjects,libmarverify,\ - onlineupdate/source/libmar/verify/mar_verify \ - onlineupdate/source/libmar/verify/cryptox \ +$(eval $(call gb_StaticLibrary_add_generated_cobjects,libmarverify,\ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/verify/mar_verify \ + UnpackedTarball/onlineupdate/onlineupdate/source/libmar/verify/cryptox \ )) -$(eval $(call gb_StaticLibrary_set_warnings_not_errors,libmarverify)) +$(eval $(call gb_StaticLibrary_set_warnings_disabled,libmarverify)) # vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/external/onlineupdate/StaticLibrary_updatehelper.mk b/external/onlineupdate/StaticLibrary_updatehelper.mk new file mode 100644 index 000000000000..742d4d1c648d --- /dev/null +++ b/external/onlineupdate/StaticLibrary_updatehelper.mk @@ -0,0 +1,70 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_StaticLibrary_StaticLibrary,updatehelper)) + +$(eval $(call gb_StaticLibrary_use_unpacked,updatehelper,onlineupdate)) + +$(eval $(call gb_StaticLibrary_set_include,updatehelper,\ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/inc/ \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/service \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include/onlineupdate \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/include \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/mfbt/double-conversion \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/toolkit/mozapps/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/xpcom/base \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_StaticLibrary_add_defs,updatehelper,\ + -DMOZ_MAINTENANCE_SERVICE \ + -DNSS3 \ + -DVERIFY_MAR_SIGNATURE \ + -DXP_$(if $(filter WNT,$(OS)),WIN,UNIX) \ + $(if $(filter WNT,$(OS)),-U_WIN32_WINNT) \ +)) + +$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,updatehelper,cpp)) + +$(eval $(call gb_StaticLibrary_add_generated_exception_objects,updatehelper,\ + UnpackedTarball/onlineupdate/mozglue/misc/Printf \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/common/readstrings \ + UnpackedTarball/onlineupdate/toolkit/mozapps/update/common/updatecommon \ +)) + +ifeq ($(OS),WNT) +$(eval $(call gb_StaticLibrary_add_generated_exception_objects,updatehelper,\ + UnpackedTarball/onlineupdate/onlineupdate/source/update/common/pathhash \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/common/uachelper \ + UnpackedTarball/onlineupdate/onlineupdate/source/update/common/updatehelper \ + UnpackedTarball/onlineupdate/onlineupdate/source/service/certificatecheck \ + UnpackedTarball/onlineupdate/onlineupdate/source/service/registrycertificates \ + UnpackedTarball/onlineupdate/toolkit/mozapps/update/common/updateutils_win \ +)) +endif + +$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,updatehelper,cc)) + +$(eval $(call gb_StaticLibrary_add_generated_exception_objects,updatehelper, \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/bignum \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/bignum-dtoa \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/cached-powers \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/double-to-string \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/fast-dtoa \ + UnpackedTarball/onlineupdate/mfbt/double-conversion/double-conversion/fixed-dtoa \ +)) + +$(eval $(call gb_StaticLibrary_set_warnings_disabled,updatehelper)) + +ifeq ($(OS),WNT) +$(eval $(call gb_StaticLibrary_add_cxxflags,updatehelper,-Zc:strictStrings-)) +endif + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/external/onlineupdate/UnpackedTarball_onlineupdate.mk b/external/onlineupdate/UnpackedTarball_onlineupdate.mk new file mode 100644 index 000000000000..e7f9a0cb76f9 --- /dev/null +++ b/external/onlineupdate/UnpackedTarball_onlineupdate.mk @@ -0,0 +1,21 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_UnpackedTarball_UnpackedTarball,onlineupdate)) + +$(eval $(call gb_UnpackedTarball_set_tarball,onlineupdate,$(ONLINEUPDATE_TARBALL))) + +$(eval $(call gb_UnpackedTarball_set_patchlevel,onlineupdate,0)) + +$(eval $(call gb_UnpackedTarball_add_patches,onlineupdate, \ + external/onlineupdate/gtk3deprecated.patch \ + external/onlineupdate/lo.patch \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/external/onlineupdate/WinResTarget_updater.mk b/external/onlineupdate/WinResTarget_updater.mk new file mode 100644 index 000000000000..edb2db7483e6 --- /dev/null +++ b/external/onlineupdate/WinResTarget_updater.mk @@ -0,0 +1,15 @@ +$(eval $(call gb_WinResTarget_WinResTarget,updaterres)) + +$(call gb_WinResTarget_get_target,updaterres,updaterres): | \ + $(call gb_UnpackedTarball_get_target,onlineupdate) + +$(eval $(call gb_WinResTarget_set_include,updaterres,\ + $$(INCLUDE) \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common \ + -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater \ +)) + +$(call gb_WinResTarget_get_clean_target,updaterres): \ + RCFILE := $(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/updater.rc +$(call gb_WinResTarget_get_target,updaterres): \ + RCFILE := $(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/updater/updater.rc diff --git a/external/onlineupdate/generate-sources.sh b/external/onlineupdate/generate-sources.sh new file mode 100755 index 000000000000..bc39603c156b --- /dev/null +++ b/external/onlineupdate/generate-sources.sh @@ -0,0 +1,196 @@ +#!/bin/sh +set -ex + +source=${1?} +tag=${2-$(git -C "${source?}" describe --abbrev=40 --always)} + +tmpdir=$(mktemp -d) + +copyto() { + (cd "${tmpdir?}" && mkdir -p $(dirname "${1?}")) + cp "${source?}"/"${2?}" "${tmpdir?}"/"${1?}" +} + +# Copy sources according to the old onlineupdate/ target layout: + +copyto include/onlineupdate/mar.h modules/libmar/src/mar.h +copyto include/onlineupdate/mar_cmdline.h modules/libmar/src/mar_cmdline.h +copyto include/onlineupdate/mar_private.h modules/libmar/src/mar_private.h +copyto include/onlineupdate/mozilla/Assertions.h mfbt/Assertions.h +copyto include/onlineupdate/mozilla/Attributes.h mfbt/Attributes.h +copyto include/onlineupdate/mozilla/Compiler.h mfbt/Compiler.h +copyto include/onlineupdate/mozilla/Likely.h mfbt/Likely.h +copyto include/onlineupdate/mozilla/MacroArgs.h mfbt/MacroArgs.h +copyto include/onlineupdate/mozilla/Types.h mfbt/Types.h +copyto include/onlineupdate/mozilla/nsTraceRefcnt.h xpcom/base/nsTraceRefcnt.h +copyto include/mozilla/Char16.h mfbt/Char16.h +copyto onlineupdate/inc/bspatch.h toolkit/mozapps/update/updater/bspatch/bspatch.h +copyto onlineupdate/source/libmar/README modules/libmar/README +copyto onlineupdate/source/libmar/sign/mar_sign.c modules/libmar/sign/mar_sign.c +copyto onlineupdate/source/libmar/sign/nss_secutil.c modules/libmar/sign/nss_secutil.c +copyto onlineupdate/source/libmar/sign/nss_secutil.h modules/libmar/sign/nss_secutil.h +copyto onlineupdate/source/libmar/src/mar_create.c modules/libmar/src/mar_create.c +copyto onlineupdate/source/libmar/src/mar_extract.c modules/libmar/src/mar_extract.c +copyto onlineupdate/source/libmar/src/mar_read.c modules/libmar/src/mar_read.c +copyto onlineupdate/source/libmar/tool/mar.c modules/libmar/tool/mar.c +copyto onlineupdate/source/libmar/verify/MacVerifyCrypto.cpp modules/libmar/verify/MacVerifyCrypto.cpp +copyto onlineupdate/source/libmar/verify/cryptox.c modules/libmar/verify/cryptox.c +copyto onlineupdate/source/libmar/verify/cryptox.h modules/libmar/verify/cryptox.h +copyto onlineupdate/source/libmar/verify/mar_verify.c modules/libmar/verify/mar_verify.c +copyto onlineupdate/source/mbsdiff/bsdiff.c other-licenses/bsdiff/bsdiff.c +copyto onlineupdate/source/service/certificatecheck.cpp toolkit/mozapps/update/common/certificatecheck.cpp +copyto onlineupdate/source/service/certificatecheck.h toolkit/mozapps/update/common/certificatecheck.h +copyto onlineupdate/source/service/maintenanceservice.cpp toolkit/components/maintenanceservice/maintenanceservice.cpp +copyto onlineupdate/source/service/maintenanceservice.h toolkit/components/maintenanceservice/maintenanceservice.h +copyto onlineupdate/source/service/registrycertificates.cpp toolkit/mozapps/update/common/registrycertificates.cpp +copyto onlineupdate/source/service/registrycertificates.h toolkit/mozapps/update/common/registrycertificates.h +copyto onlineupdate/source/service/resource.h toolkit/components/maintenanceservice/resource.h +copyto onlineupdate/source/service/servicebase.cpp toolkit/components/maintenanceservice/servicebase.cpp +copyto onlineupdate/source/service/servicebase.h toolkit/components/maintenanceservice/servicebase.h +copyto onlineupdate/source/service/serviceinstall.cpp toolkit/components/maintenanceservice/serviceinstall.cpp +copyto onlineupdate/source/service/serviceinstall.h toolkit/components/maintenanceservice/serviceinstall.h +copyto onlineupdate/source/service/workmonitor.cpp toolkit/components/maintenanceservice/workmonitor.cpp +copyto onlineupdate/source/service/workmonitor.h toolkit/components/maintenanceservice/workmonitor.h +# Renamed target from onlineupdate/source/update/common/errors.h: +copyto onlineupdate/source/update/common/updatererrors.h toolkit/mozapps/update/common/updatererrors.h +copyto onlineupdate/source/update/common/pathhash.cpp toolkit/mozapps/update/common/pathhash.cpp +copyto onlineupdate/source/update/common/pathhash.h toolkit/mozapps/update/common/pathhash.h +copyto onlineupdate/source/update/common/readstrings.cpp toolkit/mozapps/update/common/readstrings.cpp +copyto onlineupdate/source/update/common/readstrings.h toolkit/mozapps/update/common/readstrings.h +copyto onlineupdate/source/update/common/uachelper.cpp toolkit/mozapps/update/common/uachelper.cpp +copyto onlineupdate/source/update/common/uachelper.h toolkit/mozapps/update/common/uachelper.h +copyto onlineupdate/source/update/common/updatedefines.h toolkit/mozapps/update/common/updatedefines.h +copyto onlineupdate/source/update/common/updatehelper.cpp toolkit/mozapps/update/common/updatehelper.cpp +copyto onlineupdate/source/update/common/updatehelper.h toolkit/mozapps/update/common/updatehelper.h +copyto onlineupdate/source/update/updater/Makefile.in toolkit/mozapps/update/updater/Makefile.in +copyto onlineupdate/source/update/updater/archivereader.cpp toolkit/mozapps/update/updater/archivereader.cpp +copyto onlineupdate/source/update/updater/archivereader.h toolkit/mozapps/update/updater/archivereader.h +copyto onlineupdate/source/update/updater/bspatch.cpp toolkit/mozapps/update/updater/bspatch/bspatch.cpp +copyto onlineupdate/source/update/updater/gen_cert_header.py toolkit/mozapps/update/updater/gen_cert_header.py +copyto onlineupdate/source/update/updater/launchchild_osx.mm toolkit/mozapps/update/updater/launchchild_osx.mm +copyto onlineupdate/source/update/updater/loaddlls.cpp toolkit/mozapps/update/updater/loaddlls.cpp +# Renamed target from onlineupdate/source/update/updater/macbuild/Contents/Info.plist: +copyto onlineupdate/source/update/updater/macbuild/Contents/Info.plist.in toolkit/mozapps/update/updater/macbuild/Contents/Info.plist.in +copyto onlineupdate/source/update/updater/macbuild/Contents/PkgInfo toolkit/mozapps/update/updater/macbuild/Contents/PkgInfo +copyto onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in +copyto onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib +copyto onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib +copyto onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib toolkit/mozapps/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib +copyto onlineupdate/source/update/updater/macbuild/Contents/Resources/updater.icns toolkit/mozapps/update/updater/macbuild/Contents/Resources/updater.icns +copyto onlineupdate/source/update/updater/progressui-unused/progressui_osx.mm toolkit/mozapps/update/updater/progressui_osx.mm +copyto onlineupdate/source/update/updater/progressui.h toolkit/mozapps/update/updater/progressui.h +copyto onlineupdate/source/update/updater/progressui_gtk.cpp toolkit/mozapps/update/updater/progressui_gtk.cpp +copyto onlineupdate/source/update/updater/progressui_null.cpp toolkit/mozapps/update/updater/progressui_null.cpp +copyto onlineupdate/source/update/updater/progressui_win.cpp toolkit/mozapps/update/updater/progressui_win.cpp +copyto onlineupdate/source/update/updater/resource.h toolkit/mozapps/update/updater/resource.h +copyto onlineupdate/source/update/updater/updater-common.build toolkit/mozapps/update/updater/updater-common.build +copyto onlineupdate/source/update/updater/updater-xpcshell/Makefile.in toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in +copyto onlineupdate/source/update/updater/updater-xpcshell/moz.build toolkit/mozapps/update/updater/updater-xpcshell/moz.build +copyto onlineupdate/source/update/updater/updater.cpp toolkit/mozapps/update/updater/updater.cpp +copyto onlineupdate/source/update/updater/updater.exe.comctl32.manifest toolkit/mozapps/update/updater/updater.exe.comctl32.manifest +copyto onlineupdate/source/update/updater/updater.exe.manifest toolkit/mozapps/update/updater/updater.exe.manifest +copyto onlineupdate/source/update/updater/updater.ico toolkit/mozapps/update/updater/updater.ico +copyto onlineupdate/source/update/updater/updater.png toolkit/mozapps/update/updater/updater.png +copyto onlineupdate/source/update/updater/updater.rc toolkit/mozapps/update/updater/updater.rc +copyto onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cpp xpcom/base/nsVersionComparator.cpp +copyto onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h xpcom/base/nsVersionComparator.h + +# Missing source for include/onlineupdate/mozilla/TypeTraits.h +# Missing source for onlineupdate/source/libmar/sign/Makefile.in +# Missing source for onlineupdate/source/libmar/src/Makefile.in +# Missing source for onlineupdate/source/libmar/tool/Makefile.in +# Missing source for onlineupdate/source/service/windowsHelper.hxx +# Missing source for onlineupdate/source/update/common/sources.mozbuild +# Missing source for onlineupdate/source/update/common/updatelogging.cxx +# Missing source for onlineupdate/source/update/common/updatelogging.h +# Missing source for onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx +# Missing source for onlineupdate/source/update/updater/progressui_gtk_icon.h +# Missing source for onlineupdate/source/update/updater/updater.svg + +# Copy additional sources according to the actual source layout: + +copyto include/mozilla/Alignment.h mfbt/Alignment.h +copyto include/mozilla/AllocPolicy.h mfbt/AllocPolicy.h +copyto include/mozilla/ArrayUtils.h mfbt/ArrayUtils.h +copyto include/mozilla/Atomics.h mfbt/Atomics.h +copyto include/mozilla/Casting.h mfbt/Casting.h +copyto include/mozilla/CheckedInt.h mfbt/CheckedInt.h +copyto include/mozilla/CmdLineAndEnvUtils.h toolkit/xre/CmdLineAndEnvUtils.h +copyto include/mozilla/CompactPair.h mfbt/CompactPair.h +copyto include/mozilla/DebugOnly.h mfbt/DebugOnly.h +copyto include/mozilla/DynamicallyLinkedFunctionPtr.h mozglue/misc/DynamicallyLinkedFunctionPtr.h +copyto include/mozilla/EndianUtils.h mfbt/EndianUtils.h +copyto include/mozilla/Fuzzing.h mfbt/Fuzzing.h +copyto include/mozilla/HashFunctions.h mfbt/HashFunctions.h +copyto include/mozilla/IntegerPrintfMacros.h mozglue/misc/IntegerPrintfMacros.h +copyto include/mozilla/IntegerTypeTraits.h mfbt/IntegerTypeTraits.h +copyto include/mozilla/MathAlgorithms.h mfbt/MathAlgorithms.h +copyto include/mozilla/Maybe.h mfbt/Maybe.h +copyto include/mozilla/MaybeStorageBase.h mfbt/MaybeStorageBase.h +copyto include/mozilla/MemoryChecking.h mfbt/MemoryChecking.h +copyto include/mozilla/MemoryReporting.h mfbt/MemoryReporting.h +copyto include/mozilla/OperatorNewExtensions.h mfbt/OperatorNewExtensions.h +copyto include/mozilla/Poison.h mfbt/Poison.h +copyto include/mozilla/Printf.h mozglue/misc/Printf.h +copyto include/mozilla/ReentrancyGuard.h mfbt/ReentrancyGuard.h +copyto include/mozilla/Result.h mfbt/Result.h +copyto include/mozilla/ResultVariant.h mfbt/ResultVariant.h +copyto include/mozilla/Span.h mfbt/Span.h +copyto include/mozilla/Sprintf.h mozglue/misc/Sprintf.h +copyto include/mozilla/StaticAnalysisFunctions.h mfbt/StaticAnalysisFunctions.h +copyto include/mozilla/TemplateLib.h mfbt/TemplateLib.h +copyto include/mozilla/ThreadSafety.h mfbt/ThreadSafety.h +copyto include/mozilla/TypedEnumBits.h mfbt/TypedEnumBits.h +copyto include/mozilla/UniquePtr.h mfbt/UniquePtr.h +copyto include/mozilla/UniquePtrExtensions.h mfbt/UniquePtrExtensions.h +copyto include/mozilla/Variant.h mfbt/Variant.h +copyto include/mozilla/Vector.h mfbt/Vector.h +copyto include/mozilla/WinHeaderOnlyUtils.h widget/windows/WinHeaderOnlyUtils.h +copyto include/mozilla/WrappingOperations.h mfbt/WrappingOperations.h +copyto include/mozilla/fallible.h mfbt/fallible.h +copyto mfbt/double-conversion/double-conversion/bignum-dtoa.cc mfbt/double-conversion/double-conversion/bignum-dtoa.cc +copyto mfbt/double-conversion/double-conversion/bignum-dtoa.h mfbt/double-conversion/double-conversion/bignum-dtoa.h +copyto mfbt/double-conversion/double-conversion/bignum.cc mfbt/double-conversion/double-conversion/bignum.cc +copyto mfbt/double-conversion/double-conversion/bignum.h mfbt/double-conversion/double-conversion/bignum.h +copyto mfbt/double-conversion/double-conversion/cached-powers.cc mfbt/double-conversion/double-conversion/cached-powers.cc +copyto mfbt/double-conversion/double-conversion/cached-powers.h mfbt/double-conversion/double-conversion/cached-powers.h +copyto mfbt/double-conversion/double-conversion/diy-fp.h mfbt/double-conversion/double-conversion/diy-fp.h +copyto mfbt/double-conversion/double-conversion/double-to-string.cc mfbt/double-conversion/double-conversion/double-to-string.cc +copyto mfbt/double-conversion/double-conversion/double-to-string.h mfbt/double-conversion/double-conversion/double-to-string.h +copyto mfbt/double-conversion/double-conversion/fast-dtoa.cc mfbt/double-conversion/double-conversion/fast-dtoa.cc +copyto mfbt/double-conversion/double-conversion/fast-dtoa.h mfbt/double-conversion/double-conversion/fast-dtoa.h +copyto mfbt/double-conversion/double-conversion/fixed-dtoa.cc mfbt/double-conversion/double-conversion/fixed-dtoa.cc +copyto mfbt/double-conversion/double-conversion/fixed-dtoa.h mfbt/double-conversion/double-conversion/fixed-dtoa.h +copyto mfbt/double-conversion/double-conversion/ieee.h mfbt/double-conversion/double-conversion/ieee.h +copyto mfbt/double-conversion/double-conversion/utils.h mfbt/double-conversion/double-conversion/utils.h +copyto modules/xz-embedded/src/xz.h modules/xz-embedded/src/xz.h +copyto modules/xz-embedded/src/xz_config.h modules/xz-embedded/src/xz_config.h +copyto modules/xz-embedded/src/xz_crc32.c modules/xz-embedded/src/xz_crc32.c +copyto modules/xz-embedded/src/xz_crc64.c modules/xz-embedded/src/xz_crc64.c +copyto modules/xz-embedded/src/xz_dec_bcj.c modules/xz-embedded/src/xz_dec_bcj.c +copyto modules/xz-embedded/src/xz_dec_lzma2.c modules/xz-embedded/src/xz_dec_lzma2.c +copyto modules/xz-embedded/src/xz_dec_stream.c modules/xz-embedded/src/xz_dec_stream.c +copyto modules/xz-embedded/src/xz_lzma2.h modules/xz-embedded/src/xz_lzma2.h +copyto modules/xz-embedded/src/xz_private.h modules/xz-embedded/src/xz_private.h +copyto modules/xz-embedded/src/xz_stream.h modules/xz-embedded/src/xz_stream.h +copyto mozglue/misc/Printf.cpp mozglue/misc/Printf.cpp +copyto nsprpub/lib/libc/src/strdup.c nsprpub/lib/libc/src/strdup.c +copyto nsprpub/lib/libc/src/strlen.c nsprpub/lib/libc/src/strlen.c +copyto other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp +copyto other-licenses/nsis/Contrib/CityHash/cityhash/city.h other-licenses/nsis/Contrib/CityHash/cityhash/city.h +copyto toolkit/mozapps/update/common/commonupdatedir.h toolkit/mozapps/update/common/commonupdatedir.h +copyto toolkit/mozapps/update/common/updatecommon.cpp toolkit/mozapps/update/common/updatecommon.cpp +copyto toolkit/mozapps/update/common/updatecommon.h toolkit/mozapps/update/common/updatecommon.h +copyto toolkit/mozapps/update/common/updateutils_win.cpp toolkit/mozapps/update/common/updateutils_win.cpp +copyto toolkit/mozapps/update/common/updateutils_win.h toolkit/mozapps/update/common/updateutils_win.h +copyto toolkit/mozapps/update/updater/crctable.h toolkit/mozapps/update/updater/crctable.h +copyto toolkit/xre/nsWindowsRestart.cpp toolkit/xre/nsWindowsRestart.cpp +copyto xpcom/base/nsAlgorithm.h xpcom/base/nsAlgorithm.h +copyto xpcom/base/nsAutoRef.h xpcom/base/nsAutoRef.h +copyto xpcom/base/nsWindowsHelpers.h xpcom/base/nsWindowsHelpers.h +copyto xpcom/string/nsCharTraits.h xpcom/string/nsCharTraits.h +copyto xpcom/string/nsUTF8Utils.h xpcom/string/nsUTF8Utils.h + +LC_ALL=C tar -c --format=gnu --sort=name --owner=0 --group=0 --mode=go=rX,u=rwX \ + --mtime '2023-12-11 00:00:00+0' --xz -f onlineupdate-"${tag?}".tar.xz -C "${tmpdir?}" . +rm -r "${tmpdir?}" diff --git a/external/onlineupdate/gtk3deprecated.patch b/external/onlineupdate/gtk3deprecated.patch new file mode 100644 index 000000000000..fb73634d50b0 --- /dev/null +++ b/external/onlineupdate/gtk3deprecated.patch @@ -0,0 +1,11 @@ +--- onlineupdate/source/update/updater/progressui_gtk.cpp ++++ onlineupdate/source/update/updater/progressui_gtk.cpp +@@ -94,7 +94,7 @@ + gtk_window_set_icon(GTK_WINDOW(sWin), sPixbuf); + g_object_unref(sPixbuf); + +- GtkWidget* vbox = gtk_vbox_new(TRUE, 6); ++ GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + sLabel = gtk_label_new(sStrings.info.get()); + gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f); + sProgressBar = gtk_progress_bar_new(); diff --git a/external/onlineupdate/lo.patch b/external/onlineupdate/lo.patch new file mode 100644 index 000000000000..bad31b0aacfc --- /dev/null +++ b/external/onlineupdate/lo.patch @@ -0,0 +1,21 @@ +--- onlineupdate/source/update/updater/progressui_gtk.cpp ++++ onlineupdate/source/update/updater/progressui_gtk.cpp +@@ -5,6 +5,7 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + #include <gtk/gtk.h> ++#include <string.h> + #include <unistd.h> + #include "mozilla/Sprintf.h" + #include "mozilla/Atomics.h" +@@ -52,8 +53,8 @@ + char ini_path[PATH_MAX]; + SprintfLiteral(ini_path, "%s.ini", (*pargv)[0]); + if (ReadStrings(ini_path, &sStrings) != OK) { +- sEnableUI = false; +- return -1; ++ sStrings.title.reset(strdup("LibreOffice Update")); ++ sStrings.info.reset(strdup("Please wait while we update your installation.")); + } + + char icon_path[PATH_MAX]; diff --git a/onlineupdate/qa/lang_packs/Makefile b/external/onlineupdate/qa/lang_packs/Makefile index d328472f53bf..d328472f53bf 100644 --- a/onlineupdate/qa/lang_packs/Makefile +++ b/external/onlineupdate/qa/lang_packs/Makefile diff --git a/onlineupdate/qa/lang_packs/update_en_signed.mar b/external/onlineupdate/qa/lang_packs/update_en_signed.mar Binary files differindex b72d1c5df637..b72d1c5df637 100644 --- a/onlineupdate/qa/lang_packs/update_en_signed.mar +++ b/external/onlineupdate/qa/lang_packs/update_en_signed.mar diff --git a/onlineupdate/qa/lang_packs/update_signed.mar b/external/onlineupdate/qa/lang_packs/update_signed.mar Binary files differindex a145d6325c65..a145d6325c65 100644 --- a/onlineupdate/qa/lang_packs/update_signed.mar +++ b/external/onlineupdate/qa/lang_packs/update_signed.mar diff --git a/onlineupdate/qa/lang_packs/updater_lang.zip b/external/onlineupdate/qa/lang_packs/updater_lang.zip Binary files differindex 05b206bc8905..05b206bc8905 100644 --- a/onlineupdate/qa/lang_packs/updater_lang.zip +++ b/external/onlineupdate/qa/lang_packs/updater_lang.zip diff --git a/onlineupdate/qa/replace_request/Makefile b/external/onlineupdate/qa/replace_request/Makefile index 476e93213cca..476e93213cca 100644 --- a/onlineupdate/qa/replace_request/Makefile +++ b/external/onlineupdate/qa/replace_request/Makefile diff --git a/onlineupdate/qa/replace_request/README b/external/onlineupdate/qa/replace_request/README index f50c692fd692..f50c692fd692 100644 --- a/onlineupdate/qa/replace_request/README +++ b/external/onlineupdate/qa/replace_request/README diff --git a/onlineupdate/qa/replace_request/updater.zip b/external/onlineupdate/qa/replace_request/updater.zip Binary files differindex dc5e26b0f258..dc5e26b0f258 100644 --- a/onlineupdate/qa/replace_request/updater.zip +++ b/external/onlineupdate/qa/replace_request/updater.zip diff --git a/onlineupdate/qa/single_step/Makefile b/external/onlineupdate/qa/single_step/Makefile index f303992baa0f..f303992baa0f 100644 --- a/onlineupdate/qa/single_step/Makefile +++ b/external/onlineupdate/qa/single_step/Makefile diff --git a/onlineupdate/qa/single_step/complete_signed.mar b/external/onlineupdate/qa/single_step/complete_signed.mar Binary files differindex 7b0631dd338a..7b0631dd338a 100644 --- a/onlineupdate/qa/single_step/complete_signed.mar +++ b/external/onlineupdate/qa/single_step/complete_signed.mar diff --git a/onlineupdate/qa/single_step/incremental_signed.mar b/external/onlineupdate/qa/single_step/incremental_signed.mar Binary files differindex 6ec6e7a1a919..6ec6e7a1a919 100644 --- a/onlineupdate/qa/single_step/incremental_signed.mar +++ b/external/onlineupdate/qa/single_step/incremental_signed.mar diff --git a/onlineupdate/qa/single_step/single_step.zip b/external/onlineupdate/qa/single_step/single_step.zip Binary files differindex 823a590e08b4..823a590e08b4 100644 --- a/onlineupdate/qa/single_step/single_step.zip +++ b/external/onlineupdate/qa/single_step/single_step.zip diff --git a/onlineupdate/workben/test_dialog.cxx b/external/onlineupdate/workben/test_dialog.cxx index ba9f258df913..4c956410d8c0 100644 --- a/onlineupdate/workben/test_dialog.cxx +++ b/external/onlineupdate/workben/test_dialog.cxx @@ -1,9 +1,9 @@ #include "progressui.h" #if defined(_WIN32) -#include "progressui_win.cxx" +#include "progressui_win.cpp" #else -#include "progressui_gtk.cxx" +#include "progressui_gtk.cpp" #endif #include <thread> diff --git a/include/onlineupdate/mar.h b/include/onlineupdate/mar.h deleted file mode 100644 index 0e21efb920a5..000000000000 --- a/include/onlineupdate/mar.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_H__ -#define MAR_H__ - -#include "mozilla/Assertions.h" -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* We have a MAX_SIGNATURES limit so that an invalid MAR will never - * waste too much of either updater's or signmar's time. - * It is also used at various places internally and will affect memory usage. - * If you want to increase this value above 9 then you need to adjust parsing - * code in tool/mar.c. -*/ -#define MAX_SIGNATURES 8 -#ifdef __cplusplus -static_assert(MAX_SIGNATURES <= 9, "too many signatures"); -#else -MOZ_STATIC_ASSERT(MAX_SIGNATURES <= 9, "too many signatures"); -#endif - -struct ProductInformationBlock { - const char *MARChannelID; - const char *productVersion; -}; - -/** - * The MAR item data structure. - */ -typedef struct MarItem_ { - struct MarItem_ *next; /* private field */ - uint32_t offset; /* offset into archive */ - uint32_t length; /* length of data in bytes */ - uint32_t flags; /* contains file mode bits */ - char name[1]; /* file path */ -} MarItem; - -#define TABLESIZE 256 - -struct MarFile_ { - FILE *fp; - MarItem *item_table[TABLESIZE]; -}; - -typedef struct MarFile_ MarFile; - -/** - * Signature of callback function passed to mar_enum_items. - * @param mar The MAR file being visited. - * @param item The MAR item being visited. - * @param data The data parameter passed by the caller of mar_enum_items. - * @return A non-zero value to stop enumerating. - */ -typedef int (* MarItemCallback)(MarFile *mar, const MarItem *item, void *data); - -/** - * Open a MAR file for reading. - * @param path Specifies the path to the MAR file to open. This path must - * be compatible with fopen. - * @return NULL if an error occurs. - */ -MarFile *mar_open(const char *path); - -#ifdef _WIN32 -MarFile *mar_wopen(const wchar_t *path); -#endif - -/** - * Close a MAR file that was opened using mar_open. - * @param mar The MarFile object to close. - */ -void mar_close(MarFile *mar); - -/** - * Find an item in the MAR file by name. - * @param mar The MarFile object to query. - * @param item The name of the item to query. - * @return A const reference to a MAR item or NULL if not found. - */ -const MarItem *mar_find_item(MarFile *mar, const char *item); - -/** - * Enumerate all MAR items via callback function. - * @param mar The MAR file to enumerate. - * @param callback The function to call for each MAR item. - * @param data A caller specified value that is passed along to the - * callback function. - * @return 0 if the enumeration ran to completion. Otherwise, any - * non-zero return value from the callback is returned. - */ -int mar_enum_items(MarFile *mar, MarItemCallback callback, void *data); - -/** - * Read from MAR item at given offset up to bufsize bytes. - * @param mar The MAR file to read. - * @param item The MAR item to read. - * @param offset The byte offset relative to the start of the item. - * @param buf A pointer to a buffer to copy the data into. - * @param bufsize The length of the buffer to copy the data into. - * @return The number of bytes written or a negative value if an - * error occurs. - */ -int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf, - int bufsize); - -/** - * Create a MAR file from a set of files. - * @param dest The path to the file to create. This path must be - * compatible with fopen. - * @param numfiles The number of files to store in the archive. - * @param files The list of null-terminated file paths. Each file - * path must be compatible with fopen. - * @param infoBlock The information to store in the product information block. - * @return A non-zero value if an error occurs. - */ -int mar_create(const char *dest, - int numfiles, - char **files, - struct ProductInformationBlock *infoBlock); - -/** - * Extract a MAR file to the current working directory. - * @param path The path to the MAR file to extract. This path must be - * compatible with fopen. - * @return A non-zero value if an error occurs. - */ -int mar_extract(const char *path); - -#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary - -/* Read the entire file (not a MAR file) into a newly-allocated buffer. - * This function does not write to stderr. Instead, the caller should - * write whatever error messages it sees fit. The caller must free the returned - * buffer using free(). - * - * @param filePath The path to the file that should be read. - * @param maxSize The maximum valid file size. - * @param data On success, *data will point to a newly-allocated buffer - * with the file's contents in it. - * @param size On success, *size will be the size of the created buffer. - * - * @return 0 on success, -1 on error - */ -int mar_read_entire_file(const char * filePath, - uint32_t maxSize, - /*out*/ const uint8_t * *data, - /*out*/ uint32_t *size); - -/** - * Verifies a MAR file by verifying each signature with the corresponding - * certificate. That is, the first signature will be verified using the first - * certificate given, the second signature will be verified using the second - * certificate given, etc. The signature count must exactly match the number of - * certificates given, and all signature verifications must succeed. - * We do not check that the certificate was issued by any trusted authority. - * We assume it to be self-signed. We do not check whether the certificate - * is valid for this usage. - * - * @param mar The already opened MAR file. - * @param certData Pointer to the first element in an array of certificate - * file data. - * @param certDataSizes Pointer to the first element in an array for size of - * the cert data. - * @param certCount The number of elements in certData and certDataSizes - * @return 0 on success - * a negative number if there was an error - * a positive number if the signature does not verify - */ -int mar_verify_signatures(MarFile *mar, - const uint8_t * const *certData, - const uint32_t *certDataSizes, - uint32_t certCount); - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -mar_read_product_info_block(MarFile *mar, - struct ProductInformationBlock *infoBlock); - -#ifdef __cplusplus -} -#endif - -#endif /* MAR_H__ */ diff --git a/include/onlineupdate/mar_cmdline.h b/include/onlineupdate/mar_cmdline.h deleted file mode 100644 index ef6867f06fc3..000000000000 --- a/include/onlineupdate/mar_cmdline.h +++ /dev/null @@ -1,110 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_CMDLINE_H__ -#define MAR_CMDLINE_H__ - -/* We use NSPR here just to import the definition of uint32_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct ProductInformationBlock; - -/** - * Determines MAR file information. - * - * @param path The path of the MAR file to check. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * has_additional_blocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info(const char *path, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks); - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -read_product_info_block(char *path, - struct ProductInformationBlock *infoBlock); - -/** - * Refreshes the product information block with the new information. - * The input MAR must not be signed or the function call will fail. - * - * @param path The path to the MAR file whose product info block - * should be refreshed. - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -refresh_product_info_block(const char *path, - struct ProductInformationBlock *infoBlock); - -/** - * Writes out a copy of the MAR at src but with the signature block stripped. - * - * @param src The path of the source MAR file - * @param dest The path of the MAR file to write out that - has no signature block - * @return 0 on success - * -1 on error -*/ -int -strip_signature_block(const char *src, const char * dest); - -/** - * Extracts a signature from a MAR file, base64 encodes it, and writes it out - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to extract - * @param dest The path of file to write the signature to - * @return 0 on success - * -1 on error -*/ -int -extract_signature(const char *src, uint32_t sigIndex, const char * dest); - -/** - * Imports a base64 encoded signature into a MAR file - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to import - * @param base64SigFile A file which contains the signature to import - * @param dest The path of the destination MAR file with replaced signature - * @return 0 on success - * -1 on error -*/ -int -import_signature(const char *src, - uint32_t sigIndex, - const char * base64SigFile, - const char *dest); - -#ifdef __cplusplus -} -#endif - -#endif /* MAR_CMDLINE_H__ */ diff --git a/include/onlineupdate/mar_private.h b/include/onlineupdate/mar_private.h deleted file mode 100644 index 319564b749a4..000000000000 --- a/include/onlineupdate/mar_private.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MAR_PRIVATE_H__ -#define MAR_PRIVATE_H__ - -#include "limits.h" -#include "mozilla/Assertions.h" -#include <stdint.h> - -#define BLOCKSIZE 4096 -#define ROUND_UP(n, incr) (((n) / (incr) + 1) * (incr)) - -#define MAR_ID "MAR1" -#define MAR_ID_SIZE 4 - -/* The signature block comes directly after the header block - which is 16 bytes */ -#define SIGNATURE_BLOCK_OFFSET 16 - -/* Make sure the file is less than 500MB. We do this to protect against - invalid MAR files. */ -#define MAX_SIZE_OF_MAR_FILE ((int64_t)1824288000) - -/* Existing code makes assumptions that the file size is - smaller than LONG_MAX. */ -MOZ_STATIC_ASSERT(MAX_SIZE_OF_MAR_FILE < ((int64_t)LONG_MAX), - "max mar file size is too big"); - -/* We store at most the size up to the signature block + 4 - bytes per BLOCKSIZE bytes */ -MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < - (SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)), - "BLOCKSIZE is too big"); - -/* The maximum size of any signature supported by current and future - implementations of the signmar program. */ -#define MAX_SIGNATURE_LENGTH 2048 - -/* Each additional block has a unique ID. - The product information block has an ID of 1. */ -#define PRODUCT_INFO_BLOCK_ID 1 - -#define MAR_ITEM_SIZE(namelen) (3*sizeof(uint32_t) + (namelen) + 1) - -/* Product Information Block (PIB) constants */ -#define PIB_MAX_MAR_CHANNEL_ID_SIZE 63 -#define PIB_MAX_PRODUCT_VERSION_SIZE 31 - -/* The mar program is compiled as a host bin so we don't have access to NSPR at - runtime. For that reason we use ntohl, htonl, and define HOST_TO_NETWORK64 - instead of the NSPR equivalents. */ -#ifdef _WIN32 -#include <winsock2.h> -#define ftello _ftelli64 -#define fseeko _fseeki64 -#else -#define _FILE_OFFSET_BITS 64 -#include <netinet/in.h> -#include <unistd.h> -#endif - -#include <stdio.h> - -#define HOST_TO_NETWORK64(x) ( \ - ((((uint64_t) x) & 0xFF) << 56) | \ - ((((uint64_t) x) >> 8) & 0xFF) << 48) | \ - (((((uint64_t) x) >> 16) & 0xFF) << 40) | \ - (((((uint64_t) x) >> 24) & 0xFF) << 32) | \ - (((((uint64_t) x) >> 32) & 0xFF) << 24) | \ - (((((uint64_t) x) >> 40) & 0xFF) << 16) | \ - (((((uint64_t) x) >> 48) & 0xFF) << 8) | \ - (((uint64_t) x) >> 56) -#define NETWORK_TO_HOST64 HOST_TO_NETWORK64 - -#endif /* MAR_PRIVATE_H__ */ diff --git a/include/onlineupdate/mozilla/Assertions.h b/include/onlineupdate/mozilla/Assertions.h deleted file mode 100644 index 54aab582a90c..000000000000 --- a/include/onlineupdate/mozilla/Assertions.h +++ /dev/null @@ -1,503 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implementations of runtime and static assertion macros for C and C++. */ - -#ifndef mozilla_Assertions_h -#define mozilla_Assertions_h - -#if defined(MOZILLA_INTERNAL_API) && defined(__cplusplus) -#define MOZ_DUMP_ASSERTION_STACK -#endif - -#include "Attributes.h" -#include "Compiler.h" -#include "Likely.h" -#include "MacroArgs.h" -#ifdef MOZ_DUMP_ASSERTION_STACK -#include "nsTraceRefcnt.h" -#endif - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#ifdef _WIN32 - /* - * TerminateProcess and GetCurrentProcess are defined in <winbase.h>, which - * further depends on <windef.h>. We hardcode these few definitions manually - * because those headers clutter the global namespace with a significant - * number of undesired macros and symbols. - */ -# ifdef __cplusplus -extern "C" { -# endif -__declspec(dllimport) int __stdcall -TerminateProcess(void* hProcess, unsigned int uExitCode); -__declspec(dllimport) void* __stdcall GetCurrentProcess(void); -# ifdef __cplusplus -} -# endif -#else -# include <signal.h> -#endif -#ifdef ANDROID -# include <android/log.h> -#endif - -/* - * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C. - * In C++11, static_assert is provided by the compiler to the same effect. - * This can be useful when you make certain assumptions about what must hold for - * optimal, or even correct, behavior. For example, you might assert that the - * size of a struct is a multiple of the target architecture's word size: - * - * struct S { ... }; - * // C - * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * // C++11 - * static_assert(sizeof(S) % sizeof(size_t) == 0, - * "S should be a multiple of word size for efficiency"); - * - * This macro can be used in any location where both an extern declaration and a - * typedef could be used. - */ -#ifndef __cplusplus - /* - * Some of the definitions below create an otherwise-unused typedef. This - * triggers compiler warnings with some versions of gcc, so mark the typedefs - * as permissibly-unused to disable the warnings. - */ -# if defined(__GNUC__) -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -# else -# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE /* nothing */ -# endif -# define MOZ_STATIC_ASSERT_GLUE1(x, y) x##y -# define MOZ_STATIC_ASSERT_GLUE(x, y) MOZ_STATIC_ASSERT_GLUE1(x, y) -# if defined(__SUNPRO_CC) - /* - * The Sun Studio C++ compiler is buggy when declaring, inside a function, - * another extern'd function with an array argument whose length contains a - * sizeof, triggering the error message "sizeof expression not accepted as - * size of array parameter". This bug (6688515, not public yet) would hit - * defining moz_static_assert as a function, so we always define an extern - * array for Sun Studio. - * - * We include the line number in the symbol name in a best-effort attempt - * to avoid conflicts (see below). - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern char MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)[(cond) ? 1 : -1] -# elif defined(__COUNTER__) - /* - * If there was no preferred alternative, use a compiler-agnostic version. - * - * Note that the non-__COUNTER__ version has a bug in C++: it can't be used - * in both |extern "C"| and normal C++ in the same translation unit. (Alas - * |extern "C"| isn't allowed in a function.) The only affected compiler - * we really care about is gcc 4.2. For that compiler and others like it, - * we include the line number in the function name to do the best we can to - * avoid conflicts. These should be rare: a conflict would require use of - * MOZ_STATIC_ASSERT on the same line in separate files in the same - * translation unit, *and* the uses would have to be in code with - * different linkage, *and* the first observed use must be in C++-linkage - * code. - */ -# define MOZ_STATIC_ASSERT(cond, reason) \ - typedef int MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __COUNTER__)[(cond) ? 1 : -1] MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# else -# define MOZ_STATIC_ASSERT(cond, reason) \ - extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE -# endif - -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason) -#else -#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Prints |aStr| as an assertion failure (using aFilename and aLine as the - * location of the assertion) to the standard debug-output channel. - * - * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This - * method is primarily for internal use in this header, and only secondarily - * for use in implementing release-build assertions. - */ -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", - "Assertion failure: %s, at %s:%d\n", - aStr, aFilename, aLine); -#else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine); -#if defined (MOZ_DUMP_ASSERTION_STACK) && !defined(MOZILLA_XPCOMRT_API) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -static MOZ_COLD MOZ_ALWAYS_INLINE void -MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) - MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS -{ -#ifdef ANDROID - __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", - "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#else - fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); -#if defined(MOZ_DUMP_ASSERTION_STACK) && !defined(MOZILLA_XPCOMRT_API) - nsTraceRefcnt::WalkTheStack(stderr); -#endif - fflush(stderr); -#endif -} - -/** - * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should - * call MOZ_CRASH instead. - */ -#if defined(_MSC_VER) - /* - * On MSVC use the __debugbreak compiler intrinsic, which produces an inline - * (not nested in a system function) breakpoint. This distinctively invokes - * Breakpad without requiring system library symbols on all stack-processing - * machines, as a nested breakpoint would require. - * - * We use TerminateProcess with the exit code aborting would generate - * because we don't want to invoke atexit handlers, destructors, library - * unload handlers, and so on when our process might be in a compromised - * state. - * - * We don't use abort() because it'd cause Windows to annoyingly pop up the - * process error dialog multiple times. See bug 345118 and bug 426163. - * - * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the - * compiler doesn't hassle us to provide a return statement after a - * MOZ_REALLY_CRASH() call. - * - * (Technically these are Windows requirements, not MSVC requirements. But - * practically you need MSVC for debugging, and we only ship builds created - * by MSVC, so doing it this way reduces complexity.) - */ - -__declspec(noreturn) __inline void MOZ_NoReturn() {} - -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - ::__debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - ::TerminateProcess(::GetCurrentProcess(), 3); \ - ::MOZ_NoReturn(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - __debugbreak(); \ - *((volatile int*) NULL) = __LINE__; \ - TerminateProcess(GetCurrentProcess(), 3); \ - MOZ_NoReturn(); \ - } while (0) -# endif -#else -# ifdef __cplusplus -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - ::abort(); \ - } while (0) -# else -# define MOZ_REALLY_CRASH() \ - do { \ - *((volatile int*) NULL) = __LINE__; \ - abort(); \ - } while (0) -# endif -#endif - -/* - * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a - * Breakpad-compatible way, in both debug and release builds. - * - * MOZ_CRASH is a good solution for "handling" failure cases when you're - * unwilling or unable to handle them more cleanly -- for OOM, for likely memory - * corruption, and so on. It's also a good solution if you need safe behavior - * in release builds as well as debug builds. But if the failure is one that - * should be debugged and fixed, MOZ_ASSERT is generally preferable. - * - * The optional explanation-string, if provided, must be a string literal - * explaining why we're crashing. This argument is intended for use with - * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's - * obvious why we're crashing. - * - * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an - * explanation-string, we print the string to stderr. Otherwise, we don't - * print anything; this is because we want MOZ_CRASH to be 100% safe in release - * builds, and it's hard to print to stderr safely when memory might have been - * corrupted. - */ -#ifndef DEBUG -# define MOZ_CRASH(...) MOZ_REALLY_CRASH() -#else -# define MOZ_CRASH(...) \ - do { \ - MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \ - MOZ_REALLY_CRASH(); \ - } while (0) -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* - * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in - * debug builds. If it is, execution continues. Otherwise, an error message - * including the expression and the explanation-string (if provided) is printed, - * an attempt is made to invoke any existing debugger, and execution halts. - * MOZ_ASSERT is fatal: no recovery is possible. Do not assert a condition - * which can correctly be false. - * - * The optional explanation-string, if provided, must be a string literal - * explaining the assertion. It is intended for use with assertions whose - * correctness or rationale is non-obvious, and for assertions where the "real" - * condition being tested is best described prosaically. Don't provide an - * explanation if it's not actually helpful. - * - * // No explanation needed: pointer arguments often must not be NULL. - * MOZ_ASSERT(arg); - * - * // An explanation can be helpful to explain exactly how we know an - * // assertion is valid. - * MOZ_ASSERT(state == WAITING_FOR_RESPONSE, - * "given that <thingA> and <thingB>, we must have..."); - * - * // Or it might disambiguate multiple identical (save for their location) - * // assertions of the same expression. - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this Boolean object"); - * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(), - * "we already set [[PrimitiveThis]] for this String object"); - * - * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs - * *only* during debugging, not "in the field". If you want the latter, use - * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well. - * - * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and - * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare - * enough to require real user testing to hit, but is not security-sensitive. - * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT - * is firing, it should promptly be converted to a MOZ_ASSERT while the failure - * is being investigated, rather than letting users suffer. - */ - -/* - * Implement MOZ_VALIDATE_ASSERT_CONDITION_TYPE, which is used to guard against - * accidentally passing something unintended in lieu of an assertion condition. - */ - -#ifdef __cplusplus -# include "TypeTraits.h" -namespace mozilla { -namespace detail { - -template<typename T> -struct IsFunction -{ - static const bool value = false; -}; - -template<typename R, typename... A> -struct IsFunction<R(A...)> -{ - static const bool value = true; -}; - -template<typename T> -struct AssertionConditionType -{ - typedef typename RemoveReference<T>::Type ValueT; - static_assert(!IsArray<ValueT>::value, - "Expected boolean assertion condition, got an array or a " - "string!"); - static_assert(!IsFunction<ValueT>::value, - "Expected boolean assertion condition, got a function! Did " - "you intend to call that function?"); - static_assert(!IsFloatingPoint<ValueT>::value, - "It's often a bad idea to assert that a floating-point number " - "is nonzero, because such assertions tend to intermittently " - "fail. Shouldn't your code gracefully handle this case instead " - "of asserting? Anyway, if you really want to do that, write an " - "explicit boolean condition, like !!x or x!=0."); - - static const bool isValid = true; -}; - -} // namespace detail -} // namespace mozilla -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \ - static_assert(mozilla::detail::AssertionConditionType<decltype(x)>::isValid, \ - "invalid assertion condition") -#else -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) -#endif - -/* First the single-argument form. */ -#define MOZ_ASSERT_HELPER1(expr) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!(expr))) { \ - MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) -/* Now the two-argument form. */ -#define MOZ_ASSERT_HELPER2(expr, explain) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!(expr))) { \ - MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) - -#define MOZ_RELEASE_ASSERT_GLUE(a, b) a b -#define MOZ_RELEASE_ASSERT(...) \ - MOZ_RELEASE_ASSERT_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ - (__VA_ARGS__)) - -#ifdef DEBUG -# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__) -#else -# define MOZ_ASSERT(...) do { } while (0) -#endif /* DEBUG */ - -#ifdef RELEASE_BUILD -# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT -#else -# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT -#endif - -/* - * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is - * true. - * - * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num)); - * - * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is - * designed to catch bugs during debugging, not "in the field". - */ -#ifdef DEBUG -# define MOZ_ASSERT_IF(cond, expr) \ - do { \ - if (cond) { \ - MOZ_ASSERT(expr); \ - } \ - } while (0) -#else -# define MOZ_ASSERT_IF(cond, expr) do { } while (0) -#endif - -/* - * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that - * it is undefined behavior for execution to reach this point. No guarantees - * are made about what will happen if this is reached at runtime. Most code - * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra - * asserts. - */ -#if defined(__clang__) || defined(__GNUC__) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() -#elif defined(_MSC_VER) -# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0) -#else -# ifdef __cplusplus -# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort() -# else -# define MOZ_ASSUME_UNREACHABLE_MARKER() abort() -# endif -#endif - -/* - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE([reason]) tells the compiler that it - * can assume that the macro call cannot be reached during execution. This lets - * the compiler generate better-optimized code under some circumstances, at the - * expense of the program's behavior being undefined if control reaches the - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE. - * - * In Gecko, you probably should not use this macro outside of performance- or - * size-critical code, because it's unsafe. If you don't care about code size - * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH. - * - * SpiderMonkey is a different beast, and there it's acceptable to use - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE more widely. - * - * Note that MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE is noreturn, so it's valid - * not to return a value following a MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE - * call. - * - * Example usage: - * - * enum ValueType { - * VALUE_STRING, - * VALUE_INT, - * VALUE_FLOAT - * }; - * - * int ptrToInt(ValueType type, void* value) { - * { - * // We know for sure that type is either INT or FLOAT, and we want this - * // code to run as quickly as possible. - * switch (type) { - * case VALUE_INT: - * return *(int*) value; - * case VALUE_FLOAT: - * return (int) *(float*) value; - * default: - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected ValueType"); - * } - * } - */ - -/* - * Unconditional assert in debug builds for (assumed) unreachable code paths - * that have a safe return without crashing in release builds. - */ -#define MOZ_ASSERT_UNREACHABLE(reason) \ - MOZ_ASSERT(false, "MOZ_ASSERT_UNREACHABLE: " reason) - -#define MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(reason) \ - do { \ - MOZ_ASSERT_UNREACHABLE(reason); \ - MOZ_ASSUME_UNREACHABLE_MARKER(); \ - } while (0) - -/* - * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided - * expression, in debug builds and in release builds both. Then, in debug - * builds only, the value of the expression is asserted either true or false - * using MOZ_ASSERT. - */ -#ifdef DEBUG -# define MOZ_ALWAYS_TRUE(expr) MOZ_ASSERT((expr)) -# define MOZ_ALWAYS_FALSE(expr) MOZ_ASSERT(!(expr)) -#else -# define MOZ_ALWAYS_TRUE(expr) ((void)(expr)) -# define MOZ_ALWAYS_FALSE(expr) ((void)(expr)) -#endif - -#undef MOZ_DUMP_ASSERTION_STACK - -#endif /* mozilla_Assertions_h */ diff --git a/include/onlineupdate/mozilla/Attributes.h b/include/onlineupdate/mozilla/Attributes.h deleted file mode 100644 index 74b77a38d082..000000000000 --- a/include/onlineupdate/mozilla/Attributes.h +++ /dev/null @@ -1,481 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implementations of various class and method modifier attributes. */ - -#ifndef mozilla_Attributes_h -#define mozilla_Attributes_h - -#include "Compiler.h" - -/* - * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must be inlined, even if the compiler thinks - * otherwise. This is only a (much) stronger version of the inline hint: - * compilers are not guaranteed to respect it (although they're much more likely - * to do so). - * - * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the - * compiler to inline even in DEBUG builds. It should be used very rarely. - */ -#if defined(_MSC_VER) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline -#elif defined(__GNUC__) -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline -#else -# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline -#endif - -#if !defined(DEBUG) -# define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG -#elif defined(_MSC_VER) && !defined(__cplusplus) -# define MOZ_ALWAYS_INLINE __inline -#else -# define MOZ_ALWAYS_INLINE inline -#endif - -#if defined(_MSC_VER) -/* - * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality - * without warnings (functionality used by the macros below). These modes are - * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more - * standardly, by checking whether __cplusplus has a C++11 or greater value. - * Current versions of g++ do not correctly set __cplusplus, so we check both - * for forward compatibility. - * - * Even though some versions of MSVC support explicit conversion operators, we - * don't indicate support for them here, due to - * http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug - */ -# define MOZ_HAVE_NEVER_INLINE __declspec(noinline) -# define MOZ_HAVE_NORETURN __declspec(noreturn) -# ifdef __clang__ - /* clang-cl probably supports constexpr and explicit conversions. */ -# if __has_extension(cxx_constexpr) -# define MOZ_HAVE_CXX11_CONSTEXPR -# endif -# if __has_extension(cxx_explicit_conversions) -# define MOZ_HAVE_EXPLICIT_CONVERSION -# endif -# endif -#elif defined(__clang__) - /* - * Per Clang documentation, "Note that marketing version numbers should not - * be used to check for language features, as different vendors use different - * numbering schemes. Instead, use the feature checking macros." - */ -# ifndef __has_extension -# define __has_extension __has_feature /* compatibility, for older versions of clang */ -# endif -# if __has_extension(cxx_constexpr) -# define MOZ_HAVE_CXX11_CONSTEXPR -# endif -# if __has_extension(cxx_explicit_conversions) -# define MOZ_HAVE_EXPLICIT_CONVERSION -# endif -# if __has_attribute(noinline) -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# endif -# if __has_attribute(noreturn) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -# endif -#elif defined(__GNUC__) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && __cplusplus >= 201103L) -# define MOZ_HAVE_CXX11_CONSTEXPR -# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 0) -# define MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES -# endif -# define MOZ_HAVE_EXPLICIT_CONVERSION -# endif -# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) -# define MOZ_HAVE_NORETURN __attribute__((noreturn)) -#endif - -/* - * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN - * to mark some false positives - */ -#ifdef __clang_analyzer__ -# if __has_extension(attribute_analyzer_noreturn) -# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# endif -#endif - -/* - * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a - * function at compile time. A constexpr function cannot examine any values - * except its arguments and can have no side effects except its return value. - * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's - * value may be computed at compile time. It should be preferred to just - * marking variables as MOZ_CONSTEXPR because if the compiler does not support - * constexpr it will fall back to making the variable const, and some compilers - * do not accept variables being marked both const and constexpr. - */ -#ifdef MOZ_HAVE_CXX11_CONSTEXPR -# define MOZ_CONSTEXPR constexpr -# define MOZ_CONSTEXPR_VAR constexpr -# ifdef MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES -# define MOZ_CONSTEXPR_TMPL constexpr -# else -# define MOZ_CONSTEXPR_TMPL -# endif -#else -# define MOZ_CONSTEXPR /* no support */ -# define MOZ_CONSTEXPR_VAR const -# define MOZ_CONSTEXPR_TMPL -#endif - -/* - * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion - * overloaded operator that declares that a C++11 compiler should restrict - * this operator to allow only explicit type conversions, disallowing - * implicit conversions. - * - * Example: - * - * template<typename T> - * class Ptr - * { - * T* mPtr; - * MOZ_EXPLICIT_CONVERSION operator bool() const - * { - * return mPtr != nullptr; - * } - * }; - * - */ -#ifdef MOZ_HAVE_EXPLICIT_CONVERSION -# define MOZ_EXPLICIT_CONVERSION explicit -#else -# define MOZ_EXPLICIT_CONVERSION /* no support */ -#endif - -/* - * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the - * method decorated with it must never be inlined, even if the compiler would - * otherwise choose to inline the method. Compilers aren't absolutely - * guaranteed to support this, but most do. - */ -#if defined(MOZ_HAVE_NEVER_INLINE) -# define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE -#else -# define MOZ_NEVER_INLINE /* no support */ -#endif - -/* - * MOZ_NORETURN, specified at the start of a function declaration, indicates - * that the given function does not return. (The function definition does not - * need to be annotated.) - * - * MOZ_NORETURN void abort(const char* msg); - * - * This modifier permits the compiler to optimize code assuming a call to such a - * function will never return. It also enables the compiler to avoid spurious - * warnings about not initializing variables, or about any other seemingly-dodgy - * operations performed after the function returns. - * - * This modifier does not affect the corresponding function's linking behavior. - */ -#if defined(MOZ_HAVE_NORETURN) -# define MOZ_NORETURN MOZ_HAVE_NORETURN -#else -# define MOZ_NORETURN /* no support */ -#endif - -/** - * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently - * executed. This may lead it to optimize for size more aggressively than speed, - * or to allocate the body of the function in a distant part of the text segment - * to help keep it from taking up unnecessary icache when it isn't in use. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_COLD int foo(); - * - * or - * - * MOZ_COLD int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_COLD __attribute__ ((cold)) -#else -# define MOZ_COLD -#endif - -/** - * MOZ_NONNULL tells the compiler that some of the arguments to a function are - * known to be non-null. The arguments are a list of 1-based argument indexes - * identifying arguments which are known to be non-null. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_NONNULL(1, 2) int foo(char *p, char *q); - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__))) -#else -# define MOZ_NONNULL(...) -#endif - -/* - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function - * declaration, indicates that for the purposes of static analysis, this - * function does not return. (The function definition does not need to be - * annotated.) - * - * MOZ_ReportCrash(const char* s, const char* file, int ln) - * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS - * - * Some static analyzers, like scan-build from clang, can use this information - * to eliminate false positives. From the upstream documentation of scan-build: - * "This attribute is useful for annotating assertion handlers that actually - * can return, but for the purpose of using the analyzer we want to pretend - * that such functions do not return." - * - */ -#if defined(MOZ_HAVE_ANALYZER_NORETURN) -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN -#else -# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */ -#endif - -/* - * MOZ_ASAN_DENYLIST is a macro to tell AddressSanitizer (a compile-time - * instrumentation shipped with Clang and GCC) to not instrument the annotated - * function. Furthermore, it will prevent the compiler from inlining the - * function because inlining currently breaks the denylisting mechanism of - * AddressSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define MOZ_HAVE_ASAN_DENYLIST -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) -# define MOZ_HAVE_ASAN_DENYLIST -# endif -#endif - -#if defined(MOZ_HAVE_ASAN_DENYLIST) -# define MOZ_ASAN_DENYLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) -#else -# define MOZ_ASAN_DENYLIST /* nothing */ -#endif - -/* - * MOZ_TSAN_DENYLIST is a macro to tell ThreadSanitizer (a compile-time - * instrumentation shipped with Clang) to not instrument the annotated function. - * Furthermore, it will prevent the compiler from inlining the function because - * inlining currently breaks the denylisting mechanism of ThreadSanitizer. - */ -#if defined(__has_feature) -# if __has_feature(thread_sanitizer) -# define MOZ_TSAN_DENYLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread)) -# else -# define MOZ_TSAN_DENYLIST /* nothing */ -# endif -#else -# define MOZ_TSAN_DENYLIST /* nothing */ -#endif - -/** - * MOZ_ALLOCATOR tells the compiler that the function it marks returns either a - * "fresh", "pointer-free" block of memory, or nullptr. "Fresh" means that the - * block is not pointed to by any other reachable pointer in the program. - * "Pointer-free" means that the block contains no pointers to any valid object - * in the program. It may be initialized with other (non-pointer) values. - * - * Placing this attribute on appropriate functions helps GCC analyze pointer - * aliasing more accurately in their callers. - * - * GCC warns if a caller ignores the value returned by a function marked with - * MOZ_ALLOCATOR: it is hard to imagine cases where dropping the value returned - * by a function that meets the criteria above would be intentional. - * - * Place this attribute after the argument list and 'this' qualifiers of a - * function definition. For example, write - * - * void *my_allocator(size_t) MOZ_ALLOCATOR; - * - * or - * - * void *my_allocator(size_t bytes) MOZ_ALLOCATOR { ... } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_ALLOCATOR __attribute__ ((malloc, warn_unused_result)) -#else -# define MOZ_ALLOCATOR -#endif - -/** - * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's - * return value is not used by the caller. - * - * Place this attribute at the very beginning of a function definition. For - * example, write - * - * MOZ_WARN_UNUSED_RESULT int foo(); - * - * or - * - * MOZ_WARN_UNUSED_RESULT int foo() { return 42; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) -#else -# define MOZ_WARN_UNUSED_RESULT -#endif - -#ifdef __cplusplus - -/* - * The following macros are attributes that support the static analysis plugin - * included with Mozilla, and will be implemented (when such support is enabled) - * as C++11 attributes. Since such attributes are legal pretty much everywhere - * and have subtly different semantics depending on their placement, the - * following is a guide on where to place the attributes. - * - * Attributes that apply to a struct or class precede the name of the class: - * (Note that this is different from the placement of final for classes!) - * - * class MOZ_CLASS_ATTRIBUTE SomeClass {}; - * - * Attributes that apply to functions follow the parentheses and const - * qualifiers but precede final, override and the function body: - * - * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE; - * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {} - * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0; - * void OverriddenFunction() MOZ_FUNCTION_ATTRIBUTE override; - * - * Attributes that apply to variables or parameters follow the variable's name: - * - * int variable MOZ_VARIABLE_ATTRIBUTE; - * - * Attributes that apply to types follow the type name: - * - * typedef int MOZ_TYPE_ATTRIBUTE MagicInt; - * int MOZ_TYPE_ATTRIBUTE someVariable; - * int* MOZ_TYPE_ATTRIBUTE magicPtrInt; - * int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt; - * - * Attributes that apply to statements precede the statement: - * - * MOZ_IF_ATTRIBUTE if (x == 0) - * MOZ_DO_ATTRIBUTE do { } while (0); - * - * Attributes that apply to labels precede the label: - * - * MOZ_LABEL_ATTRIBUTE target: - * goto target; - * MOZ_CASE_ATTRIBUTE case 5: - * MOZ_DEFAULT_ATTRIBUTE default: - * - * The static analyses that are performed by the plugin are as follows: - * - * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate - * subclasses must provide an exact override of this method; if a subclass - * does not override this method, the compiler will emit an error. This - * attribute is not limited to virtual methods, so if it is applied to a - * nonvirtual method and the subclass does not provide an equivalent - * definition, the compiler will emit an error. - * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack, so it is a compile-time error to use it, or - * an array of such objects, as a global or static variable, or as the type of - * a new expression (unless placement new is being used). If a member of - * another class uses this class, or if another class inherits from this - * class, then it is considered to be a stack class as well, although this - * attribute need not be provided in such cases. - * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is - * expected to live on the stack or in static storage, so it is a compile-time - * error to use it, or an array of such objects, as the type of a new - * expression (unless placement new is being used). If a member of another - * class uses this class, or if another class inherits from this class, then - * it is considered to be a non-heap class as well, although this attribute - * need not be provided in such cases. - * MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS: Applies to all classes that are - * intended to prevent introducing static initializers. This attribute - * currently makes it a compile-time error to instantiate these classes - * anywhere other than at the global scope, or as a static member of a class. - * MOZ_TRIVIAL_CTOR_DTOR: Applies to all classes that must have both a trivial - * constructor and a trivial destructor. Setting this attribute on a class - * makes it a compile-time error for that class to get a non-trivial - * constructor or destructor for any reason. - * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return - * value is allocated on the heap, and will as a result check such allocations - * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking. - * MOZ_IMPLICIT: Applies to constructors. Implicit conversion constructors - * are disallowed by default unless they are marked as MOZ_IMPLICIT. This - * attribute must be used for constructors which intend to provide implicit - * conversions. - * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile - * time error to pass arithmetic expressions on variables to the function. - * MOZ_OWNING_REF: Applies to declarations of pointer types. This attribute - * tells the compiler that the raw pointer is a strong reference, and that - * property is somehow enforced by the code. This can make the compiler - * ignore these pointers when validating the usage of pointers otherwise. - * MOZ_NON_OWNING_REF: Applies to declarations of pointer types. This attribute - * tells the compiler that the raw pointer is a weak reference, and that - * property is somehow enforced by the code. This can make the compiler - * ignore these pointers when validating the usage of pointers otherwise. - * MOZ_UNSAFE_REF: Applies to declarations of pointer types. This attribute - * should be used for non-owning references that can be unsafe, and their - * safety needs to be validated through code inspection. The string argument - * passed to this macro documents the safety conditions. - * MOZ_NO_ADDREF_RELEASE_ON_RETURN: Applies to function declarations. Makes it - * a compile time error to call AddRef or Release on the return value of a - * function. This is intended to be used with operator->() of our smart - * pointer classes to ensure that the refcount of an object wrapped in a - * smart pointer is not manipulated directly. - */ -#ifdef MOZ_CLANG_PLUGIN -# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) -# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) -# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) -# define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor"))) -# ifdef DEBUG - /* in debug builds, these classes do have non-trivial constructors. */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) -# else -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) \ - MOZ_TRIVIAL_CTOR_DTOR -# endif -# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) -# define MOZ_OWNING_REF __attribute__((annotate("moz_strong_ref"))) -# define MOZ_NON_OWNING_REF __attribute__((annotate("moz_weak_ref"))) -# define MOZ_UNSAFE_REF(reason) __attribute__((annotate("moz_strong_ref"))) -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return"))) -/* - * It turns out that clang doesn't like void func() __attribute__ {} without a - * warning, so use pragmas to disable the warning. This code won't work on GCC - * anyways, so the warning is safe to ignore. - */ -# define MOZ_HEAP_ALLOCATOR \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((annotate("moz_heap_allocator"))) \ - _Pragma("clang diagnostic pop") -#else -# define MOZ_MUST_OVERRIDE /* nothing */ -# define MOZ_STACK_CLASS /* nothing */ -# define MOZ_NONHEAP_CLASS /* nothing */ -# define MOZ_TRIVIAL_CTOR_DTOR /* nothing */ -# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS /* nothing */ -# define MOZ_IMPLICIT /* nothing */ -# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */ -# define MOZ_HEAP_ALLOCATOR /* nothing */ -# define MOZ_OWNING_REF /* nothing */ -# define MOZ_NON_OWNING_REF /* nothing */ -# define MOZ_UNSAFE_REF(reason) /* nothing */ -# define MOZ_NO_ADDREF_RELEASE_ON_RETURN /* nothing */ -#endif /* MOZ_CLANG_PLUGIN */ - -#endif /* __cplusplus */ - -#endif /* mozilla_Attributes_h */ diff --git a/include/onlineupdate/mozilla/Compiler.h b/include/onlineupdate/mozilla/Compiler.h deleted file mode 100644 index 6d6fcbbb19f5..000000000000 --- a/include/onlineupdate/mozilla/Compiler.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Various compiler checks. */ - -#ifndef mozilla_Compiler_h -#define mozilla_Compiler_h - -#define MOZ_IS_GCC 0 -#define MOS_IS_MSVC 0 - -#if !defined(__clang__) && defined(__GNUC__) - -# undef MOZ_IS_GCC -# define MOZ_IS_GCC 1 - /* - * This macro should simplify gcc version checking. For example, to check - * for gcc 4.7.1 or later, check `#if MOZ_GCC_VERSION_AT_LEAST(4, 7, 1)`. - */ -# define MOZ_GCC_VERSION_AT_LEAST(major, minor, patchlevel) \ - ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \ - >= ((major) * 10000 + (minor) * 100 + (patchlevel))) -# if !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) -# error "mfbt (and Gecko) require at least gcc 4.7 to build." -# endif - -#elif defined(_MSC_VER) - -# undef MOZ_IS_MSVC -# define MOZ_IS_MSVC 1 - -#endif - -/* - * The situation with standard libraries is a lot worse than with compilers, - * particularly as clang and gcc could end up using one of three or so standard - * libraries, and they may not be up-to-snuff with newer C++11 versions. To - * detect the library, we're going to include cstddef (which is a small header - * which will be transitively included by everybody else at some point) to grab - * the version macros and deduce macros from there. - */ -#ifdef __cplusplus -# include <cstddef> -# ifdef _STLPORT_MAJOR -# define MOZ_USING_STLPORT 1 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) \ - (_STLPORT_VERSION >= ((major) << 8 | (minor) << 4 | (patch))) -# elif defined(_LIBCPP_VERSION) - /* - * libc++, unfortunately, doesn't appear to have useful versioning macros. - * Hopefully, the recommendations of N3694 with respect to standard libraries - * will get applied instead and we won't need to worry about version numbers - * here. - */ -# define MOZ_USING_LIBCXX 1 -# elif defined(__GLIBCXX__) -# define MOZ_USING_LIBSTDCXX 1 - /* - * libstdc++ is also annoying and doesn't give us useful versioning macros - * for the library. If we're using gcc, then assume that libstdc++ matches - * the compiler version. If we're using clang, we're going to have to fake - * major/minor combinations by looking for newly-defined config macros. - */ -# if MOZ_IS_GCC -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - MOZ_GCC_VERSION_AT_LEAST(major, minor, patch) -# elif defined(_GLIBCXX_THROW_OR_ABORT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 8)) -# elif defined(_GLIBCXX_NOEXCEPT) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 7)) -# elif defined(_GLIBCXX_USE_DEPRECATED) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 6)) -# elif defined(_GLIBCXX_PSEUDO_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 5)) -# elif defined(_GLIBCXX_BEGIN_EXTERN_C) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 4)) -# elif defined(_GLIBCXX_VISIBILITY_ATTR) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 3)) -# elif defined(_GLIBCXX_VISIBILITY) -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \ - ((major) < 4 || ((major) == 4 && (minor) <= 2)) -# else -# error "Your version of libstdc++ is unknown to us and is likely too old." -# endif -# endif - - // Flesh out the defines for everyone else -# ifndef MOZ_USING_STLPORT -# define MOZ_USING_STLPORT 0 -# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -# ifndef MOZ_USING_LIBCXX -# define MOZ_USING_LIBCXX 0 -# endif -# ifndef MOZ_USING_LIBSTDCXX -# define MOZ_USING_LIBSTDCXX 0 -# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) 0 -# endif -#endif /* __cplusplus */ - -#endif /* mozilla_Compiler_h */ diff --git a/include/onlineupdate/mozilla/Likely.h b/include/onlineupdate/mozilla/Likely.h deleted file mode 100644 index 5625bb226e40..000000000000 --- a/include/onlineupdate/mozilla/Likely.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a - * boolean predicate should be branch-predicted. - */ - -#ifndef mozilla_Likely_h -#define mozilla_Likely_h - -#if defined(__clang__) || defined(__GNUC__) -#define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1)) -#define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -#define MOZ_LIKELY(x) (!!(x)) -#define MOZ_UNLIKELY(x) (!!(x)) -#endif - -#endif /* mozilla_Likely_h */ diff --git a/include/onlineupdate/mozilla/MacroArgs.h b/include/onlineupdate/mozilla/MacroArgs.h deleted file mode 100644 index c8b733821035..000000000000 --- a/include/onlineupdate/mozilla/MacroArgs.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Implements various macros meant to ease the use of variadic macros. - */ - -#ifndef mozilla_MacroArgs_h -#define mozilla_MacroArgs_h - -/* - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) counts the number of variadic - * arguments and prefixes it with |aPrefix|. For example: - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2 - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3 - * - * You must pass in between 1 and 50 (inclusive) variadic arguments, past - * |aPrefix|. It is not legal to do - * - * MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix) - * - * (that is, pass in 0 variadic arguments). To ensure that a compile-time - * error occurs when these constraints are violated, use the - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments - * wherever this macro is used. - * - * Passing (__VA_ARGS__, <rest of arguments>) rather than simply calling - * MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, <rest of arguments>) very - * carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__ - * as a single token in argument lists. For details, see: - * - * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement - * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644 - */ -#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \ - MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \ - aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \ - aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \ - aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \ - aPrefix##35, aPrefix##34, aPrefix##33, aPrefix##32, aPrefix##31, \ - aPrefix##30, aPrefix##29, aPrefix##28, aPrefix##27, aPrefix##26, \ - aPrefix##25, aPrefix##24, aPrefix##23, aPrefix##22, aPrefix##21, \ - aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \ - aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \ - aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \ - aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0)) - -#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \ - MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs - -#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \ - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \ - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \ - a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \ - a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \ - a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \ - a51, ...) a51 - -/* - * MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs - * when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are - * violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used - * and pass it the same variadic arguments. - * - * This macro employs a few dirty tricks to function. To detect the zero - * argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to - * what it should be in the absence of arguments. - * - * Detecting too many arguments is a little trickier. With a valid argument - * count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14. - * With a prefix of 0.0, it expands to e.g. 0.04. If there are too many - * arguments, it expands to the first argument over the limit. If this - * exceeding argument is a number, the assertion will fail as there is no - * number than can simultaneously be both > 10 and == 0. If the exceeding - * argument is not a number, a compile-time error should still occur due to - * the operations performed on it. - */ -#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x -#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \ - static_assert( \ - sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \ - (MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \ - (int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \ - "MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */ - -/* - * MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N| - * arguments. For example: - * - * MOZ_ARGS_AFTER_2(a, b, c, d) expands to: c, d - */ -#define MOZ_ARGS_AFTER_1(a1, ...) __VA_ARGS__ -#define MOZ_ARGS_AFTER_2(a1, a2, ...) __VA_ARGS__ - -/* - * MOZ_ARG_N expands to its |N|th argument. - */ -#define MOZ_ARG_1(a1, ...) a1 -#define MOZ_ARG_2(a1, a2, ...) a2 - -#endif /* mozilla_MacroArgs_h */ diff --git a/include/onlineupdate/mozilla/TypeTraits.h b/include/onlineupdate/mozilla/TypeTraits.h deleted file mode 100644 index 7ca9d3315837..000000000000 --- a/include/onlineupdate/mozilla/TypeTraits.h +++ /dev/null @@ -1,1116 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Template-based metaprogramming and type-testing facilities. */ - -#ifndef mozilla_TypeTraits_h -#define mozilla_TypeTraits_h - -#include "Types.h" - -/* - * These traits are approximate copies of the traits and semantics from C++11's - * <type_traits> header. Don't add traits not in that header! When all - * platforms provide that header, we can convert all users and remove this one. - */ - -#include <wchar.h> - -namespace mozilla { - -/* Forward declarations. */ - -template<typename> struct RemoveCV; - -/* 20.9.3 Helper classes [meta.help] */ - -/** - * Helper class used as a base for various type traits, exposed publicly - * because <type_traits> exposes it as well. - */ -template<typename T, T Value> -struct IntegralConstant -{ - static const T value = Value; - typedef T ValueType; - typedef IntegralConstant<T, Value> Type; -}; - -/** Convenient aliases. */ -typedef IntegralConstant<bool, true> TrueType; -typedef IntegralConstant<bool, false> FalseType; - -/* 20.9.4 Unary type traits [meta.unary] */ - -/* 20.9.4.1 Primary type categories [meta.unary.cat] */ - -namespace detail { - -template<typename T> -struct IsVoidHelper : FalseType {}; - -template<> -struct IsVoidHelper<void> : TrueType {}; - -} // namespace detail - -/** - * IsVoid determines whether a type is void. - * - * mozilla::IsVoid<int>::value is false; - * mozilla::IsVoid<void>::value is true; - * mozilla::IsVoid<void*>::value is false; - * mozilla::IsVoid<volatile void>::value is true. - */ -template<typename T> -struct IsVoid : detail::IsVoidHelper<typename RemoveCV<T>::Type> {}; - -namespace detail { - -template <typename T> -struct IsIntegralHelper : FalseType {}; - -template<> struct IsIntegralHelper<char> : TrueType {}; -template<> struct IsIntegralHelper<signed char> : TrueType {}; -template<> struct IsIntegralHelper<unsigned char> : TrueType {}; -template<> struct IsIntegralHelper<short> : TrueType {}; -template<> struct IsIntegralHelper<unsigned short> : TrueType {}; -template<> struct IsIntegralHelper<int> : TrueType {}; -template<> struct IsIntegralHelper<unsigned int> : TrueType {}; -template<> struct IsIntegralHelper<long> : TrueType {}; -template<> struct IsIntegralHelper<unsigned long> : TrueType {}; -template<> struct IsIntegralHelper<long long> : TrueType {}; -template<> struct IsIntegralHelper<unsigned long long> : TrueType {}; -template<> struct IsIntegralHelper<bool> : TrueType {}; -template<> struct IsIntegralHelper<wchar_t> : TrueType {}; -#ifdef MOZ_CHAR16_IS_NOT_WCHAR -template<> struct IsIntegralHelper<char16_t> : TrueType {}; -#endif - -} /* namespace detail */ - -/** - * IsIntegral determines whether a type is an integral type. - * - * mozilla::IsIntegral<int>::value is true; - * mozilla::IsIntegral<unsigned short>::value is true; - * mozilla::IsIntegral<const long>::value is true; - * mozilla::IsIntegral<int*>::value is false; - * mozilla::IsIntegral<double>::value is false; - * - * Note that the behavior of IsIntegral on char16_t and char32_t is - * unspecified. - */ -template<typename T> -struct IsIntegral : detail::IsIntegralHelper<typename RemoveCV<T>::Type> -{}; - -template<typename T, typename U> -struct IsSame; - -namespace detail { - -template<typename T> -struct IsFloatingPointHelper - : IntegralConstant<bool, - IsSame<T, float>::value || - IsSame<T, double>::value || - IsSame<T, long double>::value> -{}; - -} // namespace detail - -/** - * IsFloatingPoint determines whether a type is a floating point type (float, - * double, long double). - * - * mozilla::IsFloatingPoint<int>::value is false; - * mozilla::IsFloatingPoint<const float>::value is true; - * mozilla::IsFloatingPoint<long double>::value is true; - * mozilla::IsFloatingPoint<double*>::value is false. - */ -template<typename T> -struct IsFloatingPoint - : detail::IsFloatingPointHelper<typename RemoveCV<T>::Type> -{}; - -namespace detail { - -template<typename T> -struct IsArrayHelper : FalseType {}; - -template<typename T, decltype(sizeof(1)) N> -struct IsArrayHelper<T[N]> : TrueType {}; - -template<typename T> -struct IsArrayHelper<T[]> : TrueType {}; - -} // namespace detail - -/** - * IsArray determines whether a type is an array type, of known or unknown - * length. - * - * mozilla::IsArray<int>::value is false; - * mozilla::IsArray<int[]>::value is true; - * mozilla::IsArray<int[5]>::value is true. - */ -template<typename T> -struct IsArray : detail::IsArrayHelper<typename RemoveCV<T>::Type> -{}; - -namespace detail { - -template<typename T> -struct IsPointerHelper : FalseType {}; - -template<typename T> -struct IsPointerHelper<T*> : TrueType {}; - -} // namespace detail - -/** - * IsPointer determines whether a type is a possibly-CV-qualified pointer type - * (but not a pointer-to-member type). - * - * mozilla::IsPointer<struct S*>::value is true; - * mozilla::IsPointer<int*>::value is true; - * mozilla::IsPointer<int**>::value is true; - * mozilla::IsPointer<const int*>::value is true; - * mozilla::IsPointer<int* const>::value is true; - * mozilla::IsPointer<int* volatile>::value is true; - * mozilla::IsPointer<void (*)(void)>::value is true; - * mozilla::IsPointer<int>::value is false; - * mozilla::IsPointer<struct S>::value is false. - * mozilla::IsPointer<int(struct S::*)>::value is false - */ -template<typename T> -struct IsPointer : detail::IsPointerHelper<typename RemoveCV<T>::Type> -{}; - -/** - * IsLvalueReference determines whether a type is an lvalue reference. - * - * mozilla::IsLvalueReference<struct S*>::value is false; - * mozilla::IsLvalueReference<int**>::value is false; - * mozilla::IsLvalueReference<void (*)(void)>::value is false; - * mozilla::IsLvalueReference<int>::value is false; - * mozilla::IsLvalueReference<struct S>::value is false; - * mozilla::IsLvalueReference<struct S*&>::value is true; - * mozilla::IsLvalueReference<struct S&&>::value is false. - */ -template<typename T> -struct IsLvalueReference : FalseType {}; - -template<typename T> -struct IsLvalueReference<T&> : TrueType {}; - -/** - * IsRvalueReference determines whether a type is an rvalue reference. - * - * mozilla::IsRvalueReference<struct S*>::value is false; - * mozilla::IsRvalueReference<int**>::value is false; - * mozilla::IsRvalueReference<void (*)(void)>::value is false; - * mozilla::IsRvalueReference<int>::value is false; - * mozilla::IsRvalueReference<struct S>::value is false; - * mozilla::IsRvalueReference<struct S*&>::value is false; - * mozilla::IsRvalueReference<struct S&&>::value is true. - */ -template<typename T> -struct IsRvalueReference : FalseType {}; - -template<typename T> -struct IsRvalueReference<T&&> : TrueType {}; - -namespace detail { - -// __is_enum is a supported extension across all of our supported compilers. -template<typename T> -struct IsEnumHelper - : IntegralConstant<bool, __is_enum(T)> -{}; - -} // namespace detail - -/** - * IsEnum determines whether a type is an enum type. - * - * mozilla::IsEnum<enum S>::value is true; - * mozilla::IsEnum<enum S*>::value is false; - * mozilla::IsEnum<int>::value is false; - */ -template<typename T> -struct IsEnum - : detail::IsEnumHelper<typename RemoveCV<T>::Type> -{}; - -namespace detail { - -// __is_class is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template<typename T> -struct IsClassHelper - : IntegralConstant<bool, __is_class(T)> -{}; - -} // namespace detail - -/** - * IsClass determines whether a type is a class type (but not a union). - * - * struct S {}; - * union U {}; - * mozilla::IsClass<int>::value is false; - * mozilla::IsClass<const S>::value is true; - * mozilla::IsClass<U>::value is false; - */ -template<typename T> -struct IsClass - : detail::IsClassHelper<typename RemoveCV<T>::Type> -{}; - -/* 20.9.4.2 Composite type traits [meta.unary.comp] */ - -/** - * IsReference determines whether a type is an lvalue or rvalue reference. - * - * mozilla::IsReference<struct S*>::value is false; - * mozilla::IsReference<int**>::value is false; - * mozilla::IsReference<int&>::value is true; - * mozilla::IsReference<void (*)(void)>::value is false; - * mozilla::IsReference<const int&>::value is true; - * mozilla::IsReference<int>::value is false; - * mozilla::IsReference<struct S>::value is false; - * mozilla::IsReference<struct S&>::value is true; - * mozilla::IsReference<struct S*&>::value is true; - * mozilla::IsReference<struct S&&>::value is true. - */ -template<typename T> -struct IsReference - : IntegralConstant<bool, - IsLvalueReference<T>::value || IsRvalueReference<T>::value> -{}; - -/** - * IsArithmetic determines whether a type is arithmetic. A type is arithmetic - * iff it is an integral type or a floating point type. - * - * mozilla::IsArithmetic<int>::value is true; - * mozilla::IsArithmetic<double>::value is true; - * mozilla::IsArithmetic<long double*>::value is false. - */ -template<typename T> -struct IsArithmetic - : IntegralConstant<bool, IsIntegral<T>::value || IsFloatingPoint<T>::value> -{}; - -/* 20.9.4.3 Type properties [meta.unary.prop] */ - -/** - * IsConst determines whether a type is const or not. - * - * mozilla::IsConst<int>::value is false; - * mozilla::IsConst<void* const>::value is true; - * mozilla::IsConst<const char*>::value is false. - */ -template<typename T> -struct IsConst : FalseType {}; - -template<typename T> -struct IsConst<const T> : TrueType {}; - -/** - * IsVolatile determines whether a type is volatile or not. - * - * mozilla::IsVolatile<int>::value is false; - * mozilla::IsVolatile<void* volatile>::value is true; - * mozilla::IsVolatile<volatile char*>::value is false. - */ -template<typename T> -struct IsVolatile : FalseType {}; - -template<typename T> -struct IsVolatile<volatile T> : TrueType {}; - -/** - * Traits class for identifying POD types. Until C++11 there's no automatic - * way to detect PODs, so for the moment this is done manually. Users may - * define specializations of this class that inherit from mozilla::TrueType and - * mozilla::FalseType (or equivalently mozilla::IntegralConstant<bool, true or - * false>, or conveniently from mozilla::IsPod for composite types) as needed to - * ensure correct IsPod behavior. - */ -template<typename T> -struct IsPod : public FalseType {}; - -template<> struct IsPod<char> : TrueType {}; -template<> struct IsPod<signed char> : TrueType {}; -template<> struct IsPod<unsigned char> : TrueType {}; -template<> struct IsPod<short> : TrueType {}; -template<> struct IsPod<unsigned short> : TrueType {}; -template<> struct IsPod<int> : TrueType {}; -template<> struct IsPod<unsigned int> : TrueType {}; -template<> struct IsPod<long> : TrueType {}; -template<> struct IsPod<unsigned long> : TrueType {}; -template<> struct IsPod<long long> : TrueType {}; -template<> struct IsPod<unsigned long long> : TrueType {}; -template<> struct IsPod<bool> : TrueType {}; -template<> struct IsPod<float> : TrueType {}; -template<> struct IsPod<double> : TrueType {}; -template<> struct IsPod<wchar_t> : TrueType {}; -#ifdef MOZ_CHAR16_IS_NOT_WCHAR -template<> struct IsPod<char16_t> : TrueType {}; -#endif -template<typename T> struct IsPod<T*> : TrueType {}; - -namespace detail { - -// __is_empty is a supported extension across all of our supported compilers: -// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html -// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits -// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx -template<typename T> -struct IsEmptyHelper - : IntegralConstant<bool, IsClass<T>::value && __is_empty(T)> -{}; - -} // namespace detail - -/** - * IsEmpty determines whether a type is a class (but not a union) that is empty. - * - * A class is empty iff it and all its base classes have no non-static data - * members (except bit-fields of length 0) and no virtual member functions, and - * no base class is empty or a virtual base class. - * - * Intuitively, empty classes don't have any data that has to be stored in - * instances of those classes. (The size of the class must still be non-zero, - * because distinct array elements of any type must have different addresses. - * However, if the Empty Base Optimization is implemented by the compiler [most - * compilers implement it, and in certain cases C++11 requires it], the size of - * a class inheriting from an empty |Base| class need not be inflated by - * |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or - * vtable pointers that must be stored in each instance for proper behavior. - * - * static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty"); - * union U1 { int x; }; - * static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty"); - * struct E1 {}; - * struct E2 { int : 0 }; - * struct E3 : E1 {}; - * struct E4 : E2 {}; - * static_assert(mozilla::IsEmpty<E1>::value && - * mozilla::IsEmpty<E2>::value && - * mozilla::IsEmpty<E3>::value && - * mozilla::IsEmpty<E4>::value, - * "all empty"); - * union U2 { E1 e1; }; - * static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty"); - * struct NE1 { int x; }; - * struct NE2 : virtual E1 {}; - * struct NE3 : E2 { virtual ~NE3() {} }; - * struct NE4 { virtual void f() {} }; - * static_assert(!mozilla::IsEmpty<NE1>::value && - * !mozilla::IsEmpty<NE2>::value && - * !mozilla::IsEmpty<NE3>::value && - * !mozilla::IsEmpty<NE4>::value, - * "all empty"); - */ -template<typename T> -struct IsEmpty : detail::IsEmptyHelper<typename RemoveCV<T>::Type> -{}; - - -namespace detail { - -template<typename T, - bool = IsFloatingPoint<T>::value, - bool = IsIntegral<T>::value, - typename NoCV = typename RemoveCV<T>::Type> -struct IsSignedHelper; - -// Floating point is signed. -template<typename T, typename NoCV> -struct IsSignedHelper<T, true, false, NoCV> : TrueType {}; - -// Integral is conditionally signed. -template<typename T, typename NoCV> -struct IsSignedHelper<T, false, true, NoCV> - : IntegralConstant<bool, bool(NoCV(-1) < NoCV(1))> -{}; - -// Non-floating point, non-integral is not signed. -template<typename T, typename NoCV> -struct IsSignedHelper<T, false, false, NoCV> : FalseType {}; - -} // namespace detail - -/** - * IsSigned determines whether a type is a signed arithmetic type. |char| is - * considered a signed type if it has the same representation as |signed char|. - * - * mozilla::IsSigned<int>::value is true; - * mozilla::IsSigned<const unsigned int>::value is false; - * mozilla::IsSigned<unsigned char>::value is false; - * mozilla::IsSigned<float>::value is true. - */ -template<typename T> -struct IsSigned : detail::IsSignedHelper<T> {}; - -namespace detail { - -template<typename T, - bool = IsFloatingPoint<T>::value, - bool = IsIntegral<T>::value, - typename NoCV = typename RemoveCV<T>::Type> -struct IsUnsignedHelper; - -// Floating point is not unsigned. -template<typename T, typename NoCV> -struct IsUnsignedHelper<T, true, false, NoCV> : FalseType {}; - -// Integral is conditionally unsigned. -template<typename T, typename NoCV> -struct IsUnsignedHelper<T, false, true, NoCV> - : IntegralConstant<bool, - (IsSame<NoCV, bool>::value || bool(NoCV(1) < NoCV(-1)))> -{}; - -// Non-floating point, non-integral is not unsigned. -template<typename T, typename NoCV> -struct IsUnsignedHelper<T, false, false, NoCV> : FalseType {}; - -} // namespace detail - -/** - * IsUnsigned determines whether a type is an unsigned arithmetic type. - * - * mozilla::IsUnsigned<int>::value is false; - * mozilla::IsUnsigned<const unsigned int>::value is true; - * mozilla::IsUnsigned<unsigned char>::value is true; - * mozilla::IsUnsigned<float>::value is false. - */ -template<typename T> -struct IsUnsigned : detail::IsUnsignedHelper<T> {}; - -/* 20.9.5 Type property queries [meta.unary.prop.query] */ - -/* 20.9.6 Relationships between types [meta.rel] */ - -/** - * IsSame tests whether two types are the same type. - * - * mozilla::IsSame<int, int>::value is true; - * mozilla::IsSame<int*, int*>::value is true; - * mozilla::IsSame<int, unsigned int>::value is false; - * mozilla::IsSame<void, void>::value is true; - * mozilla::IsSame<const int, int>::value is false; - * mozilla::IsSame<struct S, struct S>::value is true. - */ -template<typename T, typename U> -struct IsSame : FalseType {}; - -template<typename T> -struct IsSame<T, T> : TrueType {}; - -namespace detail { - -#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) - -template<class Base, class Derived> -struct BaseOfTester : IntegralConstant<bool, __is_base_of(Base, Derived)> {}; - -#else - -// The trickery used to implement IsBaseOf here makes it possible to use it for -// the cases of private and multiple inheritance. This code was inspired by the -// sample code here: -// -// http://stackoverflow.com/questions/2910979/how-is-base-of-works -template<class Base, class Derived> -struct BaseOfHelper -{ -public: - operator Base*() const; - operator Derived*(); -}; - -template<class Base, class Derived> -struct BaseOfTester -{ -private: - template<class T> - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char); -}; - -template<class Base, class Derived> -struct BaseOfTester<Base, const Derived> -{ -private: - template<class T> - static char test(Derived*, T); - static int test(Base*, int); - -public: - static const bool value = - sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char); -}; - -template<class Base, class Derived> -struct BaseOfTester<Base&, Derived&> : FalseType {}; - -template<class Type> -struct BaseOfTester<Type, Type> : TrueType {}; - -template<class Type> -struct BaseOfTester<Type, const Type> : TrueType {}; - -#endif - -} /* namespace detail */ - -/* - * IsBaseOf allows to know whether a given class is derived from another. - * - * Consider the following class definitions: - * - * class A {}; - * class B : public A {}; - * class C {}; - * - * mozilla::IsBaseOf<A, B>::value is true; - * mozilla::IsBaseOf<A, C>::value is false; - */ -template<class Base, class Derived> -struct IsBaseOf - : IntegralConstant<bool, detail::BaseOfTester<Base, Derived>::value> -{}; - -namespace detail { - -template<typename From, typename To> -struct ConvertibleTester -{ -private: - static From create(); - - template<typename From1, typename To1> - static char test(To to); - - template<typename From1, typename To1> - static int test(...); - -public: - static const bool value = - sizeof(test<From, To>(create())) == sizeof(char); -}; - -} // namespace detail - -/** - * IsConvertible determines whether a value of type From will implicitly convert - * to a value of type To. For example: - * - * struct A {}; - * struct B : public A {}; - * struct C {}; - * - * mozilla::IsConvertible<A, A>::value is true; - * mozilla::IsConvertible<A*, A*>::value is true; - * mozilla::IsConvertible<B, A>::value is true; - * mozilla::IsConvertible<B*, A*>::value is true; - * mozilla::IsConvertible<C, A>::value is false; - * mozilla::IsConvertible<A, C>::value is false; - * mozilla::IsConvertible<A*, C*>::value is false; - * mozilla::IsConvertible<C*, A*>::value is false. - * - * For obscure reasons, you can't use IsConvertible when the types being tested - * are related through private inheritance, and you'll get a compile error if - * you try. Just don't do it! - * - * Note - we need special handling for void, which ConvertibleTester doesn't - * handle. The void handling here doesn't handle const/volatile void correctly, - * which could be easily fixed if the need arises. - */ -template<typename From, typename To> -struct IsConvertible - : IntegralConstant<bool, detail::ConvertibleTester<From, To>::value> -{}; - -template<typename B> -struct IsConvertible<void, B> - : IntegralConstant<bool, IsVoid<B>::value> -{}; - -template<typename A> -struct IsConvertible<A, void> - : IntegralConstant<bool, IsVoid<A>::value> -{}; - -template<> -struct IsConvertible<void, void> - : TrueType -{}; - -/* 20.9.7 Transformations between types [meta.trans] */ - -/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */ - -/** - * RemoveConst removes top-level const qualifications on a type. - * - * mozilla::RemoveConst<int>::Type is int; - * mozilla::RemoveConst<const int>::Type is int; - * mozilla::RemoveConst<const int*>::Type is const int*; - * mozilla::RemoveConst<int* const>::Type is int*. - */ -template<typename T> -struct RemoveConst -{ - typedef T Type; -}; - -template<typename T> -struct RemoveConst<const T> -{ - typedef T Type; -}; - -/** - * RemoveVolatile removes top-level volatile qualifications on a type. - * - * mozilla::RemoveVolatile<int>::Type is int; - * mozilla::RemoveVolatile<volatile int>::Type is int; - * mozilla::RemoveVolatile<volatile int*>::Type is volatile int*; - * mozilla::RemoveVolatile<int* volatile>::Type is int*. - */ -template<typename T> -struct RemoveVolatile -{ - typedef T Type; -}; - -template<typename T> -struct RemoveVolatile<volatile T> -{ - typedef T Type; -}; - -/** - * RemoveCV removes top-level const and volatile qualifications on a type. - * - * mozilla::RemoveCV<int>::Type is int; - * mozilla::RemoveCV<const int>::Type is int; - * mozilla::RemoveCV<volatile int>::Type is int; - * mozilla::RemoveCV<int* const volatile>::Type is int*. - */ -template<typename T> -struct RemoveCV -{ - typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type; -}; - -/* 20.9.7.2 Reference modifications [meta.trans.ref] */ - -/** - * Converts reference types to the underlying types. - * - * mozilla::RemoveReference<T>::Type is T; - * mozilla::RemoveReference<T&>::Type is T; - * mozilla::RemoveReference<T&&>::Type is T; - */ - -template<typename T> -struct RemoveReference -{ - typedef T Type; -}; - -template<typename T> -struct RemoveReference<T&> -{ - typedef T Type; -}; - -template<typename T> -struct RemoveReference<T&&> -{ - typedef T Type; -}; - -template<bool Condition, typename A, typename B> -struct Conditional; - -namespace detail { - -enum Voidness { TIsVoid, TIsNotVoid }; - -template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid> -struct AddLvalueReferenceHelper; - -template<typename T> -struct AddLvalueReferenceHelper<T, TIsVoid> -{ - typedef void Type; -}; - -template<typename T> -struct AddLvalueReferenceHelper<T, TIsNotVoid> -{ - typedef T& Type; -}; - -} // namespace detail - -/** - * AddLvalueReference adds an lvalue & reference to T if one isn't already - * present. (Note: adding an lvalue reference to an rvalue && reference in - * essence replaces the && with a &&, per C+11 reference collapsing rules. For - * example, int&& would become int&.) - * - * The final computed type will only *not* be an lvalue reference if T is void. - * - * mozilla::AddLvalueReference<int>::Type is int&; - * mozilla::AddLvalueRference<volatile int&>::Type is volatile int&; - * mozilla::AddLvalueReference<void*>::Type is void*&; - * mozilla::AddLvalueReference<void>::Type is void; - * mozilla::AddLvalueReference<struct S&&>::Type is struct S&. - */ -template<typename T> -struct AddLvalueReference - : detail::AddLvalueReferenceHelper<T> -{}; - -namespace detail { - -template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid> -struct AddRvalueReferenceHelper; - -template<typename T> -struct AddRvalueReferenceHelper<T, TIsVoid> -{ - typedef void Type; -}; - -template<typename T> -struct AddRvalueReferenceHelper<T, TIsNotVoid> -{ - typedef T&& Type; -}; - -} // namespace detail - -/** - * AddRvalueReference adds an rvalue && reference to T if one isn't already - * present. (Note: adding an rvalue reference to an lvalue & reference in - * essence keeps the &, per C+11 reference collapsing rules. For example, - * int& would remain int&.) - * - * The final computed type will only *not* be a reference if T is void. - * - * mozilla::AddRvalueReference<int>::Type is int&&; - * mozilla::AddRvalueRference<volatile int&>::Type is volatile int&; - * mozilla::AddRvalueRference<const int&&>::Type is const int&&; - * mozilla::AddRvalueReference<void*>::Type is void*&&; - * mozilla::AddRvalueReference<void>::Type is void; - * mozilla::AddRvalueReference<struct S&>::Type is struct S&. - */ -template<typename T> -struct AddRvalueReference - : detail::AddRvalueReferenceHelper<T> -{}; - -/* 20.2.4 Function template declval [declval] */ - -/** - * DeclVal simplifies the definition of expressions which occur as unevaluated - * operands. It converts T to a reference type, making it possible to use in - * decltype expressions even if T does not have a default constructor, e.g.: - * decltype(DeclVal<TWithNoDefaultConstructor>().foo()) - */ -template<typename T> -typename AddRvalueReference<T>::Type DeclVal(); - -/* 20.9.7.3 Sign modifications [meta.trans.sign] */ - -template<bool B, typename T = void> -struct EnableIf; - -namespace detail { - -template<bool MakeConst, typename T> -struct WithC : Conditional<MakeConst, const T, T> -{}; - -template<bool MakeVolatile, typename T> -struct WithV : Conditional<MakeVolatile, volatile T, T> -{}; - - -template<bool MakeConst, bool MakeVolatile, typename T> -struct WithCV : WithC<MakeConst, typename WithV<MakeVolatile, T>::Type> -{}; - -template<typename T> -struct CorrespondingSigned; - -template<> -struct CorrespondingSigned<char> { typedef signed char Type; }; -template<> -struct CorrespondingSigned<unsigned char> { typedef signed char Type; }; -template<> -struct CorrespondingSigned<unsigned short> { typedef short Type; }; -template<> -struct CorrespondingSigned<unsigned int> { typedef int Type; }; -template<> -struct CorrespondingSigned<unsigned long> { typedef long Type; }; -template<> -struct CorrespondingSigned<unsigned long long> { typedef long long Type; }; - -template<typename T, - typename CVRemoved = typename RemoveCV<T>::Type, - bool IsSignedIntegerType = IsSigned<CVRemoved>::value && - !IsSame<char, CVRemoved>::value> -struct MakeSigned; - -template<typename T, typename CVRemoved> -struct MakeSigned<T, CVRemoved, true> -{ - typedef T Type; -}; - -template<typename T, typename CVRemoved> -struct MakeSigned<T, CVRemoved, false> - : WithCV<IsConst<T>::value, IsVolatile<T>::value, - typename CorrespondingSigned<CVRemoved>::Type> -{}; - -} // namespace detail - -/** - * MakeSigned produces the corresponding signed integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already a signed integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is an unsigned integer type, the signed variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the integral type of the same size as T, with the lowest rank, - * with T's const/volatile qualifiers, is produced. (This basically only acts - * to produce signed char when T = char.) - * - * mozilla::MakeSigned<unsigned long>::Type is signed long; - * mozilla::MakeSigned<volatile int>::Type is volatile int; - * mozilla::MakeSigned<const unsigned short>::Type is const signed short; - * mozilla::MakeSigned<const char>::Type is const signed char; - * mozilla::MakeSigned<bool> is an error; - * mozilla::MakeSigned<void*> is an error. - */ -template<typename T> -struct MakeSigned - : EnableIf<IsIntegral<T>::value && - !IsSame<bool, typename RemoveCV<T>::Type>::value, - typename detail::MakeSigned<T> - >::Type -{}; - -namespace detail { - -template<typename T> -struct CorrespondingUnsigned; - -template<> -struct CorrespondingUnsigned<char> { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned<signed char> { typedef unsigned char Type; }; -template<> -struct CorrespondingUnsigned<short> { typedef unsigned short Type; }; -template<> -struct CorrespondingUnsigned<int> { typedef unsigned int Type; }; -template<> -struct CorrespondingUnsigned<long> { typedef unsigned long Type; }; -template<> -struct CorrespondingUnsigned<long long> { typedef unsigned long long Type; }; - - -template<typename T, - typename CVRemoved = typename RemoveCV<T>::Type, - bool IsUnsignedIntegerType = IsUnsigned<CVRemoved>::value && - !IsSame<char, CVRemoved>::value> -struct MakeUnsigned; - -template<typename T, typename CVRemoved> -struct MakeUnsigned<T, CVRemoved, true> -{ - typedef T Type; -}; - -template<typename T, typename CVRemoved> -struct MakeUnsigned<T, CVRemoved, false> - : WithCV<IsConst<T>::value, IsVolatile<T>::value, - typename CorrespondingUnsigned<CVRemoved>::Type> -{}; - -} // namespace detail - -/** - * MakeUnsigned produces the corresponding unsigned integer type for a given - * integral type T, with the const/volatile qualifiers of T. T must be a - * possibly-const/volatile-qualified integral type that isn't bool. - * - * If T is already an unsigned integer type (not including char!), then T is - * produced. - * - * Otherwise, if T is a signed integer type, the unsigned variety of T, with - * T's const/volatile qualifiers, is produced. - * - * Otherwise, the unsigned integral type of the same size as T, with the lowest - * rank, with T's const/volatile qualifiers, is produced. (This basically only - * acts to produce unsigned char when T = char.) - * - * mozilla::MakeUnsigned<signed long>::Type is unsigned long; - * mozilla::MakeUnsigned<volatile unsigned int>::Type is volatile unsigned int; - * mozilla::MakeUnsigned<const signed short>::Type is const unsigned short; - * mozilla::MakeUnsigned<const char>::Type is const unsigned char; - * mozilla::MakeUnsigned<bool> is an error; - * mozilla::MakeUnsigned<void*> is an error. - */ -template<typename T> -struct MakeUnsigned - : EnableIf<IsIntegral<T>::value && - !IsSame<bool, typename RemoveCV<T>::Type>::value, - typename detail::MakeUnsigned<T> - >::Type -{}; - -/* 20.9.7.4 Array modifications [meta.trans.arr] */ - -/** - * RemoveExtent produces either the type of the elements of the array T, or T - * itself. - * - * mozilla::RemoveExtent<int>::Type is int; - * mozilla::RemoveExtent<const int[]>::Type is const int; - * mozilla::RemoveExtent<volatile int[5]>::Type is volatile int; - * mozilla::RemoveExtent<long[][17]>::Type is long[17]. - */ -template<typename T> -struct RemoveExtent -{ - typedef T Type; -}; - -template<typename T> -struct RemoveExtent<T[]> -{ - typedef T Type; -}; - -template<typename T, decltype(sizeof(1)) N> -struct RemoveExtent<T[N]> -{ - typedef T Type; -}; - -/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */ - -namespace detail { - -template<typename T, typename CVRemoved> -struct RemovePointerHelper -{ - typedef T Type; -}; - -template<typename T, typename Pointee> -struct RemovePointerHelper<T, Pointee*> -{ - typedef Pointee Type; -}; - -} // namespace detail - -/** - * Produces the pointed-to type if a pointer is provided, else returns the input - * type. Note that this does not dereference pointer-to-member pointers. - * - * struct S { bool m; void f(); }; - * mozilla::RemovePointer<int>::Type is int; - * mozilla::RemovePointer<int*>::Type is int; - * mozilla::RemovePointer<int* const>::Type is int; - * mozilla::RemovePointer<int* volatile>::Type is int; - * mozilla::RemovePointer<const long*>::Type is const long; - * mozilla::RemovePointer<void* const>::Type is void; - * mozilla::RemovePointer<void (S::*)()>::Type is void (S::*)(); - * mozilla::RemovePointer<void (*)()>::Type is void(); - * mozilla::RemovePointer<bool S::*>::Type is bool S::*. - */ -template<typename T> -struct RemovePointer - : detail::RemovePointerHelper<T, typename RemoveCV<T>::Type> -{}; - -/* 20.9.7.6 Other transformations [meta.trans.other] */ - -/** - * EnableIf is a struct containing a typedef of T if and only if B is true. - * - * mozilla::EnableIf<true, int>::Type is int; - * mozilla::EnableIf<false, int>::Type is a compile-time error. - * - * Use this template to implement SFINAE-style (Substitution Failure Is not An - * Error) requirements. For example, you might use it to impose a restriction - * on a template parameter: - * - * template<typename T> - * class PodVector // vector optimized to store POD (memcpy-able) types - * { - * EnableIf<IsPod<T>::value, T>::Type* vector; - * size_t length; - * ... - * }; - */ -template<bool B, typename T> -struct EnableIf -{}; - -template<typename T> -struct EnableIf<true, T> -{ - typedef T Type; -}; - -/** - * Conditional selects a class between two, depending on a given boolean value. - * - * mozilla::Conditional<true, A, B>::Type is A; - * mozilla::Conditional<false, A, B>::Type is B; - */ -template<bool Condition, typename A, typename B> -struct Conditional -{ - typedef A Type; -}; - -template<class A, class B> -struct Conditional<false, A, B> -{ - typedef B Type; -}; - -} /* namespace mozilla */ - -#endif /* mozilla_TypeTraits_h */ diff --git a/include/onlineupdate/mozilla/Types.h b/include/onlineupdate/mozilla/Types.h deleted file mode 100644 index 9d1e34b6d1d6..000000000000 --- a/include/onlineupdate/mozilla/Types.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* mfbt foundational types and macros. */ - -#ifndef mozilla_Types_h -#define mozilla_Types_h - -/* - * This header must be valid C and C++, includable by code embedding either - * SpiderMonkey or Gecko. - */ - -/* Expose all <stdint.h> types and size_t. */ -#include <stddef.h> -#include <stdint.h> - -/* Implement compiler and linker macros needed for APIs. */ - -/* - * MOZ_EXPORT is used to declare and define a symbol or type which is externally - * visible to users of the current library. It encapsulates various decorations - * needed to properly export the method's symbol. - * - * api.h: - * extern MOZ_EXPORT int MeaningOfLife(void); - * extern MOZ_EXPORT int LuggageCombination; - * - * api.c: - * int MeaningOfLife(void) { return 42; } - * int LuggageCombination = 12345; - * - * If you are merely sharing a method across files, just use plain |extern|. - * These macros are designed for use by library interfaces -- not for normal - * methods or data used cross-file. - */ -#if defined(_WIN32) -# define MOZ_EXPORT __declspec(dllexport) -#else /* Unix */ -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define MOZ_EXPORT __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define MOZ_EXPORT __global -# else -# define MOZ_EXPORT /* nothing */ -# endif -#endif - - -/* - * Whereas implementers use MOZ_EXPORT to declare and define library symbols, - * users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to access them. Most often the - * implementer of the library will expose an API macro which expands to either - * the export or import version of the macro, depending upon the compilation - * mode. - */ -#ifdef _WIN32 -# if defined(__MWERKS__) -# define MOZ_IMPORT_API /* nothing */ -# else -# define MOZ_IMPORT_API __declspec(dllimport) -# endif -#else -# define MOZ_IMPORT_API MOZ_EXPORT -#endif - -#if defined(_WIN32) && !defined(__MWERKS__) -# define MOZ_IMPORT_DATA __declspec(dllimport) -#else -# define MOZ_IMPORT_DATA MOZ_EXPORT -#endif - -/* - * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose - * export mfbt declarations when building mfbt, and they expose import mfbt - * declarations when using mfbt. - */ -#if defined(IMPL_MFBT) -# define MFBT_API MOZ_EXPORT -# define MFBT_DATA MOZ_EXPORT -#else - /* - * On linux mozglue is linked in the program and we link libxul.so with - * -z,defs. Normally that causes the linker to reject undefined references in - * libxul.so, but as a loophole it allows undefined references to weak - * symbols. We add the weak attribute to the import version of the MFBT API - * macros to exploit this. - */ -# if defined(MOZ_GLUE_IN_PROGRAM) && !defined(MOZILLA_XPCOMRT_API) -# define MFBT_API __attribute__((weak)) MOZ_IMPORT_API -# define MFBT_DATA __attribute__((weak)) MOZ_IMPORT_DATA -# else -# define MFBT_API MOZ_IMPORT_API -# define MFBT_DATA MOZ_IMPORT_DATA -# endif -#endif - -/* - * C symbols in C++ code must be declared immediately within |extern "C"| - * blocks. However, in C code, they need not be declared specially. This - * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C - * macros, so that the user need not know whether he is being used in C or C++ - * code. - * - * MOZ_BEGIN_EXTERN_C - * - * extern MOZ_EXPORT int MostRandomNumber(void); - * ...other declarations... - * - * MOZ_END_EXTERN_C - * - * This said, it is preferable to just use |extern "C"| in C++ header files for - * its greater clarity. - */ -#ifdef __cplusplus -# define MOZ_BEGIN_EXTERN_C extern "C" { -# define MOZ_END_EXTERN_C } -#else -# define MOZ_BEGIN_EXTERN_C -# define MOZ_END_EXTERN_C -#endif - -/* - * GCC's typeof is available when decltype is not. - */ -#if defined(__GNUC__) && defined(__cplusplus) && \ - !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L -# define decltype __typeof__ -#endif - -#endif /* mozilla_Types_h */ diff --git a/include/onlineupdate/mozilla/nsTraceRefcnt.h b/include/onlineupdate/mozilla/nsTraceRefcnt.h deleted file mode 100644 index c5b1de7e806a..000000000000 --- a/include/onlineupdate/mozilla/nsTraceRefcnt.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef nsTraceRefcnt_h___ -#define nsTraceRefcnt_h___ - -#include <stdio.h> // for FILE -#include "nscore.h" - -class nsTraceRefcnt -{ -public: - static void Shutdown(); - - enum StatisticsType { - ALL_STATS, - NEW_STATS - }; - - static nsresult DumpStatistics(StatisticsType aType = ALL_STATS, - FILE* aOut = 0); - - static void ResetStatistics(); - - static void DemangleSymbol(const char* aSymbol, char* aBuffer, int aBufLen); - - static void WalkTheStack(FILE* aStream); - - /** - * This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache - * the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being - * called frequently, it will be a few orders of magnitude faster than - * |WalkTheStack|. However, the cache uses a lot of memory, which can cause - * OOM crashes. Therefore, this should only be used for things like refcount - * logging which walk the stack extremely frequently. - */ - static void WalkTheStackCached(FILE* aStream); - - /** - * Tell nsTraceRefcnt whether refcounting, allocation, and destruction - * activity is legal. This is used to trigger assertions for any such - * activity that occurs because of static constructors or destructors. - */ - static void SetActivityIsLegal(bool aLegal); -}; - -#define NS_TRACE_REFCNT_CONTRACTID "@mozilla.org/xpcom/trace-refcnt;1" -#define NS_TRACE_REFCNT_CID \ -{ /* e3e7511e-a395-4924-94b1-d527861cded4 */ \ - 0xe3e7511e, \ - 0xa395, \ - 0x4924, \ - {0x94, 0xb1, 0xd5, 0x27, 0x86, 0x1c, 0xde, 0xd4} \ -} \ - -//////////////////////////////////////////////////////////////////////////////// -// And now for that utility that you've all been asking for... - -extern "C" void -NS_MeanAndStdDev(double aNumberOfValues, - double aSumOfValues, double aSumOfSquaredValues, - double* aMeanResult, double* aStdDevResult); - -//////////////////////////////////////////////////////////////////////////////// -#endif diff --git a/onlineupdate/Executable_mar.mk b/onlineupdate/Executable_mar.mk deleted file mode 100644 index 45a182323873..000000000000 --- a/onlineupdate/Executable_mar.mk +++ /dev/null @@ -1,51 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_Executable_Executable,mar)) - -$(eval $(call gb_Executable_set_include,mar,\ - -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ - -I$(SRCDIR)/onlineupdate/source/libmar/verify/ \ - -I$(SRCDIR)/onlineupdate/source/libmar/sign/ \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_Executable_use_static_libraries,mar,\ - libmar \ - libmarverify \ -)) - -ifeq ($(OS),WNT) -$(eval $(call gb_Executable_add_libs,mar,\ - ws2_32.lib \ - Crypt32.lib \ -)) -endif - -$(eval $(call gb_Executable_use_externals,mar,\ - nss3 \ -)) - -$(eval $(call gb_Executable_add_defs,mar,\ - -DMAR_NSS \ -)) - -$(eval $(call gb_Executable_add_defs,mar,\ - -DAPP_VERSION=\"$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\" \ -)) - -$(eval $(call gb_Executable_add_cobjects,mar,\ - onlineupdate/source/libmar/sign/nss_secutil \ - onlineupdate/source/libmar/sign/mar_sign \ - onlineupdate/source/libmar/tool/mar \ -)) - -$(eval $(call gb_Executable_set_warnings_not_errors,mar)) - -# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Executable_update_service.mk b/onlineupdate/Executable_update_service.mk deleted file mode 100644 index 2cbea4a63d71..000000000000 --- a/onlineupdate/Executable_update_service.mk +++ /dev/null @@ -1,62 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_Executable_Executable,update_service)) - -$(eval $(call gb_Executable_set_targettype_gui,update_service,YES)) - -$(eval $(call gb_Executable_set_include,update_service,\ - -I$(SRCDIR)/onlineupdate/inc \ - -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ - -I$(SRCDIR)/onlineupdate/source/libmar/verify/ \ - -I$(SRCDIR)/onlineupdate/source/libmar/sign/ \ - -I$(SRCDIR)/onlineupdate/source/update/common/ \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_Executable_use_static_libraries,update_service,\ - updatehelper \ - windows_process \ -)) - -$(eval $(call gb_Executable_add_libs,update_service,\ - ws2_32.lib \ - Crypt32.lib \ - shell32.lib \ - wintrust.lib \ - version.lib \ - wtsapi32.lib \ - userenv.lib \ - shlwapi.lib \ - ole32.lib \ - rpcrt4.lib \ - comctl32.lib \ - shlwapi.lib \ - kernel32.lib \ - advapi32.lib \ -)) - -$(eval $(call gb_Executable_add_ldflags,update_service,\ - /ENTRY:wmainCRTStartup \ -)) - -$(eval $(call gb_Executable_add_exception_objects,update_service,\ - onlineupdate/source/service/certificatecheck \ - onlineupdate/source/service/maintenanceservice \ - onlineupdate/source/service/registrycertificates \ - onlineupdate/source/service/servicebase \ - onlineupdate/source/service/serviceinstall \ - onlineupdate/source/service/workmonitor \ -)) - -$(eval $(call gb_Executable_add_cxxflags,update_service,-Zc:strictStrings-)) - -$(eval $(call gb_Executable_add_defs,update_service,-DUNICODE)) - -# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/Executable_updater.mk b/onlineupdate/Executable_updater.mk deleted file mode 100644 index 03df54a83e03..000000000000 --- a/onlineupdate/Executable_updater.mk +++ /dev/null @@ -1,95 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_Executable_Executable,updater)) - -$(eval $(call gb_Executable_set_include,updater,\ - -I$(SRCDIR)/onlineupdate/inc \ - -I$(SRCDIR)/onlineupdate/source/update/common \ - -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ - $$(INCLUDE) \ - $(if $(filter-out WNT,$(OS)),$$(GTK3_CFLAGS) ) \ -)) - -$(eval $(call gb_Executable_use_custom_headers,updater,onlineupdate/generated)) - -$(eval $(call gb_Executable_use_static_libraries,updater,\ - libmar \ - libmarverify \ - updatehelper \ - $(if $(filter WNT,$(OS)), \ - windows_process )\ -)) - -$(eval $(call gb_Executable_use_externals,updater,\ - bzip2 \ -)) - -ifeq ($(OS),WNT) -$(eval $(call gb_Executable_add_libs,updater,\ - Ws2_32.lib \ - Gdi32.lib \ - Comctl32.lib \ - Shell32.lib \ - Shlwapi.lib \ - Crypt32.lib \ -)) - -$(eval $(call gb_Executable_set_targettype_gui,updater,YES)) - -$(eval $(call gb_Executable_add_nativeres,updater,updaterres)) - -$(eval $(call gb_Executable_add_ldflags,updater,\ - /ENTRY:wmainCRTStartup \ -)) - -$(eval $(call gb_Executable_add_defs,updater,\ - -DVERIFY_MAR_SIGNATURE \ -)) - -else - -$(eval $(call gb_Executable_add_defs,updater,\ - -DVERIFY_MAR_SIGNATURE \ - -DNSS3 \ -)) - -$(eval $(call gb_Executable_use_externals,updater,\ - nss3 \ -)) - -$(eval $(call gb_Executable_add_libs,updater,\ - $(GTK3_LIBS) \ -)) - -endif - -$(eval $(call gb_Executable_add_exception_objects,updater,\ - onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator \ - onlineupdate/source/update/updater/archivereader \ - onlineupdate/source/update/updater/bspatch \ - onlineupdate/source/update/updater/progressui_gtk \ - onlineupdate/source/update/updater/updater \ - $(if $(filter WNT,$(OS)),\ - onlineupdate/source/update/updater/loaddlls \ - onlineupdate/source/update/updater/progressui_win \ - onlineupdate/source/update/updater/win_dirent )\ -)) - -$(eval $(call gb_Executable_set_warnings_not_errors,updater)) - -ifeq ($(OS),WNT) - -$(eval $(call gb_Executable_add_cxxflags,updater,-Zc:strictStrings-)) - -$(eval $(call gb_Executable_add_defs,updater,-DUNICODE)) - -endif - -# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/StaticLibrary_libmar.mk b/onlineupdate/StaticLibrary_libmar.mk deleted file mode 100644 index 37303d71e3b0..000000000000 --- a/onlineupdate/StaticLibrary_libmar.mk +++ /dev/null @@ -1,29 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_StaticLibrary_StaticLibrary,libmar)) - -$(eval $(call gb_StaticLibrary_set_include,libmar,\ - -I$(SRCDIR)/onlineupdate/source/libmar/src/ \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_StaticLibrary_add_cobjects,libmar,\ - onlineupdate/source/libmar/src/mar_create \ - onlineupdate/source/libmar/src/mar_extract \ - onlineupdate/source/libmar/src/mar_read \ -)) - -$(eval $(call gb_StaticLibrary_use_static_libraries,\ - libmarverify \ -)) - -$(eval $(call gb_StaticLibrary_set_warnings_not_errors,libmar)) - -# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/StaticLibrary_updatehelper.mk b/onlineupdate/StaticLibrary_updatehelper.mk deleted file mode 100644 index f040017ec9e3..000000000000 --- a/onlineupdate/StaticLibrary_updatehelper.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_StaticLibrary_StaticLibrary,updatehelper)) - -$(eval $(call gb_StaticLibrary_set_include,updatehelper,\ - -I$(SRCDIR)/onlineupdate/inc/ \ - -I$(SRCDIR)/onlineupdate/source/update/common \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_StaticLibrary_add_defs,updatehelper,\ - -DNSS3 \ - -DVERIFY_MAR_SIGNATURE \ -)) - -$(eval $(call gb_StaticLibrary_add_exception_objects,updatehelper,\ - onlineupdate/source/update/common/pathhash \ - onlineupdate/source/update/common/readstrings \ - onlineupdate/source/update/common/uachelper \ - onlineupdate/source/update/common/updatehelper \ - onlineupdate/source/update/common/updatelogging \ -)) - -$(eval $(call gb_StaticLibrary_set_warnings_not_errors,updatehelper)) - -ifeq ($(OS),WNT) -$(eval $(call gb_StaticLibrary_add_cxxflags,updatehelper,-Zc:strictStrings-)) -endif - -# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/WinResTarget_updater.mk b/onlineupdate/WinResTarget_updater.mk deleted file mode 100644 index f01b3ff425d1..000000000000 --- a/onlineupdate/WinResTarget_updater.mk +++ /dev/null @@ -1,15 +0,0 @@ -$(eval $(call gb_WinResTarget_WinResTarget,updaterres)) - -$(eval $(call gb_WinResTarget_set_include,updaterres,\ - $$(INCLUDE) \ - -I$(SRCDIR)/onlineupdate/source/update/common \ - -I$(SRCDIR)/onlineupdate/source/update/updater \ -)) - -$(eval $(call gb_WinResTarget_add_dependencies,updaterres, \ - onlineupdate/source/update/updater/updater.ico \ -)) - -$(eval $(call gb_WinResTarget_set_rcfile,updaterres, \ - onlineupdate/source/update/updater/updater \ -)) diff --git a/onlineupdate/astyle.options b/onlineupdate/astyle.options deleted file mode 100644 index fc8d9f69faff..000000000000 --- a/onlineupdate/astyle.options +++ /dev/null @@ -1,7 +0,0 @@ ---style=allman --s4 ---indent=spaces=4 ---attach-namespaces ---indent-switches ---indent-col1-comments ---pad-header diff --git a/onlineupdate/inc/Char16.h b/onlineupdate/inc/Char16.h deleted file mode 100644 index bc99179811c1..000000000000 --- a/onlineupdate/inc/Char16.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implements a UTF-16 character type. */ - -#ifndef mozilla_Char16_h -#define mozilla_Char16_h - -#ifdef __cplusplus - -/* - * C++11 introduces a char16_t type and support for UTF-16 string and character - * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t - * is a 16-bit code unit of a Unicode code point, not a "character". - */ - -#ifdef _WIN32 -# define MOZ_USE_CHAR16_WRAPPER -# include <cstdint> - /** - * Win32 API extensively uses wchar_t, which is represented by a separated - * builtin type than char16_t per spec. It's not the case for MSVC prior to - * MSVC 2015, but other compilers follow the spec. We want to mix wchar_t and - * char16_t on Windows builds. This class is supposed to make it easier. It - * stores char16_t const pointer, but provides implicit casts for wchar_t as - * well. On other platforms, we simply use - * |typedef const char16_t* char16ptr_t|. Here, we want to make the class as - * similar to this typedef, including providing some casts that are allowed - * by the typedef. - */ -class char16ptr_t -{ -private: - const char16_t* mPtr; - static_assert(sizeof(char16_t) == sizeof(wchar_t), - "char16_t and wchar_t sizes differ"); - -public: - char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {} - char16ptr_t(const wchar_t* aPtr) : - mPtr(reinterpret_cast<const char16_t*>(aPtr)) - {} - - /* Without this, nullptr assignment would be ambiguous. */ - constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {} - - operator const char16_t*() const - { - return mPtr; - } - operator const wchar_t*() const - { - return reinterpret_cast<const wchar_t*>(mPtr); - } - operator const void*() const - { - return mPtr; - } - operator bool() const - { - return mPtr != nullptr; - } - - /* Explicit cast operators to allow things like (char16_t*)str. */ - explicit operator char16_t*() const - { - return const_cast<char16_t*>(mPtr); - } - explicit operator wchar_t*() const - { - return const_cast<wchar_t*>(static_cast<const wchar_t*>(*this)); - } - explicit operator int() const - { - return reinterpret_cast<intptr_t>(mPtr); - } - explicit operator unsigned int() const - { - return reinterpret_cast<uintptr_t>(mPtr); - } - explicit operator long() const - { - return reinterpret_cast<intptr_t>(mPtr); - } - explicit operator unsigned long() const - { - return reinterpret_cast<uintptr_t>(mPtr); - } - explicit operator long long() const - { - return reinterpret_cast<intptr_t>(mPtr); - } - explicit operator unsigned long long() const - { - return reinterpret_cast<uintptr_t>(mPtr); - } - - /** - * Some Windows API calls accept BYTE* but require that data actually be - * WCHAR*. Supporting this requires explicit operators to support the - * requisite explicit casts. - */ - explicit operator const char*() const - { - return reinterpret_cast<const char*>(mPtr); - } - explicit operator const unsigned char*() const - { - return reinterpret_cast<const unsigned char*>(mPtr); - } - explicit operator unsigned char*() const - { - return - const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(mPtr)); - } - explicit operator void*() const - { - return const_cast<char16_t*>(mPtr); - } - - /* Some operators used on pointers. */ - char16_t operator[](size_t aIndex) const - { - return mPtr[aIndex]; - } - bool operator==(const char16ptr_t& aOther) const - { - return mPtr == aOther.mPtr; - } - bool operator==(decltype(nullptr)) const - { - return mPtr == nullptr; - } - bool operator!=(const char16ptr_t& aOther) const - { - return mPtr != aOther.mPtr; - } - bool operator!=(decltype(nullptr)) const - { - return mPtr != nullptr; - } - char16ptr_t operator+(int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned int aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - char16ptr_t operator+(unsigned long long aValue) const - { - return char16ptr_t(mPtr + aValue); - } - ptrdiff_t operator-(const char16ptr_t& aOther) const - { - return mPtr - aOther.mPtr; - } -}; - -inline decltype((char*)0-(char*)0) -operator-(const char16_t* aX, const char16ptr_t aY) -{ - return aX - static_cast<const char16_t*>(aY); -} - -#else - -typedef const char16_t* char16ptr_t; - -#endif - -static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); -static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?"); -static_assert(sizeof(u'A') == 2, "Is unicode char literal 16 bits?"); -static_assert(sizeof(u""[0]) == 2, "Is unicode string char 16 bits?"); - -#endif - -#endif /* mozilla_Char16_h */ diff --git a/onlineupdate/inc/bspatch.h b/onlineupdate/inc/bspatch.h deleted file mode 100644 index e9326262c243..000000000000 --- a/onlineupdate/inc/bspatch.h +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright 2003,2004 Colin Percival - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Changelog: - * 2005-04-26 - Define the header as a C structure, add a CRC32 checksum to - * the header, and make all the types 32-bit. - * --Benjamin Smedberg <benjamin@smedbergs.us> - */ - -#ifndef bspatch_h__ -#define bspatch_h__ - -#include <stdint.h> -#include <stdio.h> - -typedef struct MBSPatchHeader_ -{ - /* "MBDIFF10" */ - char tag[8]; - - /* Length of the file to be patched */ - uint32_t slen; - - /* CRC32 of the file to be patched */ - uint32_t scrc32; - - /* Length of the result file */ - uint32_t dlen; - - /* Length of the control block in bytes */ - uint32_t cblen; - - /* Length of the diff block in bytes */ - uint32_t difflen; - - /* Length of the extra block in bytes */ - uint32_t extralen; - - /* Control block (MBSPatchTriple[]) */ - /* Diff block (binary data) */ - /* Extra block (binary data) */ -} MBSPatchHeader; - -/** - * Read the header of a patch file into the MBSPatchHeader structure. - * - * @param fd Must have been opened for reading, and be at the beginning - * of the file. - */ -int MBS_ReadHeader(FILE* file, MBSPatchHeader* header); - -/** - * Apply a patch. This method does not validate the checksum of the original - * file: client code should validate the checksum before calling this method. - * - * @param patchfd Must have been processed by MBS_ReadHeader - * @param fbuffer The original file read into a memory buffer of length - * header->slen. - * @param filefd Must have been opened for writing. Should be truncated - * to header->dlen if it is an existing file. The offset - * should be at the beginning of the file. - */ -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 */ -} MBSPatchTriple; - -#endif // bspatch_h__ diff --git a/onlineupdate/inc/types.hxx b/onlineupdate/inc/types.hxx deleted file mode 100644 index 3e83a19c7d78..000000000000 --- a/onlineupdate/inc/types.hxx +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_ONLINEUPDATE_TYPES_HXX -#define INCLUDED_ONLINEUPDATE_TYPES_HXX - -#include <string> - -#if defined(_WIN32) -typedef std::wstring tstring; -typedef WCHAR NS_tchar; -#else -typedef std::string tstring; -typedef char NS_tchar; -#endif - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/onlineupdate/source/libmar/README b/onlineupdate/source/libmar/README deleted file mode 100644 index 422a289590fc..000000000000 --- a/onlineupdate/source/libmar/README +++ /dev/null @@ -1,6 +0,0 @@ -This directory contains code for a simple archive file format, which -is documented at http://wiki.mozilla.org/Software_Update:MAR - -The src directory builds a small static library used to create, read, and -extract an archive file. The tool directory builds a command line utility -around the library. diff --git a/onlineupdate/source/libmar/sign/Makefile.in b/onlineupdate/source/libmar/sign/Makefile.in deleted file mode 100644 index c5eaeb444915..000000000000 --- a/onlineupdate/source/libmar/sign/Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile just builds support for reading archives. -include $(topsrcdir)/config/rules.mk - -# The intermediate (.ii/.s) files for host and target can have the same name... -# disable parallel builds -.NOTPARALLEL: diff --git a/onlineupdate/source/libmar/sign/mar_sign.c b/onlineupdate/source/libmar/sign/mar_sign.c deleted file mode 100644 index 161cadc0d2c7..000000000000 --- a/onlineupdate/source/libmar/sign/mar_sign.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <onlineupdate/mar_private.h> -#include <onlineupdate/mar_cmdline.h> -#include <onlineupdate/mar.h> -#include "cryptox.h" -#ifndef _WIN32 -#include <unistd.h> -#endif - -#include "nss_secutil.h" -#include "base64.h" - -/** - * Initializes the NSS context. - * - * @param NSSConfigDir The config dir containing the private key to use - * @return 0 on success - * -1 on error -*/ -int -NSSInitCryptoContext(const char *NSSConfigDir) -{ - SECStatus status = NSS_Initialize(NSSConfigDir, - "", "", SECMOD_DB, NSS_INIT_READONLY); - if (SECSuccess != status) { - fprintf(stderr, "ERROR: Could not initialize NSS\n"); - return -1; - } - - return 0; -} - -/** - * Obtains a signing context. - * - * @param ctx A pointer to the signing context to fill - * @return 0 on success - * -1 on error -*/ -int -NSSSignBegin(const char *certName, - SGNContext **ctx, - SECKEYPrivateKey **privKey, - CERTCertificate **cert, - uint32_t *signatureLength) -{ - secuPWData pwdata = { PW_NONE, 0 }; - if (!certName || !ctx || !privKey || !cert || !signatureLength) { - fprintf(stderr, "ERROR: Invalid parameter passed to NSSSignBegin\n"); - return -1; - } - - /* Get the cert and embedded public key out of the database */ - *cert = PK11_FindCertFromNickname(certName, &pwdata); - if (!*cert) { - fprintf(stderr, "ERROR: Could not find cert from nickname\n"); - return -1; - } - - /* Get the private key out of the database */ - *privKey = PK11_FindKeyByAnyCert(*cert, &pwdata); - if (!*privKey) { - fprintf(stderr, "ERROR: Could not find private key\n"); - return -1; - } - - *signatureLength = PK11_SignatureLen(*privKey); - - if (*signatureLength > BLOCKSIZE) { - fprintf(stderr, - "ERROR: Program must be compiled with a larger block size" - " to support signing with signatures this large: %u.\n", - *signatureLength); - return -1; - } - - /* Check that the key length is large enough for our requirements */ - if (*signatureLength < XP_MIN_SIGNATURE_LEN_IN_BYTES) { - fprintf(stderr, "ERROR: Key length must be >= %d bytes\n", - XP_MIN_SIGNATURE_LEN_IN_BYTES); - return -1; - } - - *ctx = SGN_NewContext (SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, *privKey); - if (!*ctx) { - fprintf(stderr, "ERROR: Could not create signature context\n"); - return -1; - } - - if (SGN_Begin(*ctx) != SECSuccess) { - fprintf(stderr, "ERROR: Could not begin signature\n"); - return -1; - } - - return 0; -} - -/** - * Writes the passed buffer to the file fp and updates the signature contexts. - * - * @param fpDest The file pointer to write to. - * @param buffer The buffer to write. - * @param size The size of the buffer to write. - * @param ctxs Pointer to the first element in an array of signature - * contexts to update. - * @param ctxCount The number of signature contexts pointed to by ctxs - * @param err The name of what is being written to in case of error. - * @return 0 on success - * -2 on write error - * -3 on signature update error -*/ -int -WriteAndUpdateSignatures(FILE *fpDest, void *buffer, - uint32_t size, SGNContext **ctxs, - uint32_t ctxCount, - const char *err) -{ - uint32_t k; - if (!size) { - return 0; - } - - if (fwrite(buffer, size, 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write %s\n", err); - return -2; - } - - for (k = 0; k < ctxCount; ++k) { - if (SGN_Update(ctxs[k], buffer, size) != SECSuccess) { - fprintf(stderr, "ERROR: Could not update signature context for %s\n", err); - return -3; - } - } - return 0; -} - -/** - * Adjusts each entry's content offset in the passed in index by the - * specified amount. - * - * @param indexBuf A buffer containing the MAR index - * @param indexLength The length of the MAR index - * @param offsetAmount The amount to adjust each index entry by -*/ -void -AdjustIndexContentOffsets(char *indexBuf, uint32_t indexLength, uint32_t offsetAmount) -{ - char *indexBufLoc = indexBuf; - - /* Consume the index and adjust each index by the specified amount */ - while (indexBufLoc != (indexBuf + indexLength)) { - /* Adjust the offset */ - uint32_t* offsetToContent = (uint32_t *)indexBufLoc; - *offsetToContent = ntohl(*offsetToContent); - *offsetToContent += offsetAmount; - *offsetToContent = htonl(*offsetToContent); - /* Skip past the offset, length, and flags */ - indexBufLoc += 3 * sizeof(uint32_t); - indexBufLoc += strlen(indexBufLoc) + 1; - } -} - -/** - * Reads from fpSrc, writes it to fpDest, and updates the signature contexts. - * - * @param fpSrc The file pointer to read from. - * @param fpDest The file pointer to write to. - * @param buffer The buffer to write. - * @param size The size of the buffer to write. - * @param ctxs Pointer to the first element in an array of signature - * contexts to update. - * @param ctxCount The number of signature contexts pointed to by ctxs - * @param err The name of what is being written to in case of error. - * @return 0 on success - * -1 on read error - * -2 on write error - * -3 on signature update error -*/ -int -ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer, - uint32_t size, SGNContext **ctxs, - uint32_t ctxCount, - const char *err) -{ - if (!size) { - return 0; - } - - if (fread(buffer, size, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read %s\n", err); - return -1; - } - - return WriteAndUpdateSignatures(fpDest, buffer, size, ctxs, ctxCount, err); -} - - -/** - * Reads from fpSrc, writes it to fpDest. - * - * @param fpSrc The file pointer to read from. - * @param fpDest The file pointer to write to. - * @param buffer The buffer to write. - * @param size The size of the buffer to write. - * @param err The name of what is being written to in case of error. - * @return 0 on success - * -1 on read error - * -2 on write error -*/ -int -ReadAndWrite(FILE *fpSrc, FILE *fpDest, void *buffer, - uint32_t size, const char *err) -{ - if (!size) { - return 0; - } - - if (fread(buffer, size, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read %s\n", err); - return -1; - } - - if (fwrite(buffer, size, 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write %s\n", err); - return -2; - } - - return 0; -} - -/** - * Writes out a copy of the MAR at src but with the signature block stripped. - * - * @param src The path of the source MAR file - * @param dest The path of the MAR file to write out that - has no signature block - * @return 0 on success - * -1 on error -*/ -int -strip_signature_block(const char *src, const char * dest) -{ - uint32_t offsetToIndex, dstOffsetToIndex, indexLength, - numSignatures = 0, leftOver; - int32_t stripAmount = 0; - int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR, numBytesToCopy, - numChunks, i; - FILE *fpSrc = NULL, *fpDest = NULL; - int rv = -1, hasSignatureBlock; - char buf[BLOCKSIZE]; - char *indexBuf = NULL; - - if (!src || !dest) { - fprintf(stderr, "ERROR: Invalid parameter passed in.\n"); - return -1; - } - - fpSrc = fopen(src, "rb"); - if (!fpSrc) { - fprintf(stderr, "ERROR: could not open source file: %s\n", src); - goto failure; - } - - fpDest = fopen(dest, "wb"); - if (!fpDest) { - fprintf(stderr, "ERROR: could not create target file: %s\n", dest); - goto failure; - } - - /* Determine if the source MAR file has the new fields for signing or not */ - if (get_mar_file_info(src, &hasSignatureBlock, NULL, NULL, NULL, NULL)) { - fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n"); - goto failure; - } - - /* MAR ID */ - if (ReadAndWrite(fpSrc, fpDest, buf, MAR_ID_SIZE, "MAR ID")) { - goto failure; - } - - /* Offset to index */ - if (fread(&offsetToIndex, sizeof(offsetToIndex), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read offset\n"); - goto failure; - } - offsetToIndex = ntohl(offsetToIndex); - - /* Get the real size of the MAR */ - oldPos = ftello(fpSrc); - if (fseeko(fpSrc, 0, SEEK_END)) { - fprintf(stderr, "ERROR: Could not seek to end of file.\n"); - goto failure; - } - realSizeOfSrcMAR = ftello(fpSrc); - if (fseeko(fpSrc, oldPos, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek back to current location.\n"); - goto failure; - } - - if (hasSignatureBlock) { - /* Get the MAR length and adjust its size */ - if (fread(&sizeOfEntireMAR, - sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could read mar size\n"); - goto failure; - } - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - if (sizeOfEntireMAR != realSizeOfSrcMAR) { - fprintf(stderr, "ERROR: Source MAR is not of the right size\n"); - goto failure; - } - - /* Get the num signatures in the source file so we know what to strip */ - if (fread(&numSignatures, sizeof(numSignatures), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could read num signatures\n"); - goto failure; - } - numSignatures = ntohl(numSignatures); - - for (i = 0; i < numSignatures; i++) { - uint32_t signatureLen; - - /* Skip past the signature algorithm ID */ - if (fseeko(fpSrc, sizeof(uint32_t), SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not skip past signature algorithm ID\n"); - } - - /* Read in the length of the signature so we know how far to skip */ - if (fread(&signatureLen, sizeof(uint32_t), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read signatures length.\n"); - return CryptoX_Error; - } - signatureLen = ntohl(signatureLen); - - /* Skip past the signature */ - if (fseeko(fpSrc, signatureLen, SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not skip past signature algorithm ID\n"); - } - - stripAmount += sizeof(uint32_t) + sizeof(uint32_t) + signatureLen; - } - - } else { - sizeOfEntireMAR = realSizeOfSrcMAR; - numSignatures = 0; - } - - if (((int64_t)offsetToIndex) > sizeOfEntireMAR) { - fprintf(stderr, "ERROR: Offset to index is larger than the file size.\n"); - goto failure; - } - - dstOffsetToIndex = offsetToIndex; - if (!hasSignatureBlock) { - dstOffsetToIndex += sizeof(sizeOfEntireMAR) + sizeof(numSignatures); - } - dstOffsetToIndex -= stripAmount; - - /* Write out the index offset */ - dstOffsetToIndex = htonl(dstOffsetToIndex); - if (fwrite(&dstOffsetToIndex, sizeof(dstOffsetToIndex), 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write offset to index\n"); - goto failure; - } - dstOffsetToIndex = ntohl(dstOffsetToIndex); - - /* Write out the new MAR file size */ - if (!hasSignatureBlock) { - sizeOfEntireMAR += sizeof(sizeOfEntireMAR) + sizeof(numSignatures); - } - sizeOfEntireMAR -= stripAmount; - - /* Write out the MAR size */ - sizeOfEntireMAR = HOST_TO_NETWORK64(sizeOfEntireMAR); - if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write size of MAR\n"); - goto failure; - } - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - - /* Write out the number of signatures, which is 0 */ - numSignatures = 0; - if (fwrite(&numSignatures, sizeof(numSignatures), 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write out num signatures\n"); - goto failure; - } - - /* Write out the rest of the MAR excluding the index header and index - offsetToIndex unfortunately has to remain 32-bit because for backwards - compatibility with the old MAR file format. */ - if (ftello(fpSrc) > ((int64_t)offsetToIndex)) { - fprintf(stderr, "ERROR: Index offset is too small.\n"); - goto failure; - } - numBytesToCopy = ((int64_t)offsetToIndex) - ftello(fpSrc); - numChunks = numBytesToCopy / BLOCKSIZE; - leftOver = numBytesToCopy % BLOCKSIZE; - - /* Read each file and write it to the MAR file */ - for (i = 0; i < numChunks; ++i) { - if (ReadAndWrite(fpSrc, fpDest, buf, BLOCKSIZE, "content block")) { - goto failure; - } - } - - /* Write out the left over */ - if (ReadAndWrite(fpSrc, fpDest, buf, - leftOver, "left over content block")) { - goto failure; - } - - /* Length of the index */ - if (ReadAndWrite(fpSrc, fpDest, &indexLength, - sizeof(indexLength), "index length")) { - goto failure; - } - indexLength = ntohl(indexLength); - - /* Consume the index and adjust each index by the difference */ - indexBuf = malloc(indexLength); - if (fread(indexBuf, indexLength, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read index\n"); - goto failure; - } - - /* Adjust each entry in the index */ - if (hasSignatureBlock) { - AdjustIndexContentOffsets(indexBuf, indexLength, -stripAmount); - } else { - AdjustIndexContentOffsets(indexBuf, indexLength, - sizeof(sizeOfEntireMAR) + - sizeof(numSignatures) - - stripAmount); - } - - if (fwrite(indexBuf, indexLength, 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write index\n"); - goto failure; - } - - rv = 0; -failure: - if (fpSrc) { - fclose(fpSrc); - } - - if (fpDest) { - fclose(fpDest); - } - - if (rv) { - remove(dest); - } - - if (indexBuf) { - free(indexBuf); - } - - if (rv) { - remove(dest); - } - return rv; -} - -/** - * Extracts a signature from a MAR file, base64 encodes it, and writes it out - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to extract - * @param dest The path of file to write the signature to - * @return 0 on success - * -1 on error -*/ -int -extract_signature(const char *src, uint32_t sigIndex, const char * dest) -{ - FILE *fpSrc = NULL, *fpDest = NULL; - uint32_t i; - uint32_t signatureCount; - uint32_t signatureLen = 0; - uint8_t *extractedSignature = NULL; - char *base64Encoded = NULL; - int rv = -1; - if (!src || !dest) { - fprintf(stderr, "ERROR: Invalid parameter passed in.\n"); - goto failure; - } - - fpSrc = fopen(src, "rb"); - if (!fpSrc) { - fprintf(stderr, "ERROR: could not open source file: %s\n", src); - goto failure; - } - - fpDest = fopen(dest, "wb"); - if (!fpDest) { - fprintf(stderr, "ERROR: could not create target file: %s\n", dest); - goto failure; - } - - /* Skip to the start of the signature block */ - if (fseeko(fpSrc, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) { - fprintf(stderr, "ERROR: could not seek to signature block\n"); - goto failure; - } - - /* Get the number of signatures */ - if (fread(&signatureCount, sizeof(signatureCount), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: could not read signature count\n"); - goto failure; - } - signatureCount = ntohl(signatureCount); - if (sigIndex >= signatureCount) { - fprintf(stderr, "ERROR: Signature index was out of range\n"); - goto failure; - } - - /* Skip to the correct signature */ - for (i = 0; i <= sigIndex; i++) { - /* Avoid leaking while skipping signatures */ - free(extractedSignature); - - /* skip past the signature algorithm ID */ - if (fseeko(fpSrc, sizeof(uint32_t), SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not seek past sig algorithm ID.\n"); - goto failure; - } - - /* Get the signature length */ - if (fread(&signatureLen, sizeof(signatureLen), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: could not read signature length\n"); - goto failure; - } - signatureLen = ntohl(signatureLen); - - /* Get the signature */ - extractedSignature = malloc(signatureLen); - if (fread(extractedSignature, signatureLen, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: could not read signature\n"); - goto failure; - } - } - - base64Encoded = BTOA_DataToAscii(extractedSignature, signatureLen); - if (!base64Encoded) { - fprintf(stderr, "ERROR: could not obtain base64 encoded data\n"); - goto failure; - } - - if (fwrite(base64Encoded, strlen(base64Encoded), 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write base64 encoded string\n"); - goto failure; - } - - rv = 0; -failure: - if (base64Encoded) { - PORT_Free(base64Encoded); - } - - if (extractedSignature) { - free(extractedSignature); - } - - if (fpSrc) { - fclose(fpSrc); - } - - if (fpDest) { - fclose(fpDest); - } - - if (rv) { - remove(dest); - } - - return rv; -} - -/** - * Imports a base64 encoded signature into a MAR file - * - * @param src The path of the source MAR file - * @param sigIndex The index of the signature to import - * @param base64SigFile A file which contains the signature to import - * @param dest The path of the destination MAR file with replaced signature - * @return 0 on success - * -1 on error -*/ -int -import_signature(const char *src, uint32_t sigIndex, - const char *base64SigFile, const char *dest) -{ - int rv = -1; - FILE *fpSrc = NULL; - FILE *fpDest = NULL; - FILE *fpSigFile = NULL; - uint32_t i; - uint32_t signatureCount, signatureLen, signatureAlgorithmID, - numChunks, leftOver; - char buf[BLOCKSIZE]; - uint64_t sizeOfSrcMAR, sizeOfBase64EncodedFile; - char *passedInSignatureB64 = NULL; - uint8_t *passedInSignatureRaw = NULL; - uint8_t *extractedMARSignature = NULL; - unsigned int passedInSignatureLenRaw; - - if (!src || !dest) { - fprintf(stderr, "ERROR: Invalid parameter passed in.\n"); - goto failure; - } - - fpSrc = fopen(src, "rb"); - if (!fpSrc) { - fprintf(stderr, "ERROR: could not open source file: %s\n", src); - goto failure; - } - - fpDest = fopen(dest, "wb"); - if (!fpDest) { - fprintf(stderr, "ERROR: could not open dest file: %s\n", dest); - goto failure; - } - - fpSigFile = fopen(base64SigFile , "rb"); - if (!fpSigFile) { - fprintf(stderr, "ERROR: could not open sig file: %s\n", base64SigFile); - goto failure; - } - - /* Get the src file size */ - if (fseeko(fpSrc, 0, SEEK_END)) { - fprintf(stderr, "ERROR: Could not seek to end of src file.\n"); - goto failure; - } - sizeOfSrcMAR = ftello(fpSrc); - if (fseeko(fpSrc, 0, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek to start of src file.\n"); - goto failure; - } - - /* Get the sig file size */ - if (fseeko(fpSigFile, 0, SEEK_END)) { - fprintf(stderr, "ERROR: Could not seek to end of sig file.\n"); - goto failure; - } - sizeOfBase64EncodedFile= ftello(fpSigFile); - if (fseeko(fpSigFile, 0, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek to start of sig file.\n"); - goto failure; - } - - /* Read in the base64 encoded signature to import */ - passedInSignatureB64 = malloc(sizeOfBase64EncodedFile + 1); - passedInSignatureB64[sizeOfBase64EncodedFile] = '\0'; - if (fread(passedInSignatureB64, sizeOfBase64EncodedFile, 1, fpSigFile) != 1) { - fprintf(stderr, "ERROR: Could read b64 sig file.\n"); - goto failure; - } - - /* Decode the base64 encoded data */ - passedInSignatureRaw = ATOB_AsciiToData(passedInSignatureB64, &passedInSignatureLenRaw); - if (!passedInSignatureRaw) { - fprintf(stderr, "ERROR: could not obtain base64 decoded data\n"); - goto failure; - } - - /* Read everything up until the signature block offset and write it out */ - if (ReadAndWrite(fpSrc, fpDest, buf, - SIGNATURE_BLOCK_OFFSET, "signature block offset")) { - goto failure; - } - - /* Get the number of signatures */ - if (ReadAndWrite(fpSrc, fpDest, &signatureCount, - sizeof(signatureCount), "signature count")) { - goto failure; - } - signatureCount = ntohl(signatureCount); - if (signatureCount > MAX_SIGNATURES) { - fprintf(stderr, "ERROR: Signature count was out of range\n"); - goto failure; - } - - if (sigIndex >= signatureCount) { - fprintf(stderr, "ERROR: Signature index was out of range\n"); - goto failure; - } - - /* Read and write the whole signature block, but if we reach the - signature offset, then we should replace it with the specified - base64 decoded signature */ - for (i = 0; i < signatureCount; i++) { - /* Read/Write the signature algorithm ID */ - if (ReadAndWrite(fpSrc, fpDest, - &signatureAlgorithmID, - sizeof(signatureAlgorithmID), "sig algorithm ID")) { - goto failure; - } - - /* Read/Write the signature length */ - if (ReadAndWrite(fpSrc, fpDest, - &signatureLen, sizeof(signatureLen), "sig length")) { - goto failure; - } - signatureLen = ntohl(signatureLen); - - /* Get the signature */ - if (extractedMARSignature) { - free(extractedMARSignature); - } - extractedMARSignature = malloc(signatureLen); - - if (sigIndex == i) { - if (passedInSignatureLenRaw != signatureLen) { - fprintf(stderr, "ERROR: Signature length must be the same\n"); - goto failure; - } - - if (fread(extractedMARSignature, signatureLen, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read signature\n"); - goto failure; - } - - if (fwrite(passedInSignatureRaw, passedInSignatureLenRaw, - 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write signature\n"); - goto failure; - } - } else { - if (ReadAndWrite(fpSrc, fpDest, - extractedMARSignature, signatureLen, "signature")) { - goto failure; - } - } - } - - /* We replaced the signature so let's just skip past the rest o the - file. */ - numChunks = (sizeOfSrcMAR - ftello(fpSrc)) / BLOCKSIZE; - leftOver = (sizeOfSrcMAR - ftello(fpSrc)) % BLOCKSIZE; - - /* Read each file and write it to the MAR file */ - for (i = 0; i < numChunks; ++i) { - if (ReadAndWrite(fpSrc, fpDest, buf, BLOCKSIZE, "content block")) { - goto failure; - } - } - - if (ReadAndWrite(fpSrc, fpDest, buf, leftOver, "left over content block")) { - goto failure; - } - - rv = 0; - -failure: - - if (fpSrc) { - fclose(fpSrc); - } - - if (fpDest) { - fclose(fpDest); - } - - if (fpSigFile) { - fclose(fpSigFile); - } - - if (rv) { - remove(dest); - } - - if (extractedMARSignature) { - free(extractedMARSignature); - } - - if (passedInSignatureB64) { - free(passedInSignatureB64); - } - - if (passedInSignatureRaw) { - PORT_Free(passedInSignatureRaw); - } - - return rv; -} - -/** - * Writes out a copy of the MAR at src but with embedded signatures. - * The passed in MAR file must not already be signed or an error will - * be returned. - * - * @param NSSConfigDir The NSS directory containing the private key for signing - * @param certNames The nicknames of the certificate to use for signing - * @param certCount The number of certificate names contained in certNames. - * One signature will be produced for each certificate. - * @param src The path of the source MAR file to sign - * @param dest The path of the MAR file to write out that is signed - * @return 0 on success - * -1 on error -*/ -int -mar_repackage_and_sign(const char *NSSConfigDir, - const char * const *certNames, - uint32_t certCount, - const char *src, - const char *dest) -{ - uint32_t offsetToIndex, dstOffsetToIndex, indexLength, - numSignatures = 0, leftOver, - signatureAlgorithmID, signatureSectionLength = 0; - uint32_t signatureLengths[MAX_SIGNATURES]; - int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR, - signaturePlaceholderOffset, numBytesToCopy, - numChunks, i; - FILE *fpSrc = NULL, *fpDest = NULL; - int rv = -1, hasSignatureBlock; - SGNContext *ctxs[MAX_SIGNATURES]; - SECItem secItems[MAX_SIGNATURES]; - char buf[BLOCKSIZE]; - SECKEYPrivateKey *privKeys[MAX_SIGNATURES]; - CERTCertificate *certs[MAX_SIGNATURES]; - char *indexBuf = NULL; - uint32_t k; - - memset(signatureLengths, 0, sizeof(signatureLengths)); - memset(ctxs, 0, sizeof(ctxs)); - memset(secItems, 0, sizeof(secItems)); - memset(privKeys, 0, sizeof(privKeys)); - memset(certs, 0, sizeof(certs)); - - if (!NSSConfigDir || !certNames || certCount == 0 || !src || !dest) { - fprintf(stderr, "ERROR: Invalid parameter passed in.\n"); - return -1; - } - - if (NSSInitCryptoContext(NSSConfigDir)) { - fprintf(stderr, "ERROR: Could not init config dir: %s\n", NSSConfigDir); - goto failure; - } - - PK11_SetPasswordFunc(SECU_GetModulePassword); - - fpSrc = fopen(src, "rb"); - if (!fpSrc) { - fprintf(stderr, "ERROR: could not open source file: %s\n", src); - goto failure; - } - - fpDest = fopen(dest, "wb"); - if (!fpDest) { - fprintf(stderr, "ERROR: could not create target file: %s\n", dest); - goto failure; - } - - /* Determine if the source MAR file has the new fields for signing or not */ - if (get_mar_file_info(src, &hasSignatureBlock, NULL, NULL, NULL, NULL)) { - fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n"); - goto failure; - } - - for (k = 0; k < certCount; k++) { - if (NSSSignBegin(certNames[k], &ctxs[k], &privKeys[k], - &certs[k], &signatureLengths[k])) { - fprintf(stderr, "ERROR: NSSSignBegin failed\n"); - goto failure; - } - } - - /* MAR ID */ - if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, - buf, MAR_ID_SIZE, - ctxs, certCount, "MAR ID")) { - goto failure; - } - - /* Offset to index */ - if (fread(&offsetToIndex, sizeof(offsetToIndex), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read offset\n"); - goto failure; - } - offsetToIndex = ntohl(offsetToIndex); - - /* Get the real size of the MAR */ - oldPos = ftello(fpSrc); - if (fseeko(fpSrc, 0, SEEK_END)) { - fprintf(stderr, "ERROR: Could not seek to end of file.\n"); - goto failure; - } - realSizeOfSrcMAR = ftello(fpSrc); - if (fseeko(fpSrc, oldPos, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek back to current location.\n"); - goto failure; - } - - if (hasSignatureBlock) { - /* Get the MAR length and adjust its size */ - if (fread(&sizeOfEntireMAR, - sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could read mar size\n"); - goto failure; - } - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - if (sizeOfEntireMAR != realSizeOfSrcMAR) { - fprintf(stderr, "ERROR: Source MAR is not of the right size\n"); - goto failure; - } - - /* Get the num signatures in the source file */ - if (fread(&numSignatures, sizeof(numSignatures), 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could read num signatures\n"); - goto failure; - } - numSignatures = ntohl(numSignatures); - - /* We do not support resigning, if you have multiple signatures, - you must add them all at the same time. */ - if (numSignatures) { - fprintf(stderr, "ERROR: MAR is already signed\n"); - goto failure; - } - } else { - sizeOfEntireMAR = realSizeOfSrcMAR; - } - - if (((int64_t)offsetToIndex) > sizeOfEntireMAR) { - fprintf(stderr, "ERROR: Offset to index is larger than the file size.\n"); - goto failure; - } - - /* Calculate the total signature block length */ - for (k = 0; k < certCount; k++) { - signatureSectionLength += sizeof(signatureAlgorithmID) + - sizeof(signatureLengths[k]) + - signatureLengths[k]; - } - dstOffsetToIndex = offsetToIndex; - if (!hasSignatureBlock) { - dstOffsetToIndex += sizeof(sizeOfEntireMAR) + sizeof(numSignatures); - } - dstOffsetToIndex += signatureSectionLength; - - /* Write out the index offset */ - dstOffsetToIndex = htonl(dstOffsetToIndex); - if (WriteAndUpdateSignatures(fpDest, &dstOffsetToIndex, - sizeof(dstOffsetToIndex), ctxs, certCount, - "index offset")) { - goto failure; - } - dstOffsetToIndex = ntohl(dstOffsetToIndex); - - /* Write out the new MAR file size */ - sizeOfEntireMAR += signatureSectionLength; - if (!hasSignatureBlock) { - sizeOfEntireMAR += sizeof(sizeOfEntireMAR) + sizeof(numSignatures); - } - - /* Write out the MAR size */ - sizeOfEntireMAR = HOST_TO_NETWORK64(sizeOfEntireMAR); - if (WriteAndUpdateSignatures(fpDest, &sizeOfEntireMAR, - sizeof(sizeOfEntireMAR), ctxs, certCount, - "size of MAR")) { - goto failure; - } - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - - /* Write out the number of signatures */ - numSignatures = certCount; - numSignatures = htonl(numSignatures); - if (WriteAndUpdateSignatures(fpDest, &numSignatures, - sizeof(numSignatures), ctxs, certCount, - "num signatures")) { - goto failure; - } - numSignatures = ntohl(numSignatures); - - signaturePlaceholderOffset = ftello(fpDest); - - for (k = 0; k < certCount; k++) { - /* Write out the signature algorithm ID, Only an ID of 1 is supported */ - signatureAlgorithmID = htonl(1); - if (WriteAndUpdateSignatures(fpDest, &signatureAlgorithmID, - sizeof(signatureAlgorithmID), - ctxs, certCount, "num signatures")) { - goto failure; - } - signatureAlgorithmID = ntohl(signatureAlgorithmID); - - /* Write out the signature length */ - signatureLengths[k] = htonl(signatureLengths[k]); - if (WriteAndUpdateSignatures(fpDest, &signatureLengths[k], - sizeof(signatureLengths[k]), - ctxs, certCount, "signature length")) { - goto failure; - } - signatureLengths[k] = ntohl(signatureLengths[k]); - - /* Write out a placeholder for the signature, we'll come back to this later - *** THIS IS NOT SIGNED because it is a placeholder that will be replaced - below, plus it is going to be the signature itself. *** */ - memset(buf, 0, sizeof(buf)); - if (fwrite(buf, signatureLengths[k], 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write signature length\n"); - goto failure; - } - } - - /* Write out the rest of the MAR excluding the index header and index - offsetToIndex unfortunately has to remain 32-bit because for backwards - compatibility with the old MAR file format. */ - if (ftello(fpSrc) > ((int64_t)offsetToIndex)) { - fprintf(stderr, "ERROR: Index offset is too small.\n"); - goto failure; - } - numBytesToCopy = ((int64_t)offsetToIndex) - ftello(fpSrc); - numChunks = numBytesToCopy / BLOCKSIZE; - leftOver = numBytesToCopy % BLOCKSIZE; - - /* Read each file and write it to the MAR file */ - for (i = 0; i < numChunks; ++i) { - if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf, - BLOCKSIZE, ctxs, certCount, - "content block")) { - goto failure; - } - } - - /* Write out the left over */ - if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf, - leftOver, ctxs, certCount, - "left over content block")) { - goto failure; - } - - /* Length of the index */ - if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, &indexLength, - sizeof(indexLength), ctxs, certCount, - "index length")) { - goto failure; - } - indexLength = ntohl(indexLength); - - /* Consume the index and adjust each index by signatureSectionLength */ - indexBuf = malloc(indexLength); - if (fread(indexBuf, indexLength, 1, fpSrc) != 1) { - fprintf(stderr, "ERROR: Could not read index\n"); - goto failure; - } - - /* Adjust each entry in the index */ - if (hasSignatureBlock) { - AdjustIndexContentOffsets(indexBuf, indexLength, signatureSectionLength); - } else { - AdjustIndexContentOffsets(indexBuf, indexLength, - sizeof(sizeOfEntireMAR) + - sizeof(numSignatures) + - signatureSectionLength); - } - - if (WriteAndUpdateSignatures(fpDest, indexBuf, - indexLength, ctxs, certCount, "index")) { - goto failure; - } - - /* Ensure that we don't sign a file that is too large to be accepted by - the verification function. */ - if (ftello(fpDest) > MAX_SIZE_OF_MAR_FILE) { - goto failure; - } - - for (k = 0; k < certCount; k++) { - /* Get the signature */ - if (SGN_End(ctxs[k], &secItems[k]) != SECSuccess) { - fprintf(stderr, "ERROR: Could not end signature context\n"); - goto failure; - } - if (signatureLengths[k] != secItems[k].len) { - fprintf(stderr, "ERROR: Signature is not the expected length\n"); - goto failure; - } - } - - /* Get back to the location of the signature placeholder */ - if (fseeko(fpDest, signaturePlaceholderOffset, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek to signature offset\n"); - goto failure; - } - - for (k = 0; k < certCount; k++) { - /* Skip to the position of the next signature */ - if (fseeko(fpDest, sizeof(signatureAlgorithmID) + - sizeof(signatureLengths[k]), SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not seek to signature offset\n"); - goto failure; - } - - /* Write out the calculated signature. - *** THIS IS NOT SIGNED because it is the signature itself. *** */ - if (fwrite(secItems[k].data, secItems[k].len, 1, fpDest) != 1) { - fprintf(stderr, "ERROR: Could not write signature\n"); - goto failure; - } - } - - rv = 0; -failure: - if (fpSrc) { - fclose(fpSrc); - } - - if (fpDest) { - fclose(fpDest); - } - - if (rv) { - remove(dest); - } - - if (indexBuf) { - free(indexBuf); - } - - /* Cleanup */ - for (k = 0; k < certCount; k++) { - if (ctxs[k]) { - SGN_DestroyContext(ctxs[k], PR_TRUE); - } - - if (certs[k]) { - CERT_DestroyCertificate(certs[k]); - } - - if (privKeys[k]) { - SECKEY_DestroyPrivateKey(privKeys[k]); - } - - SECITEM_FreeItem(&secItems[k], PR_FALSE); - } - - if (rv) { - remove(dest); - } - - return rv; -} diff --git a/onlineupdate/source/libmar/sign/nss_secutil.c b/onlineupdate/source/libmar/sign/nss_secutil.c deleted file mode 100644 index 875c14309ec0..000000000000 --- a/onlineupdate/source/libmar/sign/nss_secutil.c +++ /dev/null @@ -1,238 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* With the exception of GetPasswordString, this file was - copied from NSS's cmd/lib/secutil.c hg revision 8f011395145e */ - -#include "nss_secutil.h" - -#include "prprf.h" -#ifdef _WIN32 -#include <io.h> -#else -#include <unistd.h> -#endif - -static char consoleName[] = { -#ifdef UNIX - "/dev/tty" -#else - "CON:" -#endif -}; - -#if defined(_WINDOWS) -static char * quiet_fgets (char *buf, int length, FILE *input) -{ - char *end = buf; - - /* fflush (input); */ - memset (buf, 0, length); - - if (!isatty(fileno(input))) { - return fgets(buf,length,input); - } - - while (1) - { - int c; -#if defined (_WIN32_WCE) - c = getchar(); /* gets a character from stdin */ -#else - c = getch(); /* getch gets a character from the console */ -#endif - if (c == '\b') - { - if (end > buf) - end--; - } - - else if (--length > 0) - *end++ = c; - - if (!c || c == '\n' || c == '\r') - break; - } - - return buf; -} -#endif - -char * -GetPasswordString(void *arg, char *prompt) -{ - FILE *input = stdin; - char phrase[200] = {'\0'}; - int isInputTerminal = isatty(fileno(stdin)); - - (void) arg; (void) prompt; // avoid warnings - -#ifndef _WINDOWS - if (isInputTerminal) { - input = fopen(consoleName, "r"); - if (input == NULL) { - fprintf(stderr, "Error opening input terminal for read\n"); - return NULL; - } - } -#endif - - if (isInputTerminal) { - fprintf(stdout, "Please enter your password:\n"); - fflush(stdout); - } - - QUIET_FGETS (phrase, sizeof(phrase), input); - - if (isInputTerminal) { - fprintf(stdout, "\n"); - } - -#ifndef _WINDOWS - if (isInputTerminal) { - fclose(input); - } -#endif - - /* Strip off the newlines if present */ - if (phrase[PORT_Strlen(phrase)-1] == '\n' || - phrase[PORT_Strlen(phrase)-1] == '\r') { - phrase[PORT_Strlen(phrase)-1] = 0; - } - return (char*) PORT_Strdup(phrase); -} - -char * -SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) -{ - char* phrases, *phrase; - PRFileDesc *fd; - int32_t nb; - char *pwFile = arg; - int i; - const long maxPwdFileSize = 4096; - char* tokenName = NULL; - int tokenLen = 0; - - if (!pwFile) - return 0; - - if (retry) { - return 0; /* no good retrying - the files contents will be the same */ - } - - phrases = PORT_ZAlloc(maxPwdFileSize + 1); - - if (!phrases) { - return 0; /* out of memory */ - } - - fd = PR_Open(pwFile, PR_RDONLY, 0); - if (!fd) { - fprintf(stderr, "No password file \"%s\" exists.\n", pwFile); - PORT_Free(phrases); - return NULL; - } - - nb = PR_Read(fd, phrases, maxPwdFileSize); - - PR_Close(fd); - - if (nb == 0) { - fprintf(stderr,"password file contains no data\n"); - PORT_Free(phrases); - return NULL; - } - - if (slot) { - tokenName = PK11_GetTokenName(slot); - if (tokenName) { - tokenLen = PORT_Strlen(tokenName); - } - } - i = 0; - do - { - int startphrase = i; - int phraseLen; - - /* handle the Windows EOL case */ - while (i < nb && phrases[i] != '\r' && phrases[i] != '\n') i++; - /* terminate passphrase */ - phrases[i++] = '\0'; - /* clean up any EOL before the start of the next passphrase */ - while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) { - phrases[i++] = '\0'; - } - /* now analyze the current passphrase */ - phrase = &phrases[startphrase]; - if (!tokenName) - break; - if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue; - phraseLen = PORT_Strlen(phrase); - if (phraseLen < (tokenLen+1)) continue; - if (phrase[tokenLen] != ':') continue; - phrase = &phrase[tokenLen+1]; - break; - - } while (i<nb); - - phrase = PORT_Strdup((char*)phrase); - PORT_Free(phrases); - return phrase; -} - -char * -SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) -{ - char prompt[255]; - secuPWData *pwdata = (secuPWData *)arg; - secuPWData pwnull = { PW_NONE, 0 }; - secuPWData pwxtrn = { PW_EXTERNAL, "external" }; - char *pw; - - if (pwdata == NULL) - pwdata = &pwnull; - - if (PK11_ProtectedAuthenticationPath(slot)) { - pwdata = &pwxtrn; - } - if (retry && pwdata->source != PW_NONE) { - PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n"); - return NULL; - } - - switch (pwdata->source) { - case PW_NONE: - sprintf(prompt, "Enter Password or Pin for \"%s\":", - PK11_GetTokenName(slot)); - return GetPasswordString(NULL, prompt); - case PW_FROMFILE: - /* Instead of opening and closing the file every time, get the pw - * once, then keep it in memory (duh). - */ - pw = SECU_FilePasswd(slot, retry, pwdata->data); - pwdata->source = PW_PLAINTEXT; - pwdata->data = strdup(pw); - /* it's already been dup'ed */ - return pw; - case PW_EXTERNAL: - sprintf(prompt, - "Press Enter, then enter PIN for \"%s\" on external device.\n", - PK11_GetTokenName(slot)); - pw = GetPasswordString(NULL, prompt); - if (pw) { - memset(pw, 0, PORT_Strlen(pw)); - PORT_Free(pw); - } - /* Fall Through */ - case PW_PLAINTEXT: - return strdup(pwdata->data); - default: - break; - } - - PR_fprintf(PR_STDERR, "Password check failed: No password found.\n"); - return NULL; -} diff --git a/onlineupdate/source/libmar/sign/nss_secutil.h b/onlineupdate/source/libmar/sign/nss_secutil.h deleted file mode 100644 index 5b1772d17994..000000000000 --- a/onlineupdate/source/libmar/sign/nss_secutil.h +++ /dev/null @@ -1,40 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* With the exception of GetPasswordString, this file was - copied from NSS's cmd/lib/secutil.h hg revision 8f011395145e */ - -#pragma once - -#include "nss.h" -#include "pk11pub.h" -#include "cryptohi.h" -#include "hasht.h" -#include "cert.h" -#include "key.h" -#include <stdint.h> - -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)) -#include <conio.h> -#include <io.h> -#define QUIET_FGETS quiet_fgets -static char * quiet_fgets (char *buf, int length, FILE *input); -#else -#define QUIET_FGETS fgets -#endif - -char * -SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg); diff --git a/onlineupdate/source/libmar/src/Makefile.in b/onlineupdate/source/libmar/src/Makefile.in deleted file mode 100644 index 1da582e5be03..000000000000 --- a/onlineupdate/source/libmar/src/Makefile.in +++ /dev/null @@ -1,13 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile just builds support for reading archives. - -include $(topsrcdir)/config/rules.mk - -# The intermediate (.ii/.s) files for host and target can have the same name... -# disable parallel builds -.NOTPARALLEL: diff --git a/onlineupdate/source/libmar/src/mar_create.c b/onlineupdate/source/libmar/src/mar_create.c deleted file mode 100644 index 599e0a2a7b2a..000000000000 --- a/onlineupdate/source/libmar/src/mar_create.c +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <onlineupdate/mar_private.h> -#include <onlineupdate/mar_cmdline.h> -#include <onlineupdate/mar.h> - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <netinet/in.h> -#include <unistd.h> -#endif - -struct MarItemStack { - void *head; - uint32_t size_used; - uint32_t size_allocated; - uint32_t last_offset; -}; - -/** - * Push a new item onto the stack of items. The stack is a single block - * of memory. - */ -static int mar_push(struct MarItemStack *stack, uint32_t length, uint32_t flags, - const char *name) { - int namelen; - uint32_t n_offset, n_length, n_flags; - uint32_t size; - char *data; - - namelen = strlen(name); - size = MAR_ITEM_SIZE(namelen); - - if (stack->size_allocated - stack->size_used < size) { - /* increase size of stack */ - size_t size_needed = ROUND_UP(stack->size_used + size, BLOCKSIZE); - stack->head = realloc(stack->head, size_needed); - if (!stack->head) - return -1; - stack->size_allocated = size_needed; - } - - data = (((char *) stack->head) + stack->size_used); - - n_offset = htonl(stack->last_offset); - n_length = htonl(length); - n_flags = htonl(flags); - - memcpy(data, &n_offset, sizeof(n_offset)); - data += sizeof(n_offset); - - memcpy(data, &n_length, sizeof(n_length)); - data += sizeof(n_length); - - memcpy(data, &n_flags, sizeof(n_flags)); - data += sizeof(n_flags); - - memcpy(data, name, namelen + 1); - - stack->size_used += size; - stack->last_offset += length; - return 0; -} - -static int mar_concat_file(FILE *fp, const char *path) { - FILE *in; - char buf[BLOCKSIZE]; - size_t len; - int rv = 0; - - in = fopen(path, "rb"); - if (!in) { - fprintf(stderr, "ERROR: could not open file in mar_concat_file()\n"); - perror(path); - return -1; - } - - while ((len = fread(buf, 1, BLOCKSIZE, in)) > 0) { - if (fwrite(buf, len, 1, fp) != 1) { - rv = -1; - break; - } - } - - fclose(in); - return rv; -} - -/** - * Writes out the product information block to the specified file. - * - * @param fp The opened MAR file being created. - * @param stack A pointer to the MAR item stack being used to create - * the MAR - * @param infoBlock The product info block to store in the file. - * @return 0 on success. -*/ -static int -mar_concat_product_info_block(FILE *fp, - struct MarItemStack *stack, - struct ProductInformationBlock *infoBlock) -{ - char buf[PIB_MAX_MAR_CHANNEL_ID_SIZE + PIB_MAX_PRODUCT_VERSION_SIZE]; - uint32_t additionalBlockID = 1, infoBlockSize, unused; - if (!fp || !infoBlock || - !infoBlock->MARChannelID || - !infoBlock->productVersion) { - return -1; - } - - /* The MAR channel name must be < 64 bytes per the spec */ - if (strlen(infoBlock->MARChannelID) > PIB_MAX_MAR_CHANNEL_ID_SIZE) { - return -1; - } - - /* The product version must be < 32 bytes per the spec */ - if (strlen(infoBlock->productVersion) > PIB_MAX_PRODUCT_VERSION_SIZE) { - return -1; - } - - /* Although we don't need the product information block size to include the - maximum MAR channel name and product version, we allocate the maximum - amount to make it easier to modify the MAR file for repurposing MAR files - to different MAR channels. + 2 is for the NULL terminators. */ - infoBlockSize = sizeof(infoBlockSize) + - sizeof(additionalBlockID) + - PIB_MAX_MAR_CHANNEL_ID_SIZE + - PIB_MAX_PRODUCT_VERSION_SIZE + 2; - if (stack) { - stack->last_offset += infoBlockSize; - } - - /* Write out the product info block size */ - infoBlockSize = htonl(infoBlockSize); - if (fwrite(&infoBlockSize, - sizeof(infoBlockSize), 1, fp) != 1) { - return -1; - } - infoBlockSize = ntohl(infoBlockSize); - - /* Write out the product info block ID */ - additionalBlockID = htonl(additionalBlockID); - if (fwrite(&additionalBlockID, - sizeof(additionalBlockID), 1, fp) != 1) { - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - /* Write out the channel name and NULL terminator */ - if (fwrite(infoBlock->MARChannelID, - strlen(infoBlock->MARChannelID) + 1, 1, fp) != 1) { - return -1; - } - - /* Write out the product version string and NULL terminator */ - if (fwrite(infoBlock->productVersion, - strlen(infoBlock->productVersion) + 1, 1, fp) != 1) { - return -1; - } - - /* Write out the rest of the block that is unused */ - unused = infoBlockSize - (sizeof(infoBlockSize) + - sizeof(additionalBlockID) + - strlen(infoBlock->MARChannelID) + - strlen(infoBlock->productVersion) + 2); - memset(buf, 0, sizeof(buf)); - if (fwrite(buf, unused, 1, fp) != 1) { - return -1; - } - return 0; -} - -/** - * Refreshes the product information block with the new information. - * The input MAR must not be signed or the function call will fail. - * - * @param path The path to the MAR file whose product info block - * should be refreshed. - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -refresh_product_info_block(const char *path, - struct ProductInformationBlock *infoBlock) -{ - FILE *fp ; - int rv; - uint32_t numSignatures, additionalBlockSize, additionalBlockID, - offsetAdditionalBlocks, numAdditionalBlocks, i; - int additionalBlocks, hasSignatureBlock; - - rv = get_mar_file_info(path, - &hasSignatureBlock, - &numSignatures, - &additionalBlocks, - &offsetAdditionalBlocks, - &numAdditionalBlocks); - if (rv) { - fprintf(stderr, "ERROR: Could not obtain MAR information.\n"); - return -1; - } - - if (hasSignatureBlock && numSignatures) { - fprintf(stderr, "ERROR: Cannot refresh a signed MAR\n"); - return -1; - } - - fp = fopen(path, "r+b"); - if (!fp) { - fprintf(stderr, "ERROR: could not open target file: %s\n", path); - return -1; - } - - if (fseeko(fp, offsetAdditionalBlocks, SEEK_SET)) { - fprintf(stderr, "ERROR: could not seek to additional blocks\n"); - fclose(fp); - return -1; - } - - for (i = 0; i < numAdditionalBlocks; ++i) { - /* Get the position of the start of this block */ - int64_t oldPos = ftello(fp); - - /* Read the additional block size */ - if (fread(&additionalBlockSize, - sizeof(additionalBlockSize), - 1, fp) != 1) { - fclose(fp); - return -1; - } - additionalBlockSize = ntohl(additionalBlockSize); - - /* Read the additional block ID */ - if (fread(&additionalBlockID, - sizeof(additionalBlockID), - 1, fp) != 1) { - fclose(fp); - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - if (PRODUCT_INFO_BLOCK_ID == additionalBlockID) { - if (fseeko(fp, oldPos, SEEK_SET)) { - fprintf(stderr, "Could not seek back to Product Information Block\n"); - fclose(fp); - return -1; - } - - if (mar_concat_product_info_block(fp, NULL, infoBlock)) { - fprintf(stderr, "Could not concat Product Information Block\n"); - fclose(fp); - return -1; - } - - fclose(fp); - return 0; - } else { - /* This is not the additional block you're looking for. Move along. */ - if (fseek(fp, additionalBlockSize, SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not seek past current block.\n"); - fclose(fp); - return -1; - } - } - } - - /* If we had a product info block we would have already returned */ - fclose(fp); - fprintf(stderr, "ERROR: Could not refresh because block does not exist\n"); - return -1; -} - -/** - * Create a MAR file from a set of files. - * @param dest The path to the file to create. This path must be - * compatible with fopen. - * @param numfiles The number of files to store in the archive. - * @param files The list of null-terminated file paths. Each file - * path must be compatible with fopen. - * @param infoBlock The information to store in the product information block. - * @return A non-zero value if an error occurs. - */ -int mar_create(const char *dest, int - num_files, char **files, - struct ProductInformationBlock *infoBlock) { - struct MarItemStack stack; - uint32_t offset_to_index = 0, size_of_index, - numSignatures, numAdditionalSections; - uint64_t sizeOfEntireMAR = 0; - struct stat st; - FILE *fp; - int i, rv = -1; - - memset(&stack, 0, sizeof(stack)); - - fp = fopen(dest, "wb"); - if (!fp) { - fprintf(stderr, "ERROR: could not create target file: %s\n", dest); - return -1; - } - - if (fwrite(MAR_ID, MAR_ID_SIZE, 1, fp) != 1) - goto failure; - if (fwrite(&offset_to_index, sizeof(uint32_t), 1, fp) != 1) - goto failure; - - stack.last_offset = MAR_ID_SIZE + - sizeof(offset_to_index) + - sizeof(numSignatures) + - sizeof(numAdditionalSections) + - sizeof(sizeOfEntireMAR); - - /* We will circle back on this at the end of the MAR creation to fill it */ - if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1) { - goto failure; - } - - /* Write out the number of signatures, for now only at most 1 is supported */ - numSignatures = 0; - if (fwrite(&numSignatures, sizeof(numSignatures), 1, fp) != 1) { - goto failure; - } - - /* Write out the number of additional sections, for now just 1 - for the product info block */ - numAdditionalSections = htonl(1); - if (fwrite(&numAdditionalSections, - sizeof(numAdditionalSections), 1, fp) != 1) { - goto failure; - } - numAdditionalSections = ntohl(numAdditionalSections); - - if (mar_concat_product_info_block(fp, &stack, infoBlock)) { - goto failure; - } - - for (i = 0; i < num_files; ++i) { - if (stat(files[i], &st)) { - fprintf(stderr, "ERROR: file not found: %s\n", files[i]); - goto failure; - } - - if (mar_push(&stack, st.st_size, st.st_mode & 0777, files[i])) - goto failure; - - /* concatenate input file to archive */ - if (mar_concat_file(fp, files[i])) - goto failure; - } - - /* write out the index (prefixed with length of index) */ - size_of_index = htonl(stack.size_used); - if (fwrite(&size_of_index, sizeof(size_of_index), 1, fp) != 1) - goto failure; - if (fwrite(stack.head, stack.size_used, 1, fp) != 1) - goto failure; - - /* To protect against invalid MAR files, we assume that the MAR file - size is less than or equal to MAX_SIZE_OF_MAR_FILE. */ - if (ftell(fp) > MAX_SIZE_OF_MAR_FILE) { - goto failure; - } - - /* write out offset to index file in network byte order */ - offset_to_index = htonl(stack.last_offset); - if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) - goto failure; - if (fwrite(&offset_to_index, sizeof(offset_to_index), 1, fp) != 1) - goto failure; - offset_to_index = ntohl(stack.last_offset); - - sizeOfEntireMAR = ((uint64_t)stack.last_offset) + - stack.size_used + - sizeof(size_of_index); - sizeOfEntireMAR = HOST_TO_NETWORK64(sizeOfEntireMAR); - if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1) - goto failure; - sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR); - - rv = 0; -failure: - if (stack.head) - free(stack.head); - fclose(fp); - if (rv) - remove(dest); - return rv; -} diff --git a/onlineupdate/source/libmar/src/mar_extract.c b/onlineupdate/source/libmar/src/mar_extract.c deleted file mode 100644 index 11e570242fd0..000000000000 --- a/onlineupdate/source/libmar/src/mar_extract.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <onlineupdate/mar_private.h> -#include <onlineupdate/mar.h> - -#ifdef _WIN32 -#include <io.h> -#include <direct.h> -#endif - -/* Ensure that the directory containing this file exists */ -static int mar_ensure_parent_dir(const char *path) -{ - char *slash = strrchr(path, '/'); - if (slash) - { - *slash = '\0'; - mar_ensure_parent_dir(path); -#ifdef _WIN32 - _mkdir(path); -#else - mkdir(path, 0755); -#endif - *slash = '/'; - } - return 0; -} - -static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) { - FILE *fp; - char buf[BLOCKSIZE]; - int fd, len, offset = 0; - - (void) unused; // avoid warnings - - if (mar_ensure_parent_dir(item->name)) - return -1; - -#ifdef _WIN32 - fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags); -#else - fd = creat(item->name, item->flags); -#endif - if (fd == -1) { - fprintf(stderr, "ERROR: could not create file in mar_test_callback()\n"); - perror(item->name); - return -1; - } - - fp = fdopen(fd, "wb"); - if (!fp) - return -1; - - while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) { - if (fwrite(buf, len, 1, fp) != 1) - break; - offset += len; - } - - fclose(fp); - return len == 0 ? 0 : -1; -} - -int mar_extract(const char *path) { - MarFile *mar; - int rv; - - mar = mar_open(path); - if (!mar) - return -1; - - rv = mar_enum_items(mar, mar_test_callback, NULL); - - mar_close(mar); - return rv; -} diff --git a/onlineupdate/source/libmar/src/mar_read.c b/onlineupdate/source/libmar/src/mar_read.c deleted file mode 100644 index 2a6238ca23fc..000000000000 --- a/onlineupdate/source/libmar/src/mar_read.c +++ /dev/null @@ -1,572 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <sys/types.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <onlineupdate/mar_private.h> -#include <onlineupdate/mar.h> - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <netinet/in.h> -#endif - - -/* this is the same hash algorithm used by nsZipArchive.cpp */ -static uint32_t mar_hash_name(const char *name) { - uint32_t val = 0; - unsigned char* c; - - for (c = (unsigned char *) name; *c; ++c) - val = val*37 + *c; - - return val % TABLESIZE; -} - -static int mar_insert_item(MarFile *mar, const char *name, int namelen, - uint32_t offset, uint32_t length, uint32_t flags) { - MarItem *item, *root; - uint32_t hash; - - item = (MarItem *) malloc(sizeof(MarItem) + namelen); - if (!item) - return -1; - item->next = NULL; - item->offset = offset; - item->length = length; - item->flags = flags; - memcpy(item->name, name, namelen + 1); - - hash = mar_hash_name(name); - - root = mar->item_table[hash]; - if (!root) { - mar->item_table[hash] = item; - } else { - /* append item */ - while (root->next) - root = root->next; - root->next = item; - } - return 0; -} - -static int mar_consume_index(MarFile *mar, char **buf, const char *buf_end) { - /* - * Each item has the following structure: - * uint32_t offset (network byte order) - * uint32_t length (network byte order) - * uint32_t flags (network byte order) - * char name[N] (where N >= 1) - * char null_byte; - */ - uint32_t offset; - uint32_t length; - uint32_t flags; - const char *name; - int namelen; - - if ((buf_end - *buf) < (int)(3*sizeof(uint32_t) + 2)) - return -1; - - memcpy(&offset, *buf, sizeof(offset)); - *buf += sizeof(offset); - - memcpy(&length, *buf, sizeof(length)); - *buf += sizeof(length); - - memcpy(&flags, *buf, sizeof(flags)); - *buf += sizeof(flags); - - offset = ntohl(offset); - length = ntohl(length); - flags = ntohl(flags); - - name = *buf; - /* find namelen; must take care not to read beyond buf_end */ - while (**buf) { - if (*buf == buf_end) - return -1; - ++(*buf); - } - namelen = (*buf - name); - /* consume null byte */ - if (*buf == buf_end) - return -1; - ++(*buf); - - return mar_insert_item(mar, name, namelen, offset, length, flags); -} - -static int mar_read_index(MarFile *mar) { - char id[MAR_ID_SIZE], *buf, *bufptr, *bufend; - uint32_t offset_to_index, size_of_index; - - /* verify MAR ID */ - if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1) - return -1; - if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0) - return -1; - - if (fread(&offset_to_index, sizeof(uint32_t), 1, mar->fp) != 1) - return -1; - offset_to_index = ntohl(offset_to_index); - - if (fseek(mar->fp, offset_to_index, SEEK_SET)) - return -1; - if (fread(&size_of_index, sizeof(uint32_t), 1, mar->fp) != 1) - return -1; - size_of_index = ntohl(size_of_index); - - buf = (char *) malloc(size_of_index); - if (!buf) - return -1; - if (fread(buf, size_of_index, 1, mar->fp) != 1) { - free(buf); - return -1; - } - - bufptr = buf; - bufend = buf + size_of_index; - while (bufptr < bufend && mar_consume_index(mar, &bufptr, bufend) == 0); - - free(buf); - return (bufptr == bufend) ? 0 : -1; -} - -/** - * Internal shared code for mar_open and mar_wopen. - * On failure, will fclose(fp). - */ -static MarFile *mar_fpopen(FILE *fp) -{ - MarFile *mar; - - mar = (MarFile *) malloc(sizeof(*mar)); - if (!mar) { - fclose(fp); - return NULL; - } - - mar->fp = fp; - memset(mar->item_table, 0, sizeof(mar->item_table)); - if (mar_read_index(mar)) { - mar_close(mar); - return NULL; - } - - return mar; -} - -MarFile *mar_open(const char *path) { - FILE *fp; - - fp = fopen(path, "rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in mar_open()\n"); - perror(path); - return NULL; - } - - return mar_fpopen(fp); -} - -#ifdef _WIN32 -MarFile *mar_wopen(const wchar_t *path) { - FILE *fp; - - _wfopen_s(&fp, path, L"rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in mar_wopen()\n"); - _wperror(path); - return NULL; - } - - return mar_fpopen(fp); -} -#endif - -void mar_close(MarFile *mar) { - MarItem *item; - int i; - - fclose(mar->fp); - - for (i = 0; i < TABLESIZE; ++i) { - item = mar->item_table[i]; - while (item) { - MarItem *temp = item; - item = item->next; - free(temp); - } - } - - free(mar); -} - -/** - * Determines the MAR file information. - * - * @param fp An opened MAR file in read mode. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info_fp(FILE *fp, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks) -{ - uint32_t offsetToIndex, offsetToContent, signatureCount, signatureLen, i; - - /* One of hasSignatureBlock or hasAdditionalBlocks must be non NULL */ - if (!hasSignatureBlock && !hasAdditionalBlocks) { - return -1; - } - - - /* Skip to the start of the offset index */ - if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) { - return -1; - } - - /* Read the offset to the index. */ - if (fread(&offsetToIndex, sizeof(offsetToIndex), 1, fp) != 1) { - return -1; - } - offsetToIndex = ntohl(offsetToIndex); - - if (numSignatures) { - /* Skip past the MAR file size field */ - if (fseek(fp, sizeof(uint64_t), SEEK_CUR)) { - return -1; - } - - /* Read the number of signatures field */ - if (fread(numSignatures, sizeof(*numSignatures), 1, fp) != 1) { - return -1; - } - *numSignatures = ntohl(*numSignatures); - } - - /* Skip to the first index entry past the index size field - We do it in 2 calls because offsetToIndex + sizeof(uint32_t) - could overflow in theory. */ - if (fseek(fp, offsetToIndex, SEEK_SET)) { - return -1; - } - - if (fseek(fp, sizeof(uint32_t), SEEK_CUR)) { - return -1; - } - - /* Read the first offset to content field. */ - if (fread(&offsetToContent, sizeof(offsetToContent), 1, fp) != 1) { - return -1; - } - offsetToContent = ntohl(offsetToContent); - - /* Check if we have a new or old MAR file */ - if (hasSignatureBlock) { - if (offsetToContent == MAR_ID_SIZE + sizeof(uint32_t)) { - *hasSignatureBlock = 0; - } else { - *hasSignatureBlock = 1; - } - } - - /* If the caller doesn't care about the product info block - value, then just return */ - if (!hasAdditionalBlocks) { - return 0; - } - - /* Skip to the start of the signature block */ - if (fseeko(fp, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) { - return -1; - } - - /* Get the number of signatures */ - if (fread(&signatureCount, sizeof(signatureCount), 1, fp) != 1) { - return -1; - } - signatureCount = ntohl(signatureCount); - - /* Check that we have less than the max amount of signatures so we don't - waste too much of either updater's or signmar's time. */ - if (signatureCount > MAX_SIGNATURES) { - return -1; - } - - /* Skip past the whole signature block */ - for (i = 0; i < signatureCount; i++) { - /* Skip past the signature algorithm ID */ - if (fseek(fp, sizeof(uint32_t), SEEK_CUR)) { - return -1; - } - - /* Read the signature length and skip past the signature */ - if (fread(&signatureLen, sizeof(uint32_t), 1, fp) != 1) { - return -1; - } - signatureLen = ntohl(signatureLen); - if (fseek(fp, signatureLen, SEEK_CUR)) { - return -1; - } - } - - if (ftell(fp) == (long)offsetToContent) { - *hasAdditionalBlocks = 0; - } else { - if (numAdditionalBlocks) { - /* We have an additional block, so read in the number of additional blocks - and set the offset. */ - *hasAdditionalBlocks = 1; - if (fread(numAdditionalBlocks, sizeof(uint32_t), 1, fp) != 1) { - return -1; - } - *numAdditionalBlocks = ntohl(*numAdditionalBlocks); - if (offsetAdditionalBlocks) { - *offsetAdditionalBlocks = ftell(fp); - } - } else if (offsetAdditionalBlocks) { - /* numAdditionalBlocks is not specified but offsetAdditionalBlocks - is, so fill it! */ - *offsetAdditionalBlocks = ftell(fp) + sizeof(uint32_t); - } - } - - return 0; -} - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -read_product_info_block(char *path, - struct ProductInformationBlock *infoBlock) -{ - int rv; - MarFile mar; - mar.fp = fopen(path, "rb"); - if (!mar.fp) { - fprintf(stderr, "ERROR: could not open file in read_product_info_block()\n"); - perror(path); - return -1; - } - rv = mar_read_product_info_block(&mar, infoBlock); - fclose(mar.fp); - return rv; -} - -/** - * Reads the product info block from the MAR file's additional block section. - * The caller is responsible for freeing the fields in infoBlock - * if the return is successful. - * - * @param infoBlock Out parameter for where to store the result to - * @return 0 on success, -1 on failure -*/ -int -mar_read_product_info_block(MarFile *mar, - struct ProductInformationBlock *infoBlock) -{ - uint32_t i, offsetAdditionalBlocks, numAdditionalBlocks, - additionalBlockSize, additionalBlockID; - int hasAdditionalBlocks; - - /* The buffer size is 97 bytes because the MAR channel name < 64 bytes, and - product version < 32 bytes + 3 NULL terminator bytes. */ - char buf[97] = { '\0' }; - int ret = get_mar_file_info_fp(mar->fp, NULL, NULL, - &hasAdditionalBlocks, - &offsetAdditionalBlocks, - &numAdditionalBlocks); - if (ret) - return ret; - for (i = 0; i < numAdditionalBlocks; ++i) { - /* Read the additional block size */ - if (fread(&additionalBlockSize, - sizeof(additionalBlockSize), - 1, mar->fp) != 1) { - return -1; - } - additionalBlockSize = ntohl(additionalBlockSize) - - sizeof(additionalBlockSize) - - sizeof(additionalBlockID); - - /* Read the additional block ID */ - if (fread(&additionalBlockID, - sizeof(additionalBlockID), - 1, mar->fp) != 1) { - return -1; - } - additionalBlockID = ntohl(additionalBlockID); - - if (PRODUCT_INFO_BLOCK_ID == additionalBlockID) { - const char *location; - int len; - - /* This block must be at most 104 bytes. - MAR channel name < 64 bytes, and product version < 32 bytes + 3 NULL - terminator bytes. We only check for 96 though because we remove 8 - bytes above from the additionalBlockSize: We subtract - sizeof(additionalBlockSize) and sizeof(additionalBlockID) */ - if (additionalBlockSize > 96) { - return -1; - } - - if (fread(buf, additionalBlockSize, 1, mar->fp) != 1) { - return -1; - } - - /* Extract the MAR channel name from the buffer. For now we - point to the stack allocated buffer but we strdup this - if we are within bounds of each field's max length. */ - location = buf; - len = strlen(location); - infoBlock->MARChannelID = location; - location += len + 1; - if (len >= 64) { - infoBlock->MARChannelID = NULL; - return -1; - } - - /* Extract the version from the buffer */ - len = strlen(location); - infoBlock->productVersion = location; - location += len + 1; - if (len >= 32) { - infoBlock->MARChannelID = NULL; - infoBlock->productVersion = NULL; - return -1; - } - infoBlock->MARChannelID = - strdup(infoBlock->MARChannelID); - infoBlock->productVersion = - strdup(infoBlock->productVersion); - return 0; - } else { - /* This is not the additional block you're looking for. Move along. */ - if (fseek(mar->fp, additionalBlockSize, SEEK_CUR)) { - return -1; - } - } - } - - /* If we had a product info block we would have already returned */ - return -1; -} - -const MarItem *mar_find_item(MarFile *mar, const char *name) { - uint32_t hash; - const MarItem *item; - - hash = mar_hash_name(name); - - item = mar->item_table[hash]; - while (item && strcmp(item->name, name) != 0) - item = item->next; - - return item; -} - -int mar_enum_items(MarFile *mar, MarItemCallback callback, void *closure) { - MarItem *item; - int i; - - for (i = 0; i < TABLESIZE; ++i) { - item = mar->item_table[i]; - while (item) { - int rv = callback(mar, item, closure); - if (rv) - return rv; - item = item->next; - } - } - - return 0; -} - -int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf, - int bufsize) { - int nr; - - if (offset == (int) item->length) - return 0; - if (offset > (int) item->length) - return -1; - - nr = item->length - offset; - if (nr > bufsize) - nr = bufsize; - - if (fseek(mar->fp, item->offset + offset, SEEK_SET)) - return -1; - - return fread(buf, 1, nr, mar->fp); -} - -/** - * Determines the MAR file information. - * - * @param path The path of the MAR file to check. - * @param hasSignatureBlock Optional out parameter specifying if the MAR - * file has a signature block or not. - * @param numSignatures Optional out parameter for storing the number - * of signatures in the MAR file. - * @param hasAdditionalBlocks Optional out parameter specifying if the MAR - * file has additional blocks or not. - * @param offsetAdditionalBlocks Optional out parameter for the offset to the - * first additional block. Value is only valid if - * hasAdditionalBlocks is not equal to 0. - * @param numAdditionalBlocks Optional out parameter for the number of - * additional blocks. Value is only valid if - * has_additional_blocks is not equal to 0. - * @return 0 on success and non-zero on failure. - */ -int get_mar_file_info(const char *path, - int *hasSignatureBlock, - uint32_t *numSignatures, - int *hasAdditionalBlocks, - uint32_t *offsetAdditionalBlocks, - uint32_t *numAdditionalBlocks) -{ - int rv; - FILE *fp = fopen(path, "rb"); - if (!fp) { - fprintf(stderr, "ERROR: could not open file in get_mar_file_info()\n"); - perror(path); - return -1; - } - - rv = get_mar_file_info_fp(fp, hasSignatureBlock, - numSignatures, hasAdditionalBlocks, - offsetAdditionalBlocks, numAdditionalBlocks); - - fclose(fp); - return rv; -} diff --git a/onlineupdate/source/libmar/tool/Makefile.in b/onlineupdate/source/libmar/tool/Makefile.in deleted file mode 100644 index 20a7c475aa08..000000000000 --- a/onlineupdate/source/libmar/tool/Makefile.in +++ /dev/null @@ -1,23 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# The mar executable is output into dist/host/bin since it is something that -# would only be used by our build system and should not itself be included in a -# Mozilla distribution. - -HOST_CFLAGS += \ - -DNO_SIGN_VERIFY \ - $(DEFINES) \ - $(NULL) - -include $(topsrcdir)/config/rules.mk - -ifdef CROSS_COMPILE -ifdef HOST_NSPR_MDCPUCFG -HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG) -CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG) -endif -endif diff --git a/onlineupdate/source/libmar/tool/mar.c b/onlineupdate/source/libmar/tool/mar.c deleted file mode 100644 index 3db3bb86e431..000000000000 --- a/onlineupdate/source/libmar/tool/mar.c +++ /dev/null @@ -1,463 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <onlineupdate/mar.h> -#include <onlineupdate/mar_cmdline.h> - -#ifdef _WIN32 -#include <windows.h> -#include <direct.h> -#define chdir _chdir -#else -#include <unistd.h> -#include <errno.h> -#endif - -#ifndef APP_VERSION -#error "Missing APP_VERSION" -#endif - -#define MAR_CHANNEL_ID "LOOnlineUpdater" /* Dummy value; replace or - remove in the future */ - -#if !defined(NO_SIGN_VERIFY) && (!defined(_WIN32) || defined(MAR_NSS)) -#include "cert.h" -#include "pk11pub.h" -int NSSInitCryptoContext(const char *NSSConfigDir); -#endif - -int mar_repackage_and_sign(const char *NSSConfigDir, - const char * const *certNames, - uint32_t certCount, - const char *src, - const char * dest); - -static void print_version(void) { - printf("Version: %s\n", APP_VERSION); - printf("Default Channel ID: %s\n", MAR_CHANNEL_ID); -} - -static void print_usage(void) { - printf("usage:\n"); - printf("Create a MAR file:\n"); - printf(" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] " - "-c archive.mar [files...]\n"); - printf(" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] " - "-c archive.mar -f input_file.txt\n"); - - printf("Extract a MAR file:\n"); - printf(" mar [-C workingDir] -x archive.mar\n"); -#ifndef NO_SIGN_VERIFY - printf("Sign a MAR file:\n"); - printf(" mar [-C workingDir] -d NSSConfigDir -n certname -s " - "archive.mar out_signed_archive.mar\n"); - - printf("Strip a MAR signature:\n"); - printf(" mar [-C workingDir] -r " - "signed_input_archive.mar output_archive.mar\n"); - - printf("Extract a MAR signature:\n"); - printf(" mar [-C workingDir] -n(i) -X " - "signed_input_archive.mar base_64_encoded_signature_file\n"); - - printf("Import a MAR signature:\n"); - printf(" mar [-C workingDir] -n(i) -I " - "signed_input_archive.mar base_64_encoded_signature_file " - "changed_signed_output.mar\n"); - printf("(i) is the index of the certificate to extract\n"); -#if defined(MACOSX) || (defined(_WIN32) && !defined(MAR_NSS)) - printf("Verify a MAR file:\n"); - printf(" mar [-C workingDir] -D DERFilePath -v signed_archive.mar\n"); - printf("At most %d signature certificate DER files are specified by " - "-D0 DERFilePath1 -D1 DERFilePath2, ...\n", MAX_SIGNATURES); -#else - printf("Verify a MAR file:\n"); - printf(" mar [-C workingDir] -d NSSConfigDir -n certname " - "-v signed_archive.mar\n"); - printf("At most %d signature certificate names are specified by " - "-n0 certName -n1 certName2, ...\n", MAX_SIGNATURES); -#endif - printf("At most %d verification certificate names are specified by " - "-n0 certName -n1 certName2, ...\n", MAX_SIGNATURES); -#endif - printf("Print information on a MAR file:\n"); - printf(" mar -t archive.mar\n"); - - printf("Print detailed information on a MAR file including signatures:\n"); - printf(" mar -T archive.mar\n"); - - printf("Refresh the product information block of a MAR file:\n"); - printf(" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] " - "-i unsigned_archive_to_refresh.mar\n"); - - printf("Print executable version:\n"); - printf(" mar --version\n"); - printf("This program does not handle unicode file paths properly\n"); -} - -static int mar_test_callback(MarFile *mar, - const MarItem *item, - void *unused) { - (void) mar; (void) unused; // avoid warnings - - printf("%u\t0%o\t%s\n", item->length, item->flags, item->name); - return 0; -} - -static int mar_test(const char *path) { - MarFile *mar; - - mar = mar_open(path); - if (!mar) - return -1; - - printf("SIZE\tMODE\tNAME\n"); - mar_enum_items(mar, mar_test_callback, NULL); - - mar_close(mar); - return 0; -} - -int main(int argc, char **argv) { - char *NSSConfigDir = NULL; - const char *certNames[MAX_SIGNATURES]; - char *MARChannelID = MAR_CHANNEL_ID; - char *productVersion = APP_VERSION; -#ifndef NO_SIGN_VERIFY - uint32_t k; -#endif - int rv = -1; - uint32_t certCount = 0; - int32_t sigIndex = -1; - -#if !defined(NO_SIGN_VERIFY) - uint32_t fileSizes[MAX_SIGNATURES]; - const uint8_t* certBuffers[MAX_SIGNATURES]; - char* DERFilePaths[MAX_SIGNATURES]; -#if (!defined(_WIN32) && !defined(MACOSX)) || defined(MAR_NSS) - CERTCertificate* certs[MAX_SIGNATURES]; -#endif -#endif - - memset((void*)certNames, 0, sizeof(certNames)); -#if defined(_WIN32) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY) - memset((void*)certBuffers, 0, sizeof(certBuffers)); -#endif -#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(_WIN32)) || \ - defined(MACOSX)) - memset(DERFilePaths, 0, sizeof(DERFilePaths)); - memset(fileSizes, 0, sizeof(fileSizes)); -#endif - - if (argc > 1 && 0 == strcmp(argv[1], "--version")) { - print_version(); - return 0; - } - - if (argc < 3) { - print_usage(); - return -1; - } - - while (argc > 0) { - if (argv[1][0] == '-' && (argv[1][1] == 'c' || - argv[1][1] == 't' || argv[1][1] == 'x' || - argv[1][1] == 'v' || argv[1][1] == 's' || - argv[1][1] == 'i' || argv[1][1] == 'T' || - argv[1][1] == 'r' || argv[1][1] == 'X' || - argv[1][1] == 'I')) { - break; - /* -C workingdirectory */ - } else if (argv[1][0] == '-' && argv[1][1] == 'C') { - chdir(argv[2]); - argv += 2; - argc -= 2; - } -#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(_WIN32)) || \ - defined(MACOSX)) - /* -D DERFilePath, also matches -D[index] DERFilePath - We allow an index for verifying to be symmetric - with the import and export command line arguments. */ - else if (argv[1][0] == '-' && - argv[1][1] == 'D' && - (argv[1][2] == (char)('0' + certCount) || argv[1][2] == '\0')) { - if (certCount >= MAX_SIGNATURES) { - print_usage(); - return -1; - } - DERFilePaths[certCount++] = argv[2]; - argv += 2; - argc -= 2; - } -#endif - /* -d NSSConfigdir */ - else if (argv[1][0] == '-' && argv[1][1] == 'd') { - NSSConfigDir = argv[2]; - argv += 2; - argc -= 2; - /* -n certName, also matches -n[index] certName - We allow an index for verifying to be symmetric - with the import and export command line arguments. */ - } else if (argv[1][0] == '-' && - argv[1][1] == 'n' && - (argv[1][2] == (char)('0' + certCount) || - argv[1][2] == '\0' || - !strcmp(argv[2], "-X") || - !strcmp(argv[2], "-I"))) { - if (certCount >= MAX_SIGNATURES) { - print_usage(); - return -1; - } - certNames[certCount++] = argv[2]; - if (strlen(argv[1]) > 2 && - (!strcmp(argv[2], "-X") || !strcmp(argv[2], "-I")) && - argv[1][2] >= '0' && argv[1][2] <= '9') { - sigIndex = argv[1][2] - '0'; - argv++; - argc--; - } else { - argv += 2; - argc -= 2; - } - /* MAR channel ID */ - } else if (argv[1][0] == '-' && argv[1][1] == 'H') { - MARChannelID = argv[2]; - argv += 2; - argc -= 2; - /* Product Version */ - } else if (argv[1][0] == '-' && argv[1][1] == 'V') { - productVersion = argv[2]; - argv += 2; - argc -= 2; - } - else { - print_usage(); - return -1; - } - } - - if (argv[1][0] != '-') { - print_usage(); - return -1; - } - - switch (argv[1][1]) { - case 'c': { - struct ProductInformationBlock infoBlock; - infoBlock.MARChannelID = MARChannelID; - infoBlock.productVersion = productVersion; - if (argv[argc - 2][0] == '-' && argv[argc - 2][1] == 'f') - { - char buf[1000]; - FILE* file; - char** files; - int num_files = 0; - - files = (char **)malloc(sizeof(char*)*10000); - errno = 0; - file = fopen(argv[argc - 1], "r"); - if (!file) - { - printf("%d %s", errno, strerror(errno)); - printf("Could not open file: %s", argv[argc - 1]); - exit(1); - } - - while(fgets(buf, 1000, file) != NULL) - { - int j; - size_t str_len; - for (j=strlen(buf)-1;j>=0 && (buf[j]=='\n' || buf[j]=='\r');j--) - ; - buf[j+1]='\0'; - str_len = strlen(buf) + 1; - files[num_files] = (char*)malloc(sizeof(char)*str_len); - strcpy(files[num_files], buf); - ++num_files; - } - fclose(file); - return mar_create(argv[2], num_files, files, &infoBlock); - } - else - return mar_create(argv[2], argc - 3, argv + 3, &infoBlock); - } - case 'i': { - struct ProductInformationBlock infoBlock; - infoBlock.MARChannelID = MARChannelID; - infoBlock.productVersion = productVersion; - return refresh_product_info_block(argv[2], &infoBlock); - } - case 'T': { - struct ProductInformationBlock infoBlock; - uint32_t numSignatures, numAdditionalBlocks; - int hasSignatureBlock, hasAdditionalBlock; - if (!get_mar_file_info(argv[2], - &hasSignatureBlock, - &numSignatures, - &hasAdditionalBlock, - NULL, &numAdditionalBlocks)) { - if (hasSignatureBlock) { - printf("Signature block found with %d signature%s\n", - numSignatures, - numSignatures != 1 ? "s" : ""); - } - if (hasAdditionalBlock) { - printf("%d additional block%s found:\n", - numAdditionalBlocks, - numAdditionalBlocks != 1 ? "s" : ""); - } - - rv = read_product_info_block(argv[2], &infoBlock); - if (!rv) { - printf(" - Product Information Block:\n"); - printf(" - MAR channel name: %s\n" - " - Product version: %s\n", - infoBlock.MARChannelID, - infoBlock.productVersion); - free((void *)infoBlock.MARChannelID); - free((void *)infoBlock.productVersion); - } - } - printf("\n"); - /* The fall through from 'T' to 't' is intentional */ - } - /* Fall through */ - case 't': - return mar_test(argv[2]); - - /* Extract a MAR file */ - case 'x': - return mar_extract(argv[2]); - -#ifndef NO_SIGN_VERIFY - /* Extract a MAR signature */ - case 'X': - if (sigIndex == -1) { - fprintf(stderr, "ERROR: Signature index was not passed.\n"); - return -1; - } - if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) { - fprintf(stderr, "ERROR: Signature index is out of range: %d.\n", - sigIndex); - return -1; - } - return extract_signature(argv[2], sigIndex, argv[3]); - - /* Import a MAR signature */ - case 'I': - if (sigIndex == -1) { - fprintf(stderr, "ERROR: signature index was not passed.\n"); - return -1; - } - if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) { - fprintf(stderr, "ERROR: Signature index is out of range: %d.\n", - sigIndex); - return -1; - } - if (argc < 5) { - print_usage(); - return -1; - } - return import_signature(argv[2], sigIndex, argv[3], argv[4]); - - case 'v': - if (certCount == 0) { - print_usage(); - return -1; - } - -#if (!defined(_WIN32) && !defined(MACOSX)) || defined(MAR_NSS) - if (!NSSConfigDir || certCount == 0) { - print_usage(); - return -1; - } - - if (NSSInitCryptoContext(NSSConfigDir)) { - fprintf(stderr, "ERROR: Could not initialize crypto library.\n"); - return -1; - } -#endif - - rv = 0; - for (k = 0; k < certCount; ++k) { -#if (defined(_WIN32) || defined(MACOSX)) && !defined(MAR_NSS) - rv = mar_read_entire_file(DERFilePaths[k], MAR_MAX_CERT_SIZE, - &certBuffers[k], &fileSizes[k]); -#else - /* It is somewhat circuitous to look up a CERTCertificate and then pass - * in its DER encoding just so we can later re-create that - * CERTCertificate to extract the public key out of it. However, by doing - * things this way, we maximize the reuse of the mar_verify_signatures - * function and also we keep the control flow as similar as possible - * between programs and operating systems, at least for the functions - * that are critically important to security. - */ - certs[k] = PK11_FindCertFromNickname(certNames[k], NULL); - if (certs[k]) { - certBuffers[k] = certs[k]->derCert.data; - fileSizes[k] = certs[k]->derCert.len; - } else { - rv = -1; - } -#endif - if (rv) { - fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]); - break; - } - } - - if (!rv) { - MarFile *mar = mar_open(argv[2]); - if (mar) { - rv = mar_verify_signatures(mar, certBuffers, fileSizes, certCount); - mar_close(mar); - } else { - fprintf(stderr, "ERROR: Could not open MAR file.\n"); - rv = -1; - } - } - for (k = 0; k < certCount; ++k) { -#if (defined(_WIN32) || defined(MACOSX)) && !defined(MAR_NSS) - free((void*)certBuffers[k]); -#else - /* certBuffers[k] is owned by certs[k] so don't free it */ - CERT_DestroyCertificate(certs[k]); -#endif - } - if (rv) { - /* Determine if the source MAR file has the new fields for signing */ - int hasSignatureBlock; - if (get_mar_file_info(argv[2], &hasSignatureBlock, - NULL, NULL, NULL, NULL)) { - fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n"); - } else if (!hasSignatureBlock) { - fprintf(stderr, "ERROR: The MAR file is in the old format so has" - " no signature to verify.\n"); - } - return -1; - } - return 0; - - case 's': - if (!NSSConfigDir || certCount == 0 || argc < 4) { - print_usage(); - return -1; - } - return mar_repackage_and_sign(NSSConfigDir, certNames, certCount, - argv[2], argv[3]); - - case 'r': - return strip_signature_block(argv[2], argv[3]); -#endif /* endif NO_SIGN_VERIFY disabled */ - - default: - print_usage(); - return -1; - } -} diff --git a/onlineupdate/source/libmar/verify/MacVerifyCrypto.cpp b/onlineupdate/source/libmar/verify/MacVerifyCrypto.cpp deleted file mode 100644 index e86fac3c5863..000000000000 --- a/onlineupdate/source/libmar/verify/MacVerifyCrypto.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <CoreFoundation/CoreFoundation.h> -#include <Security/Security.h> -#include <dlfcn.h> - -#include "cryptox.h" - -// We declare the necessary parts of the Security Transforms API here since -// we're building with the 10.6 SDK, which doesn't know about Security -// Transforms. -extern "C" { - const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT"); - typedef CFTypeRef SecTransformRef; - typedef struct OpaqueSecKeyRef* SecKeyRef; - - typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc) - (CFReadStreamRef inputStream); - SecTransformCreateReadTransformWithReadStreamFunc - SecTransformCreateReadTransformWithReadStreamPtr = NULL; - typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform, - CFErrorRef* error); - SecTransformExecuteFunc SecTransformExecutePtr = NULL; - typedef SecTransformRef (*SecVerifyTransformCreateFunc)(SecKeyRef key, - CFDataRef signature, - CFErrorRef* error); - SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr = NULL; - typedef Boolean (*SecTransformSetAttributeFunc)(SecTransformRef transform, - CFStringRef key, - CFTypeRef value, - CFErrorRef* error); - SecTransformSetAttributeFunc SecTransformSetAttributePtr = NULL; -} - -#define MAC_OS_X_VERSION_10_7_HEX 0x00001070 - -static int sOnLionOrLater = -1; - -static bool OnLionOrLater() -{ - if (sOnLionOrLater < 0) { - SInt32 major = 0, minor = 0; - - CFURLRef url = - CFURLCreateWithString(kCFAllocatorDefault, - CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"), - NULL); - CFReadStreamRef stream = - CFReadStreamCreateWithFile(kCFAllocatorDefault, url); - CFReadStreamOpen(stream); - CFDictionaryRef sysVersionPlist = (CFDictionaryRef) - CFPropertyListCreateWithStream(kCFAllocatorDefault, - stream, 0, kCFPropertyListImmutable, - NULL, NULL); - CFReadStreamClose(stream); - CFRelease(stream); - CFRelease(url); - - CFStringRef versionString = (CFStringRef) - CFDictionaryGetValue(sysVersionPlist, CFSTR("ProductVersion")); - CFArrayRef versions = - CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, - versionString, CFSTR(".")); - CFIndex count = CFArrayGetCount(versions); - if (count > 0) { - CFStringRef component = (CFStringRef) CFArrayGetValueAtIndex(versions, 0); - major = CFStringGetIntValue(component); - if (count > 1) { - component = (CFStringRef) CFArrayGetValueAtIndex(versions, 1); - minor = CFStringGetIntValue(component); - } - } - CFRelease(sysVersionPlist); - CFRelease(versions); - - if (major < 10) { - sOnLionOrLater = 0; - } else { - int version = 0x1000 + (minor << 4); - sOnLionOrLater = version >= MAC_OS_X_VERSION_10_7_HEX ? 1 : 0; - } - } - - return sOnLionOrLater > 0 ? true : false; -} - -static bool sCssmInitialized = false; -static CSSM_VERSION sCssmVersion = {2, 0}; -static const CSSM_GUID sMozCssmGuid = - { 0x9243121f, 0x5820, 0x4b41, - { 0xa6, 0x52, 0xba, 0xb6, 0x3f, 0x9d, 0x3d, 0x7f }}; -static CSSM_CSP_HANDLE sCspHandle = CSSM_INVALID_HANDLE; - -void* cssmMalloc (CSSM_SIZE aSize, void* aAllocRef) { - (void)aAllocRef; - return malloc(aSize); -} - -void cssmFree (void* aPtr, void* aAllocRef) { - (void)aAllocRef; - free(aPtr); - return; -} - -void* cssmRealloc (void* aPtr, CSSM_SIZE aSize, void* aAllocRef) { - (void)aAllocRef; - return realloc(aPtr, aSize); -} - -void* cssmCalloc (uint32 aNum, CSSM_SIZE aSize, void* aAllocRef) { - (void)aAllocRef; - return calloc(aNum, aSize); -} - -static CSSM_API_MEMORY_FUNCS cssmMemFuncs = { - &cssmMalloc, - &cssmFree, - &cssmRealloc, - &cssmCalloc, - NULL - }; - -CryptoX_Result -CryptoMac_InitCryptoProvider() -{ - if (!OnLionOrLater()) { - return CryptoX_Success; - } - - if (!SecTransformCreateReadTransformWithReadStreamPtr) { - SecTransformCreateReadTransformWithReadStreamPtr = - (SecTransformCreateReadTransformWithReadStreamFunc) - dlsym(RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream"); - } - if (!SecTransformExecutePtr) { - SecTransformExecutePtr = (SecTransformExecuteFunc) - dlsym(RTLD_DEFAULT, "SecTransformExecute"); - } - if (!SecVerifyTransformCreatePtr) { - SecVerifyTransformCreatePtr = (SecVerifyTransformCreateFunc) - dlsym(RTLD_DEFAULT, "SecVerifyTransformCreate"); - } - if (!SecTransformSetAttributePtr) { - SecTransformSetAttributePtr = (SecTransformSetAttributeFunc) - dlsym(RTLD_DEFAULT, "SecTransformSetAttribute"); - } - if (!SecTransformCreateReadTransformWithReadStreamPtr || - !SecTransformExecutePtr || - !SecVerifyTransformCreatePtr || - !SecTransformSetAttributePtr) { - return CryptoX_Error; - } - return CryptoX_Success; -} - -CryptoX_Result -CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData) -{ - if (!aInputData) { - return CryptoX_Error; - } - - void* inputData = CFDataCreateMutable(kCFAllocatorDefault, 0); - if (!inputData) { - return CryptoX_Error; - } - - if (!OnLionOrLater()) { - CSSM_DATA_PTR cssmData = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA)); - if (!cssmData) { - CFRelease(inputData); - return CryptoX_Error; - } - cssmData->Data = (uint8*)inputData; - cssmData->Length = 0; - *aInputData = cssmData; - return CryptoX_Success; - } - - *aInputData = inputData; - return CryptoX_Success; -} - -CryptoX_Result -CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, void* aBuf, - unsigned int aLen) -{ - if (aLen == 0) { - return CryptoX_Success; - } - if (!aInputData || !*aInputData) { - return CryptoX_Error; - } - - CFMutableDataRef inputData; - if (!OnLionOrLater()) { - inputData = (CFMutableDataRef)((CSSM_DATA_PTR)*aInputData)->Data; - ((CSSM_DATA_PTR)*aInputData)->Length += aLen; - } else { - inputData = (CFMutableDataRef)*aInputData; - } - - CFDataAppendBytes(inputData, (const uint8*)aBuf, aLen); - return CryptoX_Success; -} - -CryptoX_Result -CryptoMac_LoadPublicKey(const unsigned char* aCertData, - unsigned int aDataSize, - CryptoX_PublicKey* aPublicKey) -{ - if (!aCertData || aDataSize == 0 || !aPublicKey) { - return CryptoX_Error; - } - *aPublicKey = NULL; - - if (!OnLionOrLater()) { - if (!sCspHandle) { - CSSM_RETURN rv; - if (!sCssmInitialized) { - CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE; - rv = CSSM_Init(&sCssmVersion, - CSSM_PRIVILEGE_SCOPE_PROCESS, - &sMozCssmGuid, - CSSM_KEY_HIERARCHY_NONE, - &pvcPolicy, - NULL); - if (rv != CSSM_OK) { - return CryptoX_Error; - } - sCssmInitialized = true; - } - - rv = CSSM_ModuleLoad(&gGuidAppleCSP, - CSSM_KEY_HIERARCHY_NONE, - NULL, - NULL); - if (rv != CSSM_OK) { - return CryptoX_Error; - } - - CSSM_CSP_HANDLE cspHandle; - rv = CSSM_ModuleAttach(&gGuidAppleCSP, - &sCssmVersion, - &cssmMemFuncs, - 0, - CSSM_SERVICE_CSP, - 0, - CSSM_KEY_HIERARCHY_NONE, - NULL, - 0, - NULL, - &cspHandle); - if (rv != CSSM_OK) { - return CryptoX_Error; - } - sCspHandle = cspHandle; - } - } - - CFDataRef certData = CFDataCreate(kCFAllocatorDefault, - aCertData, - aDataSize); - if (!certData) { - return CryptoX_Error; - } - - SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, - certData); - CFRelease(certData); - if (!cert) { - return CryptoX_Error; - } - - OSStatus status = SecCertificateCopyPublicKey(cert, - (SecKeyRef*)aPublicKey); - CFRelease(cert); - if (status != 0) { - return CryptoX_Error; - } - - return CryptoX_Success; -} - -CryptoX_Result -CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData, - CryptoX_PublicKey* aPublicKey, - const unsigned char* aSignature, - unsigned int aSignatureLen) -{ - if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey || - !aSignature || aSignatureLen == 0) { - return CryptoX_Error; - } - - if (!OnLionOrLater()) { - if (!sCspHandle) { - return CryptoX_Error; - } - - CSSM_KEY* publicKey; - OSStatus status = SecKeyGetCSSMKey((SecKeyRef)*aPublicKey, - (const CSSM_KEY**)&publicKey); - if (status) { - return CryptoX_Error; - } - - CSSM_CC_HANDLE ccHandle; - if (CSSM_CSP_CreateSignatureContext(sCspHandle, - CSSM_ALGID_SHA1WithRSA, - NULL, - publicKey, - &ccHandle) != CSSM_OK) { - return CryptoX_Error; - } - - CryptoX_Result result = CryptoX_Error; - CSSM_DATA signatureData; - signatureData.Data = (uint8*)aSignature; - signatureData.Length = aSignatureLen; - CSSM_DATA inputData; - inputData.Data = - CFDataGetMutableBytePtr((CFMutableDataRef) - (((CSSM_DATA_PTR)*aInputData)->Data)); - inputData.Length = ((CSSM_DATA_PTR)*aInputData)->Length; - if (CSSM_VerifyData(ccHandle, - &inputData, - 1, - CSSM_ALGID_NONE, - &signatureData) == CSSM_OK) { - result = CryptoX_Success; - } - return result; - } - - CFDataRef signatureData = CFDataCreate(kCFAllocatorDefault, - aSignature, aSignatureLen); - if (!signatureData) { - return CryptoX_Error; - } - - CFErrorRef error; - SecTransformRef verifier = - SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey, - signatureData, - &error); - if (!verifier || error) { - CFRelease(signatureData); - return CryptoX_Error; - } - - SecTransformSetAttributePtr(verifier, - kSecTransformInputAttributeName, - (CFDataRef)*aInputData, - &error); - if (error) { - CFRelease(signatureData); - CFRelease(verifier); - return CryptoX_Error; - } - - CryptoX_Result result = CryptoX_Error; - CFTypeRef rv = SecTransformExecutePtr(verifier, &error); - if (error) { - CFRelease(signatureData); - CFRelease(verifier); - return CryptoX_Error; - } - - if (CFGetTypeID(rv) == CFBooleanGetTypeID() && - CFBooleanGetValue((CFBooleanRef)rv) == true) { - result = CryptoX_Success; - } - - CFRelease(signatureData); - CFRelease(verifier); - - return result; -} - -void -CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData) -{ - if (!aInputData || !*aInputData) { - return; - } - - CFMutableDataRef inputData = NULL; - if (OnLionOrLater()) { - inputData = (CFMutableDataRef)*aInputData; - } else { - inputData = (CFMutableDataRef)((CSSM_DATA_PTR)*aInputData)->Data; - } - - CFRelease(inputData); - if (!OnLionOrLater()) { - free((CSSM_DATA_PTR)*aInputData); - } -} - -void -CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey) -{ - if (!aPublicKey || !*aPublicKey) { - return; - } - if (!OnLionOrLater() && sCspHandle != CSSM_INVALID_HANDLE) { - CSSM_ModuleDetach(sCspHandle); - sCspHandle = CSSM_INVALID_HANDLE; - } - CFRelease((SecKeyRef)*aPublicKey); -} diff --git a/onlineupdate/source/libmar/verify/cryptox.c b/onlineupdate/source/libmar/verify/cryptox.c deleted file mode 100644 index 7cce8bf036fd..000000000000 --- a/onlineupdate/source/libmar/verify/cryptox.c +++ /dev/null @@ -1,282 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#endif - -#include <stdlib.h> -#include "cryptox.h" - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable: 4204) -#endif - -#if defined(MAR_NSS) - -/** - * Loads the public key for the specified cert name from the NSS store. - * - * @param certData The DER-encoded X509 certificate to extract the key from. - * @param certDataSize The size of certData. - * @param publicKey Out parameter for the public key to use. - * @return CryptoX_Success on success, CryptoX_Error on error. -*/ -CryptoX_Result -NSS_LoadPublicKey(const unsigned char *certData, unsigned int certDataSize, - SECKEYPublicKey **publicKey) -{ - CERTCertificate * cert; - SECItem certDataItem = { siBuffer, (unsigned char*) certData, certDataSize }; - - if (!certData || !publicKey) { - return CryptoX_Error; - } - - cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certDataItem, NULL, - PR_FALSE, PR_TRUE); - /* Get the cert and embedded public key out of the database */ - if (!cert) { - return CryptoX_Error; - } - *publicKey = CERT_ExtractPublicKey(cert); - CERT_DestroyCertificate(cert); - - if (!*publicKey) { - return CryptoX_Error; - } - return CryptoX_Success; -} - -CryptoX_Result -NSS_VerifyBegin(VFYContext **ctx, - SECKEYPublicKey * const *publicKey) -{ - SECStatus status; - if (!ctx || !publicKey || !*publicKey) { - return CryptoX_Error; - } - - /* Check that the key length is large enough for our requirements */ - if ((SECKEY_PublicKeyStrength(*publicKey) * 8) < - XP_MIN_SIGNATURE_LEN_IN_BYTES) { - fprintf(stderr, "ERROR: Key length must be >= %d bytes\n", - XP_MIN_SIGNATURE_LEN_IN_BYTES); - return CryptoX_Error; - } - - *ctx = VFY_CreateContext(*publicKey, NULL, - SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, NULL); - if (*ctx == NULL) { - return CryptoX_Error; - } - - status = VFY_Begin(*ctx); - return SECSuccess == status ? CryptoX_Success : CryptoX_Error; -} - -/** - * Verifies if a verify context matches the passed in signature. - * - * @param ctx The verify context that the signature should match. - * @param signature The signature to match. - * @param signatureLen The length of the signature. - * @return CryptoX_Success on success, CryptoX_Error on error. -*/ -CryptoX_Result -NSS_VerifySignature(VFYContext * const *ctx, - const unsigned char *signature, - unsigned int signatureLen) -{ - SECItem signedItem; - SECStatus status; - if (!ctx || !signature || !*ctx) { - return CryptoX_Error; - } - - signedItem.len = signatureLen; - signedItem.data = (unsigned char*)signature; - status = VFY_EndWithSignature(*ctx, &signedItem); - return SECSuccess == status ? CryptoX_Success : CryptoX_Error; -} - -#elif defined(WNT) -/** - * Verifies if a signature + public key matches a hash context. - * - * @param hash The hash context that the signature should match. - * @param pubKey The public key to use on the signature. - * @param signature The signature to check. - * @param signatureLen The length of the signature. - * @return CryptoX_Success on success, CryptoX_Error on error. -*/ -CryptoX_Result -CryptoAPI_VerifySignature(HCRYPTHASH *hash, - HCRYPTKEY *pubKey, - const BYTE *signature, - DWORD signatureLen) -{ - DWORD i; - BOOL result; -/* Windows APIs expect the bytes in the signature to be in little-endian - * order, but we write the signature in big-endian order. Other APIs like - * NSS and OpenSSL expect big-endian order. - */ - BYTE *signatureReversed; - if (!hash || !pubKey || !signature || signatureLen < 1) { - return CryptoX_Error; - } - - signatureReversed = malloc(signatureLen); - if (!signatureReversed) { - return CryptoX_Error; - } - - for (i = 0; i < signatureLen; i++) { - signatureReversed[i] = signature[signatureLen - 1 - i]; - } - result = CryptVerifySignature(*hash, signatureReversed, - signatureLen, *pubKey, NULL, 0); - free(signatureReversed); - return result ? CryptoX_Success : CryptoX_Error; -} - -/** - * Obtains the public key for the passed in cert data - * - * @param provider The crypto provider - * @param certData Data of the certificate to extract the public key from - * @param sizeOfCertData The size of the certData buffer - * @param certStore Pointer to the handle of the certificate store to use - * @param CryptoX_Success on success -*/ -CryptoX_Result -CryptoAPI_LoadPublicKey(HCRYPTPROV provider, - BYTE *certData, - DWORD sizeOfCertData, - HCRYPTKEY *publicKey) -{ - CRYPT_DATA_BLOB blob; - CERT_CONTEXT *context; - if (!provider || !certData || !publicKey) { - return CryptoX_Error; - } - - blob.cbData = sizeOfCertData; - blob.pbData = certData; - if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, - CERT_QUERY_CONTENT_FLAG_CERT, - CERT_QUERY_FORMAT_FLAG_BINARY, - 0, NULL, NULL, NULL, - NULL, NULL, (const void **)&context)) { - return CryptoX_Error; - } - - if (!CryptImportPublicKeyInfo(provider, - PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, - &context->pCertInfo->SubjectPublicKeyInfo, - publicKey)) { - CertFreeCertificateContext(context); - return CryptoX_Error; - } - - CertFreeCertificateContext(context); - return CryptoX_Success; -} - -/* Try to acquire context in this way: - * 1. Enhanced provider without creating a new key set - * 2. Enhanced provider with creating a new key set - * 3. Default provider without creating a new key set - * 4. Default provider without creating a new key set - * #2 and #4 should not be needed because of the CRYPT_VERIFYCONTEXT, - * but we add it just in case. - * - * @param provider Out parameter containing the provider handle. - * @return CryptoX_Success on success, CryptoX_Error on error. - */ -CryptoX_Result -CryptoAPI_InitCryptoContext(HCRYPTPROV *provider) -{ - if (!CryptAcquireContext(provider, - NULL, - MS_ENHANCED_PROV, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - if (!CryptAcquireContext(provider, - NULL, - MS_ENHANCED_PROV, - PROV_RSA_FULL, - CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) { - if (!CryptAcquireContext(provider, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - if (!CryptAcquireContext(provider, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) { - *provider = CryptoX_InvalidHandleValue; - return CryptoX_Error; - } - } - } - } - return CryptoX_Success; -} - -/** - * Begins a signature verification hash context - * - * @param provider The crypt provider to use - * @param hash Out parameter for a handle to the hash context - * @return CryptoX_Success on success, CryptoX_Error on error. -*/ -CryptoX_Result -CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash) -{ - BOOL result; - if (!provider || !hash) { - return CryptoX_Error; - } - - *hash = (HCRYPTHASH)NULL; - result = CryptCreateHash(provider, CALG_SHA1, - 0, 0, hash); - return result ? CryptoX_Success : CryptoX_Error; -} - -/** - * Updates a signature verification hash context - * - * @param hash The hash context to update - * @param buf The buffer to update the hash context with - * @param len The size of the passed in buffer - * @return CryptoX_Success on success, CryptoX_Error on error. -*/ -CryptoX_Result -CryptoAPI_VerifyUpdate(HCRYPTHASH* hash, BYTE *buf, DWORD len) -{ - BOOL result; - if (!hash || !buf) { - return CryptoX_Error; - } - - result = CryptHashData(*hash, buf, len, 0); - return result ? CryptoX_Success : CryptoX_Error; -} - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -#endif - - - diff --git a/onlineupdate/source/libmar/verify/cryptox.h b/onlineupdate/source/libmar/verify/cryptox.h deleted file mode 100644 index b0f00725fdf0..000000000000 --- a/onlineupdate/source/libmar/verify/cryptox.h +++ /dev/null @@ -1,172 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CRYPTOX_H -#define CRYPTOX_H - -#define XP_MIN_SIGNATURE_LEN_IN_BYTES 256 - -#define CryptoX_Result int -#define CryptoX_Success 0 -#define CryptoX_Error (-1) -#define CryptoX_Succeeded(X) ((X) == CryptoX_Success) -#define CryptoX_Failed(X) ((X) != CryptoX_Success) - -#if defined(MAR_NSS) - -#include "cert.h" -#include "keyhi.h" -#include "cryptohi.h" - -#define CryptoX_InvalidHandleValue NULL -#define CryptoX_ProviderHandle void* -#define CryptoX_SignatureHandle VFYContext * -#define CryptoX_PublicKey SECKEYPublicKey * -#define CryptoX_Certificate CERTCertificate * - -#ifdef __cplusplus -extern "C" { -#endif -CryptoX_Result NSS_LoadPublicKey(const unsigned char* certData, - unsigned int certDataSize, - SECKEYPublicKey** publicKey); -CryptoX_Result NSS_VerifyBegin(VFYContext **ctx, - SECKEYPublicKey * const *publicKey); -CryptoX_Result NSS_VerifySignature(VFYContext * const *ctx , - const unsigned char *signature, - unsigned int signatureLen); -#ifdef __cplusplus -} // extern "C" -#endif - -#define CryptoX_InitCryptoProvider(CryptoHandle) \ - CryptoX_Success -#define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ - NSS_VerifyBegin(SignatureHandle, PublicKey) -#define CryptoX_FreeSignatureHandle(SignatureHandle) \ - VFY_DestroyContext(*SignatureHandle, PR_TRUE) -#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \ - VFY_Update(*SignatureHandle, (const unsigned char*)(buf), len) -#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \ - NSS_LoadPublicKey(certData, dataSize, publicKey) -#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \ - NSS_VerifySignature(hash, (const unsigned char *)(signedData), len) -#define CryptoX_FreePublicKey(key) \ - SECKEY_DestroyPublicKey(*key) -#define CryptoX_FreeCertificate(cert) \ - CERT_DestroyCertificate(*cert) - -#elif defined(MACOSX) - -#define CryptoX_InvalidHandleValue NULL -#define CryptoX_ProviderHandle void* -#define CryptoX_SignatureHandle void* -#define CryptoX_PublicKey void* -#define CryptoX_Certificate void* - -// Forward-declare Objective-C functions implemented in MacVerifyCrypto.mm. -#ifdef __cplusplus -extern "C" { -#endif -CryptoX_Result CryptoMac_InitCryptoProvider(); -CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData); -CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, - void* aBuf, unsigned int aLen); -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); -void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData); -void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey); -#ifdef __cplusplus -} // extern "C" -#endif - -#define CryptoX_InitCryptoProvider(aProviderHandle) \ - CryptoMac_InitCryptoProvider() -#define CryptoX_VerifyBegin(aCryptoHandle, aInputData, aPublicKey) \ - CryptoMac_VerifyBegin(aInputData) -#define CryptoX_VerifyUpdate(aInputData, aBuf, aLen) \ - CryptoMac_VerifyUpdate(aInputData, aBuf, aLen) -#define CryptoX_LoadPublicKey(aProviderHandle, aCertData, aDataSize, \ - aPublicKey) \ - CryptoMac_LoadPublicKey(aCertData, aDataSize, aPublicKey) -#define CryptoX_VerifySignature(aInputData, aPublicKey, aSignature, \ - aSignatureLen) \ - CryptoMac_VerifySignature(aInputData, aPublicKey, aSignature, aSignatureLen) -#define CryptoX_FreeSignatureHandle(aInputData) \ - CryptoMac_FreeSignatureHandle(aInputData) -#define CryptoX_FreePublicKey(aPublicKey) \ - CryptoMac_FreePublicKey(aPublicKey) -#define CryptoX_FreeCertificate(aCertificate) - -#elif defined(WNT) - -#include <windows.h> -#include <wincrypt.h> - -CryptoX_Result CryptoAPI_InitCryptoContext(HCRYPTPROV *provider); -CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV hProv, - BYTE *certData, - DWORD sizeOfCertData, - HCRYPTKEY *publicKey); -CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash); -CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH* hash, - BYTE *buf, DWORD len); -CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash, - HCRYPTKEY *pubKey, - const BYTE *signature, - DWORD signatureLen); - -#define CryptoX_InvalidHandleValue ((ULONG_PTR)NULL) -#define CryptoX_ProviderHandle HCRYPTPROV -#define CryptoX_SignatureHandle HCRYPTHASH -#define CryptoX_PublicKey HCRYPTKEY -#define CryptoX_Certificate HCERTSTORE -#define CryptoX_InitCryptoProvider(CryptoHandle) \ - CryptoAPI_InitCryptoContext(CryptoHandle) -#define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ - CryptoAPI_VerifyBegin(CryptoHandle, SignatureHandle) -#define CryptoX_FreeSignatureHandle(SignatureHandle) -#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \ - CryptoAPI_VerifyUpdate(SignatureHandle, (BYTE *)(buf), len) -#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \ - CryptoAPI_LoadPublicKey(CryptoHandle, (BYTE*)(certData), dataSize, publicKey) -#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \ - CryptoAPI_VerifySignature(hash, publicKey, signedData, len) -#define CryptoX_FreePublicKey(key) \ - CryptDestroyKey(*(key)) -#define CryptoX_FreeCertificate(cert) \ - CertCloseStore(*(cert), CERT_CLOSE_STORE_FORCE_FLAG); - -#else - -/* This default implementation is necessary because we don't want to - * link to NSS from updater code on non Windows platforms. On Windows - * we use CryptoAPI instead of NSS. We don't call any function as they - * would just fail, but this simplifies linking. - */ - -#define CryptoX_InvalidHandleValue NULL -#define CryptoX_ProviderHandle void* -#define CryptoX_SignatureHandle void* -#define CryptoX_PublicKey void* -#define CryptoX_Certificate void* -#define CryptoX_InitCryptoProvider(CryptoHandle) \ - CryptoX_Error -#define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ - CryptoX_Error -#define CryptoX_FreeSignatureHandle(SignatureHandle) -#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) CryptoX_Error -#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \ - CryptoX_Error -#define CryptoX_VerifySignature(hash, publicKey, signedData, len) CryptoX_Error -#define CryptoX_FreePublicKey(key) CryptoX_Error - -#endif - -#endif diff --git a/onlineupdate/source/libmar/verify/mar_verify.c b/onlineupdate/source/libmar/verify/mar_verify.c deleted file mode 100644 index 9f33f8badd3e..000000000000 --- a/onlineupdate/source/libmar/verify/mar_verify.c +++ /dev/null @@ -1,466 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <onlineupdate/mar_private.h> -#include <onlineupdate/mar.h> -#include "cryptox.h" - -int -mar_read_entire_file(const char * filePath, uint32_t maxSize, - /*out*/ const uint8_t * *data, - /*out*/ uint32_t *size) -{ - int result; - FILE * f; - - if (!filePath || !data || !size) { - return -1; - } - - f = fopen(filePath, "rb"); - if (!f) { - return -1; - } - - result = -1; - if (!fseeko(f, 0, SEEK_END)) { - int64_t fileSize = ftello(f); - if (fileSize > 0 && fileSize <= maxSize && !fseeko(f, 0, SEEK_SET)) { - unsigned char * fileData; - - *size = (unsigned int) fileSize; - fileData = malloc(*size); - if (fileData) { - if (fread(fileData, *size, 1, f) == 1) { - *data = fileData; - result = 0; - } else { - free(fileData); - } - } - } - } - - fclose(f); - - return result; -} - -int mar_extract_and_verify_signatures_fp(FILE *fp, - CryptoX_ProviderHandle provider, - CryptoX_PublicKey *keys, - uint32_t keyCount); -int mar_verify_signatures_for_fp(FILE *fp, - CryptoX_ProviderHandle provider, - CryptoX_PublicKey *keys, - const uint8_t * const *extractedSignatures, - uint32_t keyCount, - uint32_t *numVerified); - -/** - * Reads the specified number of bytes from the file pointer and - * stores them in the passed buffer. - * - * @param fp The file pointer to read from. - * @param buffer The buffer to store the read results. - * @param size The number of bytes to read, buffer must be - * at least of this size. - * @param ctxs Pointer to the first element in an array of verify context. - * @param count The number of elements in ctxs - * @param err The name of what is being written to in case of error. - * @return 0 on success - * -1 on read error - * -2 on verify update error -*/ -int -ReadAndUpdateVerifyContext(FILE *fp, - void *buffer, - uint32_t size, - CryptoX_SignatureHandle *ctxs, - uint32_t count, - const char *err) -{ - uint32_t k; - if (!fp || !buffer || !ctxs || count == 0 || !err) { - fprintf(stderr, "ERROR: Invalid parameter specified.\n"); - return CryptoX_Error; - } - - if (!size) { - return CryptoX_Success; - } - - if (fread(buffer, size, 1, fp) != 1) { - fprintf(stderr, "ERROR: Could not read %s\n", err); - return CryptoX_Error; - } - - for (k = 0; k < count; k++) { - if (CryptoX_Failed(CryptoX_VerifyUpdate(&ctxs[k], buffer, size))) { - fprintf(stderr, "ERROR: Could not update verify context for %s\n", err); - return -2; - } - } - return CryptoX_Success; -} - -/** - * Verifies a MAR file by verifying each signature with the corresponding - * certificate. That is, the first signature will be verified using the first - * certificate given, the second signature will be verified using the second - * certificate given, etc. The signature count must exactly match the number of - * certificates given, and all signature verifications must succeed. - * - * @param mar The file who's signature should be calculated - * @param certData Pointer to the first element in an array of - * certificate data - * @param certDataSizes Pointer to the first element in an array for size of - * the data stored - * @param certCount The number of elements in certData and certDataSizes - * @return 0 on success -*/ -int -mar_verify_signatures(MarFile *mar, - const uint8_t * const *certData, - const uint32_t *certDataSizes, - uint32_t certCount) { - int rv = -1; - CryptoX_ProviderHandle provider = CryptoX_InvalidHandleValue; - CryptoX_PublicKey keys[MAX_SIGNATURES]; - uint32_t k; - - memset(keys, 0, sizeof(keys)); - - if (!mar || !certData || !certDataSizes || certCount == 0) { - fprintf(stderr, "ERROR: Invalid parameter specified.\n"); - goto failure; - } - - if (!mar->fp) { - fprintf(stderr, "ERROR: MAR file is not open.\n"); - goto failure; - } - - if (CryptoX_Failed(CryptoX_InitCryptoProvider(&provider))) { - fprintf(stderr, "ERROR: Could not init crypto library.\n"); - goto failure; - } - - for (k = 0; k < certCount; ++k) { - if (CryptoX_Failed(CryptoX_LoadPublicKey(provider, certData[k], certDataSizes[k], - &keys[k]))) { - fprintf(stderr, "ERROR: Could not load public key.\n"); - goto failure; - } - } - - rv = mar_extract_and_verify_signatures_fp(mar->fp, provider, keys, certCount); - -failure: - - for (k = 0; k < certCount; ++k) { - if (keys[k]) { - CryptoX_FreePublicKey(&keys[k]); - } - } - - return rv; -} - -/** - * Extracts each signature from the specified MAR file, - * then calls mar_verify_signatures_for_fp to verify each signature. - * - * @param fp An opened MAR file handle - * @param provider A library provider - * @param keys The public keys to use to verify the MAR - * @param keyCount The number of keys pointed to by keys - * @return 0 on success -*/ -int -mar_extract_and_verify_signatures_fp(FILE *fp, - CryptoX_ProviderHandle provider, - CryptoX_PublicKey *keys, - uint32_t keyCount) { - uint32_t signatureCount, signatureLen, numVerified = 0; - uint32_t signatureAlgorithmIDs[MAX_SIGNATURES]; - int rv = -1; - uint8_t *extractedSignatures[MAX_SIGNATURES]; - uint32_t i; - - memset(signatureAlgorithmIDs, 0, sizeof(signatureAlgorithmIDs)); - memset(extractedSignatures, 0, sizeof(extractedSignatures)); - - if (!fp) { - fprintf(stderr, "ERROR: Invalid file pointer passed.\n"); - return CryptoX_Error; - } - - /* To protect against invalid MAR files, we assume that the MAR file - size is less than or equal to MAX_SIZE_OF_MAR_FILE. */ - if (fseeko(fp, 0, SEEK_END)) { - fprintf(stderr, "ERROR: Could not seek to the end of the MAR file.\n"); - return CryptoX_Error; - } - if (ftello(fp) > MAX_SIZE_OF_MAR_FILE) { - fprintf(stderr, "ERROR: MAR file is too large to be verified.\n"); - return CryptoX_Error; - } - - /* Skip to the start of the signature block */ - if (fseeko(fp, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek to the signature block.\n"); - return CryptoX_Error; - } - - /* Get the number of signatures */ - if (fread(&signatureCount, sizeof(signatureCount), 1, fp) != 1) { - fprintf(stderr, "ERROR: Could not read number of signatures.\n"); - return CryptoX_Error; - } - signatureCount = ntohl(signatureCount); - - /* Check that we have less than the max amount of signatures so we don't - waste too much of either updater's or signmar's time. */ - if (signatureCount > MAX_SIGNATURES) { - fprintf(stderr, "ERROR: At most %d signatures can be specified.\n", - MAX_SIGNATURES); - return CryptoX_Error; - } - - for (i = 0; i < signatureCount; i++) { - /* Get the signature algorithm ID */ - if (fread(&signatureAlgorithmIDs[i], sizeof(uint32_t), 1, fp) != 1) { - fprintf(stderr, "ERROR: Could not read signatures algorithm ID.\n"); - return CryptoX_Error; - } - signatureAlgorithmIDs[i] = ntohl(signatureAlgorithmIDs[i]); - - if (fread(&signatureLen, sizeof(uint32_t), 1, fp) != 1) { - fprintf(stderr, "ERROR: Could not read signatures length.\n"); - return CryptoX_Error; - } - signatureLen = ntohl(signatureLen); - - /* To protected against invalid input make sure the signature length - isn't too big. */ - if (signatureLen > MAX_SIGNATURE_LENGTH) { - fprintf(stderr, "ERROR: Signature length is too large to verify.\n"); - return CryptoX_Error; - } - - extractedSignatures[i] = malloc(signatureLen); - if (!extractedSignatures[i]) { - fprintf(stderr, "ERROR: Could allocate buffer for signature.\n"); - return CryptoX_Error; - } - if (fread(extractedSignatures[i], signatureLen, 1, fp) != 1) { - fprintf(stderr, "ERROR: Could not read extracted signature.\n"); - for (i = 0; i < signatureCount; ++i) { - free(extractedSignatures[i]); - } - return CryptoX_Error; - } - - /* We don't try to verify signatures we don't know about */ - if (signatureAlgorithmIDs[i] != 1) { - fprintf(stderr, "ERROR: Unknown signature algorithm ID.\n"); - for (i = 0; i < signatureCount; ++i) { - free(extractedSignatures[i]); - } - return CryptoX_Error; - } - } - - rv = mar_verify_signatures_for_fp(fp, - provider, - keys, - (const uint8_t * const *)extractedSignatures, - signatureCount, - &numVerified); - for (i = 0; i < signatureCount; ++i) { - free(extractedSignatures[i]); - } - - /* If we reached here and we verified every - signature, return success. */ - if (numVerified == signatureCount && keyCount == numVerified) { - assert(rv == 0); (void) rv; - return CryptoX_Success; - } - - if (numVerified == 0) { - fprintf(stderr, "ERROR: Not all signatures were verified.\n"); - } else { - fprintf(stderr, "ERROR: Only %d of %d signatures were verified.\n", - numVerified, signatureCount); - } - return CryptoX_Error; -} - -/** - * Verifies a MAR file by verifying each signature with the corresponding - * certificate. That is, the first signature will be verified using the first - * certificate given, the second signature will be verified using the second - * certificate given, etc. The signature count must exactly match the number of - * certificates given, and all signature verifications must succeed. - * - * @param fp An opened MAR file handle - * @param provider A library provider - * @param keys A pointer to the first element in an - * array of keys. - * @param extractedSignatures Pointer to the first element in an array - * of extracted signatures. - * @param signatureCount The number of signatures in the MAR file - * @param numVerified Out parameter which will be filled with - * the number of verified signatures. - * This information can be useful for printing - * error messages. - * @return 0 on success, *numVerified == signatureCount. -*/ -int -mar_verify_signatures_for_fp(FILE *fp, - CryptoX_ProviderHandle provider, - CryptoX_PublicKey *keys, - const uint8_t * const *extractedSignatures, - uint32_t signatureCount, - uint32_t *numVerified) -{ - CryptoX_SignatureHandle signatureHandles[MAX_SIGNATURES]; - char buf[BLOCKSIZE]; - uint32_t signatureLengths[MAX_SIGNATURES]; - uint32_t i; - int rv = CryptoX_Error; - - (void) provider; (void) keys; // avoid warnings - - memset(signatureHandles, 0, sizeof(signatureHandles)); - memset(signatureLengths, 0, sizeof(signatureLengths)); - - if (!extractedSignatures || !numVerified) { - fprintf(stderr, "ERROR: Invalid parameter specified.\n"); - goto failure; - } - - *numVerified = 0; - - /* This function is only called when we have at least one signature, - but to protected against future people who call this function we - make sure a non zero value is passed in. - */ - if (!signatureCount) { - fprintf(stderr, "ERROR: There must be at least one signature.\n"); - goto failure; - } - - for (i = 0; i < signatureCount; i++) { - if (CryptoX_Failed(CryptoX_VerifyBegin(provider, - &signatureHandles[i], &keys[i]))) { - fprintf(stderr, "ERROR: Could not initialize signature handle.\n"); - goto failure; - } - } - - /* Skip to the start of the file */ - if (fseeko(fp, 0, SEEK_SET)) { - fprintf(stderr, "ERROR: Could not seek to start of the file\n"); - goto failure; - } - - /* Bytes 0-3: MAR1 - Bytes 4-7: index offset - Bytes 8-15: size of entire MAR - */ - if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp, buf, - SIGNATURE_BLOCK_OFFSET + - sizeof(uint32_t), - signatureHandles, - signatureCount, - "signature block"))) { - goto failure; - } - - /* Read the signature block */ - for (i = 0; i < signatureCount; i++) { - /* Get the signature algorithm ID */ - if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp, - &buf, - sizeof(uint32_t), - signatureHandles, - signatureCount, - "signature algorithm ID"))) { - goto failure; - } - - if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp, - &signatureLengths[i], - sizeof(uint32_t), - signatureHandles, - signatureCount, - "signature length"))) { - goto failure; - } - signatureLengths[i] = ntohl(signatureLengths[i]); - if (signatureLengths[i] > MAX_SIGNATURE_LENGTH) { - fprintf(stderr, "ERROR: Embedded signature length is too large.\n"); - goto failure; - } - - /* Skip past the signature itself as those are not included */ - if (fseeko(fp, signatureLengths[i], SEEK_CUR)) { - fprintf(stderr, "ERROR: Could not seek past signature.\n"); - goto failure; - } - } - - /* Read the rest of the file after the signature block */ - while (!feof(fp)) { - int numRead = fread(buf, 1, BLOCKSIZE , fp); - if (ferror(fp)) { - fprintf(stderr, "ERROR: Error reading data block.\n"); - goto failure; - } - - for (i = 0; i < signatureCount; i++) { - if (CryptoX_Failed(CryptoX_VerifyUpdate(&signatureHandles[i], - buf, numRead))) { - fprintf(stderr, "ERROR: Error updating verify context with" - " data block.\n"); - goto failure; - } - } - } - - /* Verify the signatures */ - for (i = 0; i < signatureCount; i++) { - if (CryptoX_Failed(CryptoX_VerifySignature(&signatureHandles[i], - &keys[i], - extractedSignatures[i], - signatureLengths[i]))) { - fprintf(stderr, "ERROR: Error verifying signature.\n"); - goto failure; - } - ++*numVerified; - } - - rv = CryptoX_Success; -failure: - for (i = 0; i < signatureCount; i++) { - CryptoX_FreeSignatureHandle(&signatureHandles[i]); - } - - return rv; -} diff --git a/onlineupdate/source/mbsdiff/bsdiff.cxx b/onlineupdate/source/mbsdiff/bsdiff.cxx deleted file mode 100644 index 72bbcde1899f..000000000000 --- a/onlineupdate/source/mbsdiff/bsdiff.cxx +++ /dev/null @@ -1,405 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - bsdiff.c -- Binary patch generator. - - Copyright 2003 Colin Percival - - For the terms under which this work may be distributed, please see - the adjoining file "LICENSE". - - ChangeLog: - 2005-05-05 - Use the modified header struct from bspatch.h; use 32-bit - values throughout. - --Benjamin Smedberg <benjamin@smedbergs.us> - 2005-05-18 - Use the same CRC algorithm as bzip2, and leverage the CRC table - provided by libbz2. - --Darin Fisher <darin@meer.net> -*/ - -#include "bspatch.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <stdarg.h> -#ifdef _WIN32 -#include <io.h> -#include <winsock2.h> -#else -#include <unistd.h> -#include <arpa/inet.h> -#define _O_BINARY 0 -#endif - -#undef MIN -#define MIN(x,y) (((x)<(y)) ? (x) : (y)) - -/*---------------------------------------------------------------------------*/ - -/* This variable lives in libbz2. It's declared in bzlib_private.h, so we just - * declare it here to avoid including that entire header file. - */ -extern "C" unsigned int BZ2_crc32Table[256]; - -static unsigned int -crc32(const unsigned char *buf, unsigned int len) -{ - unsigned int crc = 0xffffffffL; - - const unsigned char *end = buf + len; - for (; buf != end; ++buf) - crc = (crc << 8) ^ BZ2_crc32Table[(crc >> 24) ^ *buf]; - - crc = ~crc; - return crc; -} - -/*---------------------------------------------------------------------------*/ - -static void -reporterr(int e, const char *fmt, ...) -{ - if (fmt) { - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - } - - exit(e); -} - -static void -split(int32_t *I,int32_t *V,int32_t start,int32_t len,int32_t h) -{ - int32_t i,j,k,x,tmp,jj,kk; - - if(len<16) { - for(k=start;k<start+len;k+=j) { - j=1;x=V[I[k]+h]; - for(i=1;k+i<start+len;i++) { - if(V[I[k+i]+h]<x) { - x=V[I[k+i]+h]; - j=0; - }; - if(V[I[k+i]+h]==x) { - tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp; - j++; - }; - }; - for(i=0;i<j;i++) V[I[k+i]]=k+j-1; - if(j==1) I[k]=-1; - }; - return; - }; - - x=V[I[start+len/2]+h]; - jj=0;kk=0; - for(i=start;i<start+len;i++) { - if(V[I[i]+h]<x) jj++; - if(V[I[i]+h]==x) kk++; - }; - jj+=start;kk+=jj; - - i=start;j=0;k=0; - while(i<jj) { - if(V[I[i]+h]<x) { - i++; - } else if(V[I[i]+h]==x) { - tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp; - j++; - } else { - tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp; - k++; - }; - }; - - while(jj+j<kk) { - if(V[I[jj+j]+h]==x) { - j++; - } else { - tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp; - k++; - }; - }; - - if(jj>start) split(I,V,start,jj-start,h); - - for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1; - if(jj==kk-1) I[jj]=-1; - - if(start+len>kk) split(I,V,kk,start+len-kk,h); -} - -static void -qsufsort(int32_t *I,int32_t *V,unsigned char *old,int32_t oldsize) -{ - int32_t buckets[256]; - int32_t i,h,len; - - for(i=0;i<256;i++) buckets[i]=0; - for(i=0;i<oldsize;i++) buckets[old[i]]++; - for(i=1;i<256;i++) buckets[i]+=buckets[i-1]; - for(i=255;i>0;i--) buckets[i]=buckets[i-1]; - buckets[0]=0; - - for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i; - I[0]=oldsize; - for(i=0;i<oldsize;i++) V[i]=buckets[old[i]]; - V[oldsize]=0; - for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1; - I[0]=-1; - - for(h=1;I[0]!=-(oldsize+1);h+=h) { - len=0; - for(i=0;i<oldsize+1;) { - if(I[i]<0) { - len-=I[i]; - i-=I[i]; - } else { - if(len) I[i-len]=-len; - len=V[I[i]]+1-i; - split(I,V,i,len,h); - i+=len; - len=0; - }; - }; - if(len) I[i-len]=-len; - }; - - for(i=0;i<oldsize+1;i++) I[V[i]]=i; -} - -static int32_t -matchlen(unsigned char *old,int32_t oldsize,unsigned char *newbuf,int32_t newsize) -{ - int32_t i; - - for(i=0;(i<oldsize)&&(i<newsize);i++) - if(old[i]!=newbuf[i]) break; - - return i; -} - -static int32_t -search(int32_t *I,unsigned char *old,int32_t oldsize, - unsigned char *newbuf,int32_t newsize,int32_t st,int32_t en,int32_t *pos) -{ - int32_t x,y; - - if(en-st<2) { - x=matchlen(old+I[st],oldsize-I[st],newbuf,newsize); - y=matchlen(old+I[en],oldsize-I[en],newbuf,newsize); - - if(x>y) { - *pos=I[st]; - return x; - } else { - *pos=I[en]; - return y; - } - }; - - x=st+(en-st)/2; - if(memcmp(old+I[x],newbuf,MIN(oldsize-I[x],newsize))<0) { - return search(I,old,oldsize,newbuf,newsize,x,en,pos); - } else { - return search(I,old,oldsize,newbuf,newsize,st,x,pos); - }; -} - -int main(int argc,char *argv[]) -{ - int fd; - unsigned char *old = nullptr,*newbuf = nullptr; - int32_t oldsize = 0, newsize = 0; - int32_t *I = nullptr,*V = nullptr; - - int32_t scan,pos = 0,len; - int32_t lastscan,lastpos,lastoffset; - int32_t oldscore,scsc; - - int32_t s,Sf,lenf,Sb,lenb; - int32_t overlap,Ss,lens; - int32_t i; - - int32_t dblen,eblen; - unsigned char *db,*eb = nullptr; - - unsigned int scrc; - - MBSPatchHeader header = { - {'M','B','D','I','F','F','1','0'}, - 0, 0, 0, 0, 0, 0 - }; - - uint32_t numtriples; - - if(argc!=4) - reporterr(1,"usage: %s <oldfile> <newfile> <patchfile>\n",argv[0]); - - /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if(((fd=open(argv[1],O_RDONLY|_O_BINARY,0))<0) || - ((oldsize=lseek(fd,0,SEEK_END))==-1) || - ((old=(unsigned char*) malloc(oldsize+1))==NULL) || - (lseek(fd,0,SEEK_SET)!=0) || - (read(fd,old,oldsize)!=oldsize) || - (close(fd)==-1)) - reporterr(1,"%s\n",argv[1]); - - scrc = crc32(old, oldsize); - - if(((I=(int32_t*) malloc((oldsize+1)*sizeof(int32_t)))==NULL) || - ((V=(int32_t*) malloc((oldsize+1)*sizeof(int32_t)))==NULL)) - reporterr(1,NULL); - - qsufsort(I,V,old,oldsize); - - free(V); - - /* Allocate newsize+1 bytes instead of newsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if(((fd=open(argv[2],O_RDONLY|_O_BINARY,0))<0) || - ((newsize=lseek(fd,0,SEEK_END))==-1) || - ((newbuf=(unsigned char*) malloc(newsize+1))==NULL) || - (lseek(fd,0,SEEK_SET)!=0) || - (read(fd,newbuf,newsize)!=newsize) || - (close(fd)==-1)) reporterr(1,"%s\n",argv[2]); - - if(((db=(unsigned char*) malloc(newsize+1))==NULL) || - ((eb=(unsigned char*) malloc(newsize+1))==NULL)) - reporterr(1,NULL); - - dblen=0; - eblen=0; - - if((fd=open(argv[3],O_CREAT|O_TRUNC|O_WRONLY|_O_BINARY,0666))<0) - reporterr(1,"%s\n",argv[3]); - - /* start writing here */ - - /* We don't know the lengths yet, so we will write the header again - at the end */ - - if(write(fd,&header,sizeof(MBSPatchHeader))!=sizeof(MBSPatchHeader)) - reporterr(1,"%s\n",argv[3]); - - scan=0;len=0; - lastscan=0;lastpos=0;lastoffset=0; - numtriples = 0; - while(scan<newsize) { - oldscore=0; - - for(scsc=scan+=len;scan<newsize;scan++) { - len=search(I,old,oldsize,newbuf+scan,newsize-scan, - 0,oldsize,&pos); - - for(;scsc<scan+len;scsc++) - if((scsc+lastoffset<oldsize) && - (old[scsc+lastoffset] == newbuf[scsc])) - oldscore++; - - if(((len==oldscore) && (len!=0)) || - (len>oldscore+8)) break; - - if((scan+lastoffset<oldsize) && - (old[scan+lastoffset] == newbuf[scan])) - oldscore--; - }; - - if((len!=oldscore) || (scan==newsize)) { - MBSPatchTriple triple; - - s=0;Sf=0;lenf=0; - for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) { - if(old[lastpos+i]==newbuf[lastscan+i]) s++; - i++; - if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; }; - }; - - lenb=0; - if(scan<newsize) { - s=0;Sb=0; - for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) { - if(old[pos-i]==newbuf[scan-i]) s++; - if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; - }; - }; - - if(lastscan+lenf>scan-lenb) { - overlap=(lastscan+lenf)-(scan-lenb); - s=0;Ss=0;lens=0; - for(i=0;i<overlap;i++) { - if(newbuf[lastscan+lenf-overlap+i]== - old[lastpos+lenf-overlap+i]) s++; - if(newbuf[scan-lenb+i]== - old[pos-lenb+i]) s--; - if(s>Ss) { Ss=s; lens=i+1; }; - }; - - lenf+=lens-overlap; - lenb-=lens; - }; - - for(i=0;i<lenf;i++) - db[dblen+i]=newbuf[lastscan+i]-old[lastpos+i]; - for(i=0;i<(scan-lenb)-(lastscan+lenf);i++) - eb[eblen+i]=newbuf[lastscan+lenf+i]; - - dblen+=lenf; - eblen+=(scan-lenb)-(lastscan+lenf); - - triple.x = htonl(lenf); - triple.y = htonl((scan-lenb)-(lastscan+lenf)); - triple.z = htonl((pos-lenb)-(lastpos+lenf)); - if (write(fd,&triple,sizeof(triple)) != sizeof(triple)) - reporterr(1,NULL); - -#ifdef DEBUG_bsmedberg - printf("Writing a block:\n" - " X: %u\n" - " Y: %u\n" - " Z: %i\n", - (uint32_t) lenf, - (uint32_t) ((scan-lenb)-(lastscan+lenf)), - (uint32_t) ((pos-lenb)-(lastpos+lenf))); -#endif - - ++numtriples; - - lastscan=scan-lenb; - lastpos=pos-lenb; - lastoffset=pos-scan; - }; - }; - - if(write(fd,db,dblen)!=dblen) - reporterr(1,NULL); - - if(write(fd,eb,eblen)!=eblen) - reporterr(1,NULL); - - header.slen = htonl(oldsize); - header.scrc32 = htonl(scrc); - header.dlen = htonl(newsize); - header.cblen = htonl(numtriples * sizeof(MBSPatchTriple)); - header.difflen = htonl(dblen); - header.extralen = htonl(eblen); - - if (lseek(fd,0,SEEK_SET) == -1 || - write(fd,&header,sizeof(header)) != sizeof(header) || - close(fd) == -1) - reporterr(1,NULL); - - free(db); - free(eb); - free(I); - free(old); - free(newbuf); - - return 0; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/onlineupdate/source/service/certificatecheck.cxx b/onlineupdate/source/service/certificatecheck.cxx deleted file mode 100644 index 58d70162f40c..000000000000 --- a/onlineupdate/source/service/certificatecheck.cxx +++ /dev/null @@ -1,292 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <windows.h> -#include <softpub.h> -#include <wintrust.h> - -#include "certificatecheck.hxx" -#include "servicebase.hxx" - -#pragma comment(lib, "wintrust.lib") -#pragma comment(lib, "crypt32.lib") - -static const int ENCODING = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; - -/** - * Checks to see if a file stored at filePath matches the specified info. - * - * @param filePath The PE file path to check - * @param infoToMatch The acceptable information to match - * @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info - * does not match, or the last error otherwise. - */ -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; - - // 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; - } - - // 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; - } - - // 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; - } - -cleanup: - if (signerInfo) - { - LocalFree(signerInfo); - } - if (certContext) - { - CertFreeCertificateContext(certContext); - } - if (certStore) - { - CertCloseStore(certStore, 0); - } - if (cryptMsg) - { - CryptMsgClose(cryptMsg); - } - return lastError; -} - -/** - * Checks to see if a file stored at filePath matches the specified info. - * - * @param certContext The certificate context of the file - * @param infoToMatch The acceptable information to match - * @return FALSE if the info does not match or if any error occurs in the check - */ -BOOL -DoCertificateAttributesMatch(PCCERT_CONTEXT certContext, - CertificateCheckInfo &infoToMatch) -{ - 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 (!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; - } - - // 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; - } - - 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; - } - - // 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; - } - - // 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); - } - - // If there were any errors we would have aborted by now. - return TRUE; -} - -/** - * Duplicates the specified string - * - * @param inputString The string to duplicate - * @return The duplicated string which should be freed by the caller. - */ -LPWSTR -AllocateAndCopyWideString(LPCWSTR inputString) -{ - LPWSTR outputString = - (LPWSTR)LocalAlloc(LPTR, (wcslen(inputString) + 1) * sizeof(WCHAR)); - if (outputString) - { - lstrcpyW(outputString, inputString); - } - return outputString; -} - -/** - * Verifies the trust of the specified file path. - * - * @param filePath The file path to check. - * @return ERROR_SUCCESS if successful, or the last error code otherwise. - */ -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 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; - } - - 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 deleted file mode 100644 index 1efbcb153a65..000000000000 --- a/onlineupdate/source/service/certificatecheck.hxx +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _CERTIFICATECHECK_H_ -#define _CERTIFICATECHECK_H_ - -#include <wincrypt.h> - -struct CertificateCheckInfo -{ - LPCWSTR name; - LPCWSTR issuer; -}; - -BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT pCertContext, - CertificateCheckInfo &infoToMatch); -DWORD VerifyCertificateTrustForFile(LPCWSTR filePath); -DWORD CheckCertificateForPEFile(LPCWSTR filePath, - CertificateCheckInfo &infoToMatch); - -#endif diff --git a/onlineupdate/source/service/maintenanceservice.cxx b/onlineupdate/source/service/maintenanceservice.cxx deleted file mode 100644 index da324de54df3..000000000000 --- a/onlineupdate/source/service/maintenanceservice.cxx +++ /dev/null @@ -1,438 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <windows.h> -#include <shlwapi.h> -#include <stdio.h> -#include <wchar.h> -#include <shlobj.h> - -#include "serviceinstall.hxx" -#include "maintenanceservice.hxx" -#include "servicebase.hxx" -#include "workmonitor.hxx" -#include "uachelper.h" -#include "updatehelper.h" - -// Link w/ subsystem window so we don't get a console when executing -// this binary through the installer. -#pragma comment(linker, "/SUBSYSTEM:windows") - -SERVICE_STATUS gSvcStatus = { 0 }; -SERVICE_STATUS_HANDLE gSvcStatusHandle = nullptr; -HANDLE gWorkDoneEvent = nullptr; -HANDLE gThread = nullptr; -bool gServiceControlStopping = false; - -// logs are pretty small, about 20 lines, so 10 seems reasonable. -#define LOGS_TO_KEEP 10 - -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"); - } - - 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; - } - - 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; - } - - 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; -} - -/** - * Obtains the base path where logs should be stored - * - * @param path The out buffer for the backup log path of size MAX_PATH + 1 - * @return TRUE if successful. - */ -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; -} - -/** - * Calculated a backup path based on the log number. - * - * @param path The out buffer to store the log path of size MAX_PATH + 1 - * @param basePath The base directory where the calculated path should go - * @param logNumber The log number, 0 == updater.log - * @return TRUE if successful. - */ -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); -} - -/** - * Moves the old log files out of the way before a new one is written. - * If you for example keep 3 logs, then this function will do: - * updater2.log -> updater3.log - * updater1.log -> updater2.log - * updater.log -> updater1.log - * Which clears room for a new updater.log in the basePath directory - * - * @param basePath The base directory path where log files are stored - * @param numLogsToKeep The number of logs to keep - */ -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; - } - - if (!MoveFileExW(oldPath, newPath, MOVEFILE_REPLACE_EXISTING)) - { - continue; - } - } -} - -/** - * Ensures the service is shutdown once all work is complete. - * There is an issue on XP SP2 and below where the service can hang - * in a stop pending state even though the SCM is notified of a stopped - * state. Control *should* be returned to StartServiceCtrlDispatcher from the - * call to SetServiceStatus on a stopped state in the wmain thread. - * Sometimes this is not the case though. This thread will terminate the process - * if it has been 5 seconds after all work is done and the process is still not - * terminated. This thread is only started once a stopped state was sent to the - * SCM. The stop pending hang can be reproduced intermittently even if you set - * a stopped state directly and never set a stop pending state. It is safe to - * forcefully terminate the process ourselves since all work is done once we - * start this thread. -*/ -DWORD WINAPI -EnsureProcessTerminatedThread(LPVOID) -{ - 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); - } -} - -/** - * Main entry point when running as a service. - */ -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; - - // 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 command 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); - - // 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); - - // 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(); - } -} - -/** - * Sets the current service status and reports it to the SCM. - * - * @param currentState The current state (see SERVICE_STATUS) - * @param exitCode The system error code - * @param waitHint Estimated time for pending operation in milliseconds - */ -void -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); -} - -/** - * Since the SvcCtrlHandler should only spend at most 30 seconds before - * returning, this function does the service stop work for the SvcCtrlHandler. -*/ -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; -} - -/** - * Called by SCM whenever a control code is sent to the service - * using the ControlService function. - */ -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); - } - } - break; - default: - break; - } -} diff --git a/onlineupdate/source/service/maintenanceservice.hxx b/onlineupdate/source/service/maintenanceservice.hxx deleted file mode 100644 index af5db9e29dae..000000000000 --- a/onlineupdate/source/service/maintenanceservice.hxx +++ /dev/null @@ -1,10 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -void WINAPI SvcMain(DWORD dwArgc, LPWSTR *lpszArgv); -void SvcInit(DWORD dwArgc, LPWSTR *lpszArgv); -void WINAPI SvcCtrlHandler(DWORD dwCtrl); -void ReportSvcStatus(DWORD dwCurrentState, - DWORD dwWin32ExitCode, - DWORD dwWaitHint); diff --git a/onlineupdate/source/service/registrycertificates.cxx b/onlineupdate/source/service/registrycertificates.cxx deleted file mode 100644 index ea0905cea888..000000000000 --- a/onlineupdate/source/service/registrycertificates.cxx +++ /dev/null @@ -1,181 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <windows.h> - -#include <memory> - -#include "registrycertificates.hxx" -#include "pathhash.h" -#include "servicebase.hxx" -#include "updatehelper.h" -#define MAX_KEY_LENGTH 255 - -namespace { - -struct AutoRegKey -{ - AutoRegKey(HKEY key): - mKey(key) - { - } - - ~AutoRegKey() - { - releaseKey(mKey); - } - - void releaseKey(HKEY key) - { - if (key != nullptr) - { - RegCloseKey(key); - } - } - - HKEY mKey; - - HKEY get() - { - return mKey; - } -}; - -} - -/** - * Verifies if the file path matches any certificate stored in the registry. - * - * @param filePath The file path of the application to check if allowed. - * @return TRUE if the binary matches any of the allowed certificates. - */ -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; - } - - // 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 - } - - 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 - } - - // 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, - }; - - 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; -} diff --git a/onlineupdate/source/service/registrycertificates.hxx b/onlineupdate/source/service/registrycertificates.hxx deleted file mode 100644 index 858b05d7c606..000000000000 --- a/onlineupdate/source/service/registrycertificates.hxx +++ /dev/null @@ -1,13 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _REGISTRYCERTIFICATES_H_ -#define _REGISTRYCERTIFICATES_H_ - -#include "certificatecheck.hxx" - -BOOL DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, - LPCWSTR filePath); - -#endif diff --git a/onlineupdate/source/service/resource.hxx b/onlineupdate/source/service/resource.hxx deleted file mode 100644 index f1a1c383665d..000000000000 --- a/onlineupdate/source/service/resource.hxx +++ /dev/null @@ -1,20 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by updater.rc -// -#define IDI_DIALOG 1003 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/onlineupdate/source/service/servicebase.cxx b/onlineupdate/source/service/servicebase.cxx deleted file mode 100644 index 4fb632878cec..000000000000 --- a/onlineupdate/source/service/servicebase.cxx +++ /dev/null @@ -1,97 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "servicebase.hxx" -#include "windowsHelper.hxx" - -// Shared code between applications and updater.exe - -/** - * Verifies if 2 files are byte for byte equivalent. - * - * @param file1Path The first file to verify. - * @param file2Path The second file to verify. - * @param sameContent Out parameter, TRUE if the files are equal - * @return TRUE If there was no error checking the files. - */ -BOOL -VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL &sameContent) -{ - 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, - 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 (!ReadFile(file2.get(), buf2, COMPARE_BLOCKSIZE, &readAmount, nullptr) || - readAmount != COMPARE_BLOCKSIZE) - { - return FALSE; - } - - if (memcmp(buf1, buf2, COMPARE_BLOCKSIZE)) - { - // 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; -} diff --git a/onlineupdate/source/service/servicebase.hxx b/onlineupdate/source/service/servicebase.hxx deleted file mode 100644 index 45375fbe5d32..000000000000 --- a/onlineupdate/source/service/servicebase.hxx +++ /dev/null @@ -1,21 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <windows.h> -#include "updatelogging.h" - -BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra); -BOOL VerifySameFiles(LPCWSTR file1Path, LPCWSTR file2Path, BOOL& sameContent); - -// 32KiB for comparing files at a time seems reasonable. -// The bigger the better for speed, but this will be used -// on the stack so I don't want it to be too big. -#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 -// 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 "libreoffice-updater.exe-7bab28a0-0599-4f37-9efe-f7f8b71f05e3" -#define IDS_UPDATER_IDENTITY 1006 diff --git a/onlineupdate/source/service/serviceinstall.cxx b/onlineupdate/source/service/serviceinstall.cxx deleted file mode 100644 index 7d53d25cbd6b..000000000000 --- a/onlineupdate/source/service/serviceinstall.cxx +++ /dev/null @@ -1,850 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <windows.h> -#include <aclapi.h> -#include <stdlib.h> -#include <shlwapi.h> - -// Used for DNLEN and UNLEN -#include <lm.h> - -#include "serviceinstall.hxx" -#include "servicebase.hxx" -#include "updatehelper.h" -#include "shellapi.h" -#include "readstrings.h" -#include "errors.h" - -#include <memory> - -#pragma comment(lib, "version.lib") - -namespace { - -struct AutoServiceHandle -{ - AutoServiceHandle(SC_HANDLE handle): - mHandle(handle) - { - } - - ~AutoServiceHandle() - { - releaseHandle(mHandle); - } - - void releaseHandle(SC_HANDLE handle) - { - if (handle != nullptr) - CloseServiceHandle(handle); - } - - SC_HANDLE get() const - { - return mHandle; - } - - operator bool() const - { - return mHandle != nullptr; - } - - void reset(SC_HANDLE handle = nullptr) - { - releaseHandle(mHandle); - mHandle = handle; - } - - SC_HANDLE mHandle; -}; - -} - -/** - * A wrapper function to read strings for the maintenance service. - * - * @param path The path of the ini file to read from - * @param results The maintenance service strings that were read - * @return OK on success -*/ -static int -ReadMaintenanceServiceStrings(LPCWSTR path, - MaintenanceServiceStringTable *results) -{ - // Read in the maintenance service description string if specified. - const unsigned int kNumStrings = 1; - // TODO: moggi: needs adaptation for LibreOffice - 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; -} - -/** - * Obtains the version number from the specified PE file's version information - * Version Format: A.B.C.D (Example 10.0.0.300) - * - * @param path The path of the file to check the version on - * @param A The first part of the version number - * @param B The second part of the version number - * @param C The third part of the version number - * @param D The fourth part of the version number - * @return TRUE if successful - */ -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; -} - -/** - * Updates the service description with what is stored in updater.ini - * at the same path as the currently executing module binary. - * - * @param serviceHandle A handle to an opened service with - * SERVICE_CHANGE_CONFIG access right - * @param TRUE on success. -*/ -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; -} - -/** - * Determines if the MozillaMaintenance service path needs to be updated - * and fixes it if it is wrong. - * - * @param service A handle to the service to fix. - * @param currentServicePath The current (possibly wrong) path that is used. - * @param servicePathWasWrong Out parameter set to TRUE if a fix was needed. - * @return TRUE if the service path is now correct. -*/ -BOOL -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; - 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; -} - -/** - * Installs or upgrades the SVC_NAME service. - * If an existing service is already installed, we replace it with the - * currently running process. - * - * @param action The action to perform. - * @return TRUE if the service was installed/upgraded - */ -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)", - 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. - 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.")); - } - - // 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 - 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; -} - -/** - * Stops the Maintenance service. - * - * @return TRUE if successful. - */ -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; -} - -/** - * Uninstalls the Maintenance service. - * - * @return TRUE if successful. - */ -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; -} - -/** - * Sets the access control list for user access for the specified service. - * - * @param hService The service to set the access control list on - * @return TRUE if successful - */ -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; -} - -/** - * Sets the access control list for user access for the specified service. - * - * @param hService The service to set the access control list on - * @param pNewAcl The out param ACL which should be freed by caller - * @param psd out param security descriptor, should be freed by caller - * @return ERROR_SUCCESS if successful - */ -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(); - } - - 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(); - } - } - - // 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; -} diff --git a/onlineupdate/source/service/serviceinstall.hxx b/onlineupdate/source/service/serviceinstall.hxx deleted file mode 100644 index 1afaada84519..000000000000 --- a/onlineupdate/source/service/serviceinstall.hxx +++ /dev/null @@ -1,21 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "readstrings.h" - -#define SVC_DISPLAY_NAME L"Mozilla Maintenance Service" - -enum SvcInstallAction { UpgradeSvc, InstallSvc, ForceInstallSvc }; -BOOL SvcInstall(SvcInstallAction action); -BOOL SvcUninstall(); -BOOL StopService(); -BOOL SetUserAccessServiceDACL(SC_HANDLE hService); -DWORD SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl, - PSECURITY_DESCRIPTOR psd); - -struct MaintenanceServiceStringTable -{ - char serviceDescription[MAX_TEXT_LEN]; -}; - diff --git a/onlineupdate/source/service/windowsHelper.hxx b/onlineupdate/source/service/windowsHelper.hxx deleted file mode 100644 index e17b40c61055..000000000000 --- a/onlineupdate/source/service/windowsHelper.hxx +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_ONLINEUPDATE_SERVICE_WINDOWSHELPER_HXX -#define INCLUDED_ONLINEUPDATE_SERVICE_WINDOWSHELPER_HXX - -struct AutoHandle -{ - AutoHandle(HANDLE handle): - mHandle(handle) - { - } - - ~AutoHandle() - { - release(mHandle); - } - - void release(HANDLE handle) - { - if (handle && handle != INVALID_HANDLE_VALUE) - { - CloseHandle(handle); - } - } - - HANDLE get() const - { - return mHandle; - } - - bool operator==(const AutoHandle& rhs) const - { - return mHandle == rhs.mHandle; - } - - HANDLE mHandle; -}; - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/onlineupdate/source/service/workmonitor.cxx b/onlineupdate/source/service/workmonitor.cxx deleted file mode 100644 index 6228b1e6c53f..000000000000 --- a/onlineupdate/source/service/workmonitor.cxx +++ /dev/null @@ -1,770 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <shlobj.h> -#include <shlwapi.h> -#include <wtsapi32.h> -#include <userenv.h> -#include <shellapi.h> -#include <cstddef> - -#pragma comment(lib, "wtsapi32.lib") -#pragma comment(lib, "userenv.lib") -#pragma comment(lib, "shlwapi.lib") -#pragma comment(lib, "ole32.lib") -#pragma comment(lib, "rpcrt4.lib") - -#include "workmonitor.hxx" -#include "serviceinstall.hxx" -#include "servicebase.hxx" -#include "registrycertificates.hxx" -#include "uachelper.h" -#include "updatehelper.h" -#include "errors.h" -#include "windowsHelper.hxx" - -// Wait 15 minutes for an update operation to run at most. -// Updates usually take less than a minute so this seems like a -// significantly large and safe amount of time to wait. -static const int TIME_TO_WAIT_ON_UPDATER = 15 * 60 * 1000; -wchar_t* MakeCommandLine(int argc, wchar_t **argv); -BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode); -BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath, - LPCWSTR newFileName); - -/* - * Read the update.status file and sets isApplying to true if - * the status is set to applying. - * - * @param updateDirPath The directory where update.status is stored - * @param isApplying Out parameter for specifying if the status - * is set to applying or not. - * @return TRUE if the information was filled. -*/ -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, - 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; - } - - 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)); - - const char kApplying[] = "applying"; - isApplying = strncmp(buf, kApplying, - sizeof(kApplying) - 1) == 0; - return TRUE; -} - -/** - * Determines whether we're staging an update. - * - * @param argc The argc value normally sent to updater.exe - * @param argv The argv value normally sent to updater.exe - * @return boolean True if we're staging an update - */ -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"); -} - -/** - * Determines whether the param only contains digits. - * - * @param str The string to check - * @param boolean True if the param only contains digits - */ -static bool -IsDigits(WCHAR *str) -{ - while (*str) - { - if (!iswdigit(*str++)) - { - return FALSE; - } - } - return TRUE; -} - -/** - * Determines whether the command line contains just the directory to apply the - * update to (old command line) or if it contains the installation directory and - * the directory to apply the update to. - * - * @param argc The argc value normally sent to updater.exe - * @param argv The argv value normally sent to updater.exe - * @param boolean True if the command line contains just the directory to apply - * the update to - */ -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])); -} - -/** - * Gets the installation directory from the arguments passed to updater.exe. - * - * @param argcTmp The argc value normally sent to updater.exe - * @param argvTmp The argv value normally sent to updater.exe - * @param aResultDir Buffer to hold the installation directory. - */ -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; -} - -/** - * Runs an update process as the service using the SYSTEM account. - * - * @param argc The number of arguments in argv - * @param argv The arguments normally passed to updater.exe - * argv[0] must be the path to updater.exe - * @param processStarted Set to TRUE if the process was started. - * @return TRUE if the update process was run had a return code of 0. - */ -BOOL -StartUpdateProcess(int argc, - LPWSTR *argv, - 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.")); - } - // 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)); - } - } - } - } - - free(cmdLine); - return updateWasSuccessful; -} - -/** - * Processes a software update command - * - * @param argc The number of arguments in argv - * @param argv The arguments normally passed to updater.exe - * argv[0] must be the path to updater.exe - * @return TRUE if the update was successful. - */ -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, - 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.")); - } - 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; -} - -/** - * Obtains the updater path alongside a subdir of the service binary. - * The purpose of this function is to return a path that is likely high - * integrity and therefore more safe to execute code from. - * - * @param serviceUpdaterPath Out parameter for the path where the updater - * should be copied to. - * @return TRUE if a file path was obtained. - */ -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; -} - -/** - * Deletes the passed in updater path and the associated updater.ini file. - * - * @param serviceUpdaterPath The path to delete. - * @return TRUE if a file was deleted. - */ -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; -} - -/** - * Executes a service command. - * - * @param argc The number of arguments in argv - * @param argv The service command line arguments, argv[0] and argv[1] - * and automatically included by Windows. argv[2] is the - * service command. - * - * @return FALSE if there was an error executing the service command. - */ -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 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())); - } - } - - result = ProcessSoftwareUpdateCommand(argc - 3, argv + 3); - DeleteSecureUpdater(secureUpdaterPath); - } - - // 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/service/workmonitor.hxx b/onlineupdate/source/service/workmonitor.hxx deleted file mode 100644 index 8fc2e51a7ded..000000000000 --- a/onlineupdate/source/service/workmonitor.hxx +++ /dev/null @@ -1,5 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -BOOL ExecuteServiceCommand(int argc, LPWSTR* argv); diff --git a/onlineupdate/source/update/common/errors.h b/onlineupdate/source/update/common/errors.h deleted file mode 100644 index 2216b54491ee..000000000000 --- a/onlineupdate/source/update/common/errors.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef Errors_h__ -#define Errors_h__ - -#define OK 0 - -// Error codes that are no longer used should not be used again unless they -// aren't used in client code (e.g. nsUpdateService.js, updates.js, -// UpdatePrompt.js, etc.). - -#define MAR_ERROR_EMPTY_ACTION_LIST 1 -#define LOADSOURCE_ERROR_WRONG_SIZE 2 - -// Error codes 3-16 are for general update problems. -#define USAGE_ERROR 3 -#define CRC_ERROR 4 -#define PARSE_ERROR 5 -#define READ_ERROR 6 -#define WRITE_ERROR 7 -// #define UNEXPECTED_ERROR 8 // Replaced with errors 38-42 -#define ELEVATION_CANCELED 9 -#define READ_STRINGS_MEM_ERROR 10 -#define ARCHIVE_READER_MEM_ERROR 11 -#define BSPATCH_MEM_ERROR 12 -#define UPDATER_MEM_ERROR 13 -#define UPDATER_QUOTED_PATH_MEM_ERROR 14 -#define BAD_ACTION_ERROR 15 -#define STRING_CONVERSION_ERROR 16 - -// Error codes 17-23 are related to security tasks for MAR -// signing and MAR protection. -#define CERT_LOAD_ERROR 17 -#define CERT_HANDLING_ERROR 18 -#define CERT_VERIFY_ERROR 19 -#define ARCHIVE_NOT_OPEN 20 -#define COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR 21 -#define MAR_CHANNEL_MISMATCH_ERROR 22 -#define VERSION_DOWNGRADE_ERROR 23 - -// Error codes 24-33 and 49-51 are for the Windows maintenance service. -#define SERVICE_UPDATER_COULD_NOT_BE_STARTED 24 -#define SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS 25 -#define SERVICE_UPDATER_SIGN_ERROR 26 -#define SERVICE_UPDATER_COMPARE_ERROR 27 -#define SERVICE_UPDATER_IDENTITY_ERROR 28 -#define SERVICE_STILL_APPLYING_ON_SUCCESS 29 -#define SERVICE_STILL_APPLYING_ON_FAILURE 30 -#define SERVICE_UPDATER_NOT_FIXED_DRIVE 31 -#define SERVICE_COULD_NOT_LOCK_UPDATER 32 -#define SERVICE_INSTALLDIR_ERROR 33 - -#define NO_INSTALLDIR_ERROR 34 -#define WRITE_ERROR_ACCESS_DENIED 35 -// #define WRITE_ERROR_SHARING_VIOLATION 36 // Replaced with errors 46-48 -#define WRITE_ERROR_CALLBACK_APP 37 -#define UNEXPECTED_BZIP_ERROR 39 -#define UNEXPECTED_MAR_ERROR 40 -#define UNEXPECTED_BSPATCH_ERROR 41 -#define UNEXPECTED_FILE_OPERATION_ERROR 42 -#define FILESYSTEM_MOUNT_READWRITE_ERROR 43 -#define DELETE_ERROR_EXPECTED_DIR 46 -#define DELETE_ERROR_EXPECTED_FILE 47 -#define RENAME_ERROR_EXPECTED_FILE 48 - -// Error codes 24-33 and 49-51 are for the Windows maintenance service. -#define SERVICE_COULD_NOT_COPY_UPDATER 49 -#define SERVICE_STILL_APPLYING_TERMINATED 50 -#define SERVICE_STILL_APPLYING_NO_EXIT_CODE 51 - -#define WRITE_ERROR_FILE_COPY 61 -#define WRITE_ERROR_DELETE_FILE 62 -#define WRITE_ERROR_OPEN_PATCH_FILE 63 -#define WRITE_ERROR_PATCH_FILE 64 -#define WRITE_ERROR_APPLY_DIR_PATH 65 -#define WRITE_ERROR_CALLBACK_PATH 66 -#define WRITE_ERROR_FILE_ACCESS_DENIED 67 -#define WRITE_ERROR_DIR_ACCESS_DENIED 68 -#define WRITE_ERROR_DELETE_BACKUP 69 -#define WRITE_ERROR_EXTRACT 70 - -// Error codes 80 through 99 are reserved for nsUpdateService.js - -// The following error codes are only used by updater.exe -// when a fallback key exists for tests. -#define FALLBACKKEY_UNKNOWN_ERROR 100 -#define FALLBACKKEY_REGPATH_ERROR 101 -#define FALLBACKKEY_NOKEY_ERROR 102 -#define FALLBACKKEY_SERVICE_NO_STOP_ERROR 103 -#define FALLBACKKEY_LAUNCH_ERROR 104 - -#endif // Errors_h__ diff --git a/onlineupdate/source/update/common/pathhash.cxx b/onlineupdate/source/update/common/pathhash.cxx deleted file mode 100644 index 67e53fa35bea..000000000000 --- a/onlineupdate/source/update/common/pathhash.cxx +++ /dev/null @@ -1,153 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#include <windows.h> -#include <wincrypt.h> -#include "pathhash.h" - - -/** - * Converts a binary sequence into a hex string - * - * @param hash The binary data sequence - * @param hashSize The size of the binary data sequence - * @param hexString A buffer to store the hex string, must be of - * size 2 * @hashSize -*/ -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; - } -} - -/** - * Calculates an MD5 hash for the given input binary data - * - * @param data Any sequence of bytes - * @param dataSize The number of bytes inside @data - * @param hash Output buffer to store hash, must be freed by the caller - * @param hashSize The number of bytes in the output buffer - * @return TRUE on success -*/ -static BOOL -CalculateMD5(const char *data, DWORD dataSize, - BYTE **hash, DWORD &hashSize) -{ - HCRYPTPROV hProv = 0; - HCRYPTHASH hHash = 0; - - 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; - } - } - - 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; -} - -/** - * Converts a file path into a unique registry location for cert storage - * - * @param filePath The input file path to get a registry path from - * @param registryPath A buffer to write the registry path to, must - * be of size in WCHARs MAX_PATH + 1 - * @return TRUE if successful -*/ -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)) - { - 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; -} -#endif diff --git a/onlineupdate/source/update/common/pathhash.h b/onlineupdate/source/update/common/pathhash.h deleted file mode 100644 index 9856b4cf45aa..000000000000 --- a/onlineupdate/source/update/common/pathhash.h +++ /dev/null @@ -1,19 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _PATHHASH_H_ -#define _PATHHASH_H_ - -/** - * Converts a file path into a unique registry location for cert storage - * - * @param filePath The input file path to get a registry path from - * @param registryPath A buffer to write the registry path to, must - * be of size in WCHARs MAX_PATH + 1 - * @return TRUE if successful -*/ -BOOL CalculateRegistryPathFromFilePath(const LPCWSTR filePath, - LPWSTR registryPath); - -#endif diff --git a/onlineupdate/source/update/common/readstrings.cxx b/onlineupdate/source/update/common/readstrings.cxx deleted file mode 100644 index e1366cdddaed..000000000000 --- a/onlineupdate/source/update/common/readstrings.cxx +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <limits.h> -#include <string.h> -#include <stdio.h> -#include "readstrings.h" -#include "errors.h" - -#ifdef _WIN32 -# define NS_tfopen _wfopen -# define OPEN_MODE L"rb" -#else -# define NS_tfopen fopen -# define OPEN_MODE "r" -#endif - -// stack based FILE wrapper to ensure that fclose is called. -class AutoFILE -{ -public: - explicit AutoFILE(FILE *fp) : fp_(fp) {} - ~AutoFILE() - { - if (fp_) fclose(fp_); - } - operator FILE *() - { - return fp_; - } -private: - FILE *fp_; -}; - -class AutoCharArray -{ -public: - explicit AutoCharArray(size_t len) - { - ptr_ = new char[len]; - } - ~AutoCharArray() - { - delete[] ptr_; - } - operator char *() - { - return ptr_; - } -private: - char *ptr_; -}; - -static const char kNL[] = "\r\n"; -static const char kEquals[] = "="; -static const char kWhitespace[] = " \t"; -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; - } - } - } - while (*d); - - 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; - } - } - ++i; - } - while (*i); - - *str = nullptr; - return ret; -} - -/** - * Find a key in a keyList containing zero-delimited keys ending with "\0\0". - * Returns a zero-based index of the key in the list, or -1 if the key is not found. - */ -static int -find_key(const char *keyList, char* key) -{ - if (!keyList) - return -1; - - int index = 0; - const char *p = keyList; - while (*p) - { - if (strcmp(key, p) == 0) - return index; - - p += strlen(p) + 1; - index++; - } - - // The key was not found if we came here - return -1; -} - -/** - * A very basic parser for updater.ini taken mostly from nsINIParser.cpp - * that can be used by standalone apps. - * - * @param path Path to the .ini file to read - * @param keyList List of zero-delimited keys ending with two zero characters - * @param numStrings Number of strings to read into results buffer - must be equal to the number of keys - * @param results Two-dimensional array of strings to be filled in the same order as the keys provided - * @param section Optional name of the section to read; defaults to "Strings" - */ -int -ReadStrings(const NS_tchar *path, - const char *keyList, - unsigned int numStrings, - 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; - } - - 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; -} - -// A wrapper function to read strings for the updater. -// Added for compatibility with the original code. -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]; - - 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'; - - return result; -} diff --git a/onlineupdate/source/update/common/readstrings.h b/onlineupdate/source/update/common/readstrings.h deleted file mode 100644 index 747081394c10..000000000000 --- a/onlineupdate/source/update/common/readstrings.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef READSTRINGS_H__ -#define READSTRINGS_H__ - -#define MAX_TEXT_LEN 600 - -#ifdef _WIN32 -# include <windows.h> -#endif - -#include "types.hxx" - -struct StringTable -{ - char title[MAX_TEXT_LEN]; - char info[MAX_TEXT_LEN]; -}; - -/** - * This function reads in localized strings from updater.ini - */ -int ReadStrings(const NS_tchar *path, StringTable *results); - -/** - * This function reads in localized strings corresponding to the keys from a given .ini - */ -int ReadStrings(const NS_tchar *path, - const char *keyList, - unsigned int numStrings, - char results[][MAX_TEXT_LEN], - const char *section = nullptr); - -#endif // READSTRINGS_H__ diff --git a/onlineupdate/source/update/common/sources.mozbuild b/onlineupdate/source/update/common/sources.mozbuild deleted file mode 100644 index 3de907b32f05..000000000000 --- a/onlineupdate/source/update/common/sources.mozbuild +++ /dev/null @@ -1,19 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -sources = [] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': - sources += [ - 'pathhash.cpp', - 'uachelper.cpp', - 'updatehelper.cpp', - ] - -sources += [ - 'readstrings.cpp', - 'updatelogging.cpp', -] - -SOURCES += sorted(['%s/%s' % (srcdir, s) for s in sources]) diff --git a/onlineupdate/source/update/common/uachelper.cxx b/onlineupdate/source/update/common/uachelper.cxx deleted file mode 100644 index 831b12680719..000000000000 --- a/onlineupdate/source/update/common/uachelper.cxx +++ /dev/null @@ -1,237 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#include <windows.h> -#include <wtsapi32.h> -#include "uachelper.h" -#include "updatelogging.h" - -// 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 -}; - -/** - * Opens a user token for the given session ID - * - * @param sessionID The session ID for the token to obtain - * @return A handle to the token to obtain which will be primary if enough - * permissions exist. Caller should close the handle. - */ -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; -} - -/** - * Opens a linked token for the specified token. - * - * @param token The token to get the linked token from - * @return A linked token or nullptr if one does not exist. - * Caller should close the handle. - */ -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; -} - - -/** - * Enables or disables a privilege for the specified token. - * - * @param token The token to adjust the privilege on. - * @param priv The privilege to adjust. - * @param enable Whether to enable or disable it - * @return TRUE if the token was adjusted to the specified value. - */ -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; -} - -/** - * For each privilege that is specified, an attempt will be made to - * drop the privilege. - * - * @param token The token to adjust the privilege on. - * Pass nullptr for current token. - * @param unneededPrivs An array of unneeded privileges. - * @param count The size of the array - * @return TRUE if there were no errors - */ -BOOL -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; - } - 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; - } - } - - if (obtainedToken) - { - CloseHandle(obtainedToken); - } - return result; -} - -/** - * Disables privileges for the specified token. - * The privileges to disable are in PrivsToDisable. - * In the future there could be new privs and we are not sure if we should - * explicitly disable these or not. - * - * @param token The token to drop the privilege on. - * Pass nullptr for current token. - * @return TRUE if there were no errors - */ -BOOL -UACHelper::DisablePrivileges(HANDLE token) -{ - static const size_t PrivsToDisableSize = - sizeof(UACHelper::PrivsToDisable) / sizeof(UACHelper::PrivsToDisable[0]); - - return DisableUnneededPrivileges(token, UACHelper::PrivsToDisable, - PrivsToDisableSize); -} - -/** - * Check if the current user can elevate. - * - * @return true if the user can elevate. - * false otherwise. - */ -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; -} -#endif diff --git a/onlineupdate/source/update/common/uachelper.h b/onlineupdate/source/update/common/uachelper.h deleted file mode 100644 index 4e8d1c84239a..000000000000 --- a/onlineupdate/source/update/common/uachelper.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _UACHELPER_H_ -#define _UACHELPER_H_ - -class UACHelper -{ -public: - 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[]; -}; - -#endif diff --git a/onlineupdate/source/update/common/updatedefines.h b/onlineupdate/source/update/common/updatedefines.h deleted file mode 100644 index 748f9e098dd6..000000000000 --- a/onlineupdate/source/update/common/updatedefines.h +++ /dev/null @@ -1,135 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef UPDATEDEFINES_H -#define UPDATEDEFINES_H - -#include "readstrings.h" - -#ifndef MAXPATHLEN -# ifdef PATH_MAX -# define MAXPATHLEN PATH_MAX -# elif defined(MAX_PATH) -# define MAXPATHLEN MAX_PATH -# elif defined(_MAX_PATH) -# define MAXPATHLEN _MAX_PATH -# elif defined(CCHMAXPATH) -# define MAXPATHLEN CCHMAXPATH -# else -# define MAXPATHLEN 1024 -# endif -#endif - -#if defined(_WIN32) -# include <windows.h> -# include <shlwapi.h> -# include <direct.h> -# include <io.h> -# include <stdio.h> -# include <stdarg.h> - -# define F_OK 00 -# define W_OK 02 -# define R_OK 04 -# define S_ISDIR(s) (((s) & _S_IFMT) == _S_IFDIR) -# define S_ISREG(s) (((s) & _S_IFMT) == _S_IFREG) - -# define access _access - -# define putenv _putenv -# define DELETE_DIR L"tobedeleted" -# define CALLBACK_BACKUP_EXT L".moz-callback" - -# define LOG_S "%S" -# define NS_T(str) L ## str -# define NS_SLASH NS_T('\\') - -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; -} -#define NS_tsnprintf mywcsprintf -# define NS_taccess _waccess -# define NS_tchdir _wchdir -# define NS_tchmod _wchmod -# define NS_tfopen _wfopen -# define NS_tmkdir(path, perms) _wmkdir(path) -# define NS_tremove _wremove -// _wrename is used to avoid the link tracking service. -# define NS_trename _wrename -# define NS_trmdir _wrmdir -# define NS_tstat _wstat -# define NS_tlstat _wstat // No symlinks on Windows -# define NS_tstat_t _stat -# define NS_tstrcat wcscat -# define NS_tstrcmp wcscmp -# define NS_tstrncmp wcsncmp -# define NS_tstricmp wcsicmp -# define NS_tstrcpy wcscpy -# define NS_tstrncpy wcsncpy -# define NS_tstrlen wcslen -# define NS_tstrchr wcschr -# define NS_tstrrchr wcsrchr -# define NS_tstrstr wcsstr -# include "win_dirent.h" -# define NS_tDIR DIR -# define NS_tdirent dirent -# define NS_topendir opendir -# define NS_tclosedir closedir -# define NS_treaddir readdir -#else -# include <sys/wait.h> -# include <unistd.h> - -#ifdef __sun -# include <sys/stat.h> -#else -# include <fts.h> -#endif -# include <dirent.h> - -#ifdef MACOSX -# include <sys/time.h> -#endif - -# define LOG_S "%s" -# define NS_T(str) str -# define NS_SLASH NS_T('/') -# define NS_tsnprintf snprintf -# define NS_taccess access -# define NS_tchdir chdir -# define NS_tchmod chmod -# define NS_tfopen fopen -# define NS_tmkdir mkdir -# define NS_tremove remove -# define NS_trename rename -# define NS_trmdir rmdir -# define NS_tstat stat -# define NS_tstat_t stat -# define NS_tlstat lstat -# define NS_tstrcat strcat -# define NS_tstrcmp strcmp -# define NS_tstrncmp strncmp -# define NS_tstricmp strcasecmp -# define NS_tstrcpy strcpy -# define NS_tstrncpy strncpy -# define NS_tstrlen strlen -# define NS_tstrrchr strrchr -# define NS_tstrstr strstr -# define NS_tDIR DIR -# define NS_tdirent dirent -# define NS_topendir opendir -# define NS_tclosedir closedir -# define NS_treaddir readdir -#endif - -#define BACKUP_EXT NS_T(".moz-backup") - -#endif diff --git a/onlineupdate/source/update/common/updatehelper.cxx b/onlineupdate/source/update/common/updatehelper.cxx deleted file mode 100644 index 09f857b1a9e9..000000000000 --- a/onlineupdate/source/update/common/updatehelper.cxx +++ /dev/null @@ -1,807 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#include <windows.h> - -// Needed for CreateToolhelp32Snapshot -#include <tlhelp32.h> -#ifndef ONLY_SERVICE_LAUNCHING - -#include <stdio.h> -#include "shlobj.h" -#include "updatehelper.h" -#include "uachelper.h" -#include "pathhash.h" - -#include <memory> - -// Needed for PathAppendW -#include <shlwapi.h> - -BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra); - -/** - * Obtains the path of a file in the same directory as the specified file. - * - * @param destinationBuffer A buffer of size MAX_PATH + 1 to store the result. - * @param siblingFIlePath The path of another file in the same directory - * @param newFileName The filename of another file in the same directory - * @return TRUE if successful - */ -BOOL -PathGetSiblingFilePath(LPWSTR destinationBuffer, - LPCWSTR siblingFilePath, - LPCWSTR newFileName) -{ - if (wcslen(siblingFilePath) >= MAX_PATH) - { - return FALSE; - } - - wcsncpy(destinationBuffer, siblingFilePath, MAX_PATH); - if (!PathRemoveFileSpecW(destinationBuffer)) - { - return FALSE; - } - - if (wcslen(destinationBuffer) + wcslen(newFileName) >= MAX_PATH) - { - return FALSE; - } - - return PathAppendSafe(destinationBuffer, newFileName); -} - -/** - * Launch the post update application as the specified user (helper.exe). - * It takes in the path of the callback application to calculate the path - * of helper.exe. For service updates this is called from both the system - * account and the current user account. - * - * @param installationDir The path to the callback application binary. - * @param updateInfoDir The directory where update info is stored. - * @param forceSync If true even if the ini file specifies async, the - * process will wait for termination of PostUpdate. - * @param userToken The user token to run as, if nullptr the current - * user will be used. - * @return TRUE if there was no error starting the process. - */ -BOOL -LaunchWinPostProcess(const WCHAR *installationDir, - const WCHAR *updateInfoDir, - 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; -} - -/** - * Starts the upgrade process for update of the service if it is - * already installed. - * - * @param installDir the installation directory where - * maintenanceservice_installer.exe is located. - * @return TRUE if successful - */ -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) - { - CloseServiceHandle(manager); - return FALSE; - } - - // If we reach here, then the service is installed, so - // proceed with upgrading it. - - CloseServiceHandle(manager); - - // 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; -} - -#endif - -/** - * Executes a maintenance service command - * - * @param argc The total number of arguments in argv - * @param argv An array of null terminated strings to pass to the service, - * @return ERROR_SUCCESS if the service command was started. - * Less than 16000, a windows system error code from StartServiceW - * More than 20000, 20000 + the last state of the service constant if - * the last state is something other than stopped. - * 17001 if the SCM could not be opened - * 17002 if the service could not be opened -*/ -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) - { - 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; -} - -#ifndef ONLY_SERVICE_LAUNCHING - -/** - * Launch a service initiated action for a software update with the - * specified arguments. - * - * @param exePath The path of the executable to run - * @param argc The total number of arguments in argv - * @param argv An array of null terminated strings to pass to the exePath, - * argv[0] must be the path to the updater.exe - * @return ERROR_SUCCESS if successful - */ -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; -} - -/** - * Joins a base directory path with a filename. - * - * @param base The base directory path of size MAX_PATH + 1 - * @param extra The filename to append - * @return TRUE if the file name was successful appended to base - */ -BOOL -PathAppendSafe(LPWSTR base, LPCWSTR extra) -{ - if (wcslen(base) + wcslen(extra) >= MAX_PATH) - { - return FALSE; - } - - return PathAppendW(base, extra); -} - -/** - * Sets update.status to pending so that the next startup will not use - * the service and instead will attempt an update the with a UAC prompt. - * - * @param updateDirPath The path of the update directory - * @return TRUE if successful - */ -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); -} - -/** - * Sets update.status to a specific failure code - * - * @param updateDirPath The path of the update directory - * @return TRUE if successful - */ -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; -} - -#endif - -/** - * Waits for a service to enter a stopped state. - * This function does not stop the service, it just blocks until the service - * is stopped. - * - * @param serviceName The service to wait for. - * @param maxWaitSeconds The maximum number of seconds to wait - * @return state of the service after a timeout or when stopped. - * A value of 255 is returned for an error. Typical values are: - * SERVICE_STOPPED 0x00000001 - * SERVICE_START_PENDING 0x00000002 - * SERVICE_STOP_PENDING 0x00000003 - * SERVICE_RUNNING 0x00000004 - * SERVICE_CONTINUE_PENDING 0x00000005 - * SERVICE_PAUSE_PENDING 0x00000006 - * SERVICE_PAUSED 0x00000007 - * last status not set 0x000000CF - * Could no query status 0x000000DF - * Could not open service, access denied 0x000000EB - * Could not open service, invalid handle 0x000000EC - * Could not open service, invalid name 0x000000ED - * Could not open service, does not exist 0x000000EE - * Could not open service, other error 0x000000EF - * Could not open SCM, access denied 0x000000FD - * Could not open SCM, database does not exist 0x000000FE; - * Could not open SCM, other error 0x000000FF; - * Note: The strange choice of error codes above SERVICE_PAUSED are chosen - * in case Windows comes out with other service stats higher than 7, they - * would likely call it 8 and above. JS code that uses this in TestAUSHelper - * only handles values up to 255 so that's why we don't use GetLastError - * directly. - */ -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; - } - - // 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); - } - - lastServiceState = ssp.dwCurrentState; - CloseServiceHandle(service); - CloseServiceHandle(serviceManager); - return lastServiceState; -} - -#ifndef ONLY_SERVICE_LAUNCHING - -/** - * Determines if there is at least one process running for the specified - * application. A match will be found across any session for any user. - * - * @param process The process to check for existence - * @return ERROR_NOT_FOUND if the process was not found - * ERROR_SUCCESS if the process was found and there were no errors - * Other Win32 system error code for other errors -**/ -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; - } - - do - { - if (wcsicmp(filename, processEntry.szExeFile) == 0) - { - CloseHandle(snapshot); - return ERROR_SUCCESS; - } - } - while (Process32NextW(snapshot, &processEntry)); - CloseHandle(snapshot); - return ERROR_NOT_FOUND; -} - -/** - * Waits for the specified application to exit. - * - * @param filename The application to wait for. - * @param maxSeconds The maximum amount of seconds to wait for all - * instances of the application to exit. - * @return ERROR_SUCCESS if no instances of the application exist - * WAIT_TIMEOUT if the process is still running after maxSeconds. - * Any other Win32 system error code. -*/ -DWORD -WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds) -{ - DWORD applicationRunningError = WAIT_TIMEOUT; - for (DWORD i = 0; i < maxSeconds; i++) - { - applicationRunningError = IsProcessRunning(filename); - if (ERROR_NOT_FOUND == applicationRunningError) - { - return ERROR_SUCCESS; - } - Sleep(1000); - } - - if (ERROR_SUCCESS == applicationRunningError) - { - return WAIT_TIMEOUT; - } - - return applicationRunningError; -} - -/** - * Determines if the fallback key exists or not - * - * @return TRUE if the fallback key exists and there was no error checking -*/ -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; -} - -#endif - -/** - * Determines if the file system for the specified file handle is local - * @param file path to check the filesystem type for, must be at most MAX_PATH - * @param isLocal out parameter which will hold TRUE if the drive is local - * @return TRUE if the call succeeded -*/ -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; -} - - -/** - * Determines the DWORD value of a registry key value - * - * @param key The base key to where the value name exists - * @param valueName The name of the value - * @param retValue Out parameter which will hold the value - * @return TRUE on success -*/ -static BOOL -GetDWORDValue(HKEY key, LPCWSTR valueName, DWORD &retValue) -{ - DWORD regDWORDValueSize = sizeof(DWORD); - LONG retCode = RegQueryValueExW(key, valueName, 0, nullptr, - reinterpret_cast<LPBYTE>(&retValue), - ®DWORDValueSize); - return ERROR_SUCCESS == retCode; -} - -/** - * Determines if the system's elevation type allows - * unprompted elevation. - * - * @param isUnpromptedElevation Out parameter which specifies if unprompted - * elevation is allowed. - * @return TRUE if the user can actually elevate and the value was obtained - * successfully. -*/ -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; -} -#endif diff --git a/onlineupdate/source/update/common/updatehelper.h b/onlineupdate/source/update/common/updatehelper.h deleted file mode 100644 index b8c557bd64fd..000000000000 --- a/onlineupdate/source/update/common/updatehelper.h +++ /dev/null @@ -1,34 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -BOOL LaunchWinPostProcess(const WCHAR *installationDir, - const WCHAR *updateInfoDir, - bool forceSync, - HANDLE userToken); -BOOL StartServiceUpdate(LPCWSTR installDir); -BOOL GetUpdateDirectoryPath(LPWSTR path); -DWORD LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR *argv); -BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode); -BOOL WriteStatusPending(LPCWSTR updateDirPath); -DWORD WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds); -DWORD WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds); -BOOL DoesFallbackKeyExist(); -BOOL IsLocalFile(LPCWSTR file, BOOL &isLocal); -DWORD StartServiceCommand(int argc, LPCWSTR* argv); -BOOL IsUnpromptedElevation(BOOL &isUnpromptedElevation); - -#define SVC_NAME L"LibreOfficeMaintenance" - -#define BASE_SERVICE_REG_KEY \ - L"SOFTWARE\\LibreOffice\\MaintenanceService" - -// The test only fallback key, as its name implies, is only present on machines -// that will use automated tests. Since automated tests always run from a -// different directory for each test, the presence of this key bypasses the -// "This is a valid installation directory" check. This key also stores -// the allowed name and issuer for cert checks so that the cert check -// code can still be run unchanged. -#define TEST_ONLY_FALLBACK_KEY_PATH \ - BASE_SERVICE_REG_KEY L"\\3932ecacee736d366d6436db0f55bce4" - diff --git a/onlineupdate/source/update/common/updatelogging.cxx b/onlineupdate/source/update/common/updatelogging.cxx deleted file mode 100644 index ed055cd47072..000000000000 --- a/onlineupdate/source/update/common/updatelogging.cxx +++ /dev/null @@ -1,85 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(_WIN32) -#include <windows.h> -#endif - - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> - -#include "updatelogging.h" - -UpdateLog::UpdateLog() - : logFP(nullptr) - , sourcePath(nullptr) -{ -} - -void UpdateLog::Init(NS_tchar* sourcePathParam, - const NS_tchar* fileName, - const NS_tchar* alternateFileName, - bool append) -{ - 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)) - { - 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")); -} - -void UpdateLog::Finish() -{ - if (!logFP) - return; - - fclose(logFP); - logFP = nullptr; -} - -void UpdateLog::Flush() -{ - if (!logFP) - return; - - 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); -} - -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); -} diff --git a/onlineupdate/source/update/common/updatelogging.h b/onlineupdate/source/update/common/updatelogging.h deleted file mode 100644 index 591cb3f4f2c2..000000000000 --- a/onlineupdate/source/update/common/updatelogging.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef UPDATELOGGING_H -#define UPDATELOGGING_H - -#include "updatedefines.h" -#include <stdio.h> - -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(); - } - -protected: - UpdateLog(); - FILE *logFP; - NS_tchar* sourcePath; -}; - -#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args -#define LOG(args) UpdateLog::GetPrimaryLog().Printf args -#define LogInit(PATHNAME_, FILENAME_) \ - UpdateLog::GetPrimaryLog().Init(PATHNAME_, FILENAME_, 0, false) -#define LogInitAppend(PATHNAME_, FILENAME_, ALTERNATE_) \ - UpdateLog::GetPrimaryLog().Init(PATHNAME_, FILENAME_, ALTERNATE_, true) -#define LogFinish() UpdateLog::GetPrimaryLog().Finish() -#define LogFlush() UpdateLog::GetPrimaryLog().Flush() - -#endif diff --git a/onlineupdate/source/update/common/win_dirent.h b/onlineupdate/source/update/common/win_dirent.h deleted file mode 100644 index fff13f9e0c9f..000000000000 --- a/onlineupdate/source/update/common/win_dirent.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef WINDIRENT_H__ -#define WINDIRENT_H__ -#ifdef _WIN32 -#include <windows.h> - -struct DIR -{ - explicit DIR(const WCHAR* path); - ~DIR(); - HANDLE findHandle; - WCHAR name[MAX_PATH]; -}; - -struct dirent -{ - dirent(); - WCHAR d_name[MAX_PATH]; -}; - -DIR* opendir(const WCHAR* path); -int closedir(DIR* dir); -dirent* readdir(DIR* dir); - -#endif // WNT -#endif // WINDIRENT_H__ diff --git a/onlineupdate/source/update/updater/Makefile.in b/onlineupdate/source/update/updater/Makefile.in deleted file mode 100644 index 57813b36a20c..000000000000 --- a/onlineupdate/source/update/updater/Makefile.in +++ /dev/null @@ -1,28 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# For changes here, also consider ./updater-xpcshell/Makefile.in - -# This is how the xpcshellCertificate.der file is generated, in case we ever -# have to regenerate it. -# ./certutil -L -d modules/libmar/tests/unit/data -n mycert -r > xpcshellCertificate.der -xpcshellCert.h: xpcshellCertificate.der - -ifdef MOZ_WIDGET_GTK -libs:: updater.png - $(NSINSTALL) -D $(DIST)/bin/icons - $(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/icons -endif - -ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) -libs:: - $(NSINSTALL) -D $(DIST)/bin/updater.app - rsync -a -C --exclude '*.in' $(srcdir)/macbuild/Contents $(DIST)/bin/updater.app - sed -e 's/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \ - iconv -f UTF-8 -t UTF-16 > $(DIST)/bin/updater.app/Contents/Resources/English.lproj/InfoPlist.strings - $(NSINSTALL) -D $(DIST)/bin/updater.app/Contents/MacOS - $(NSINSTALL) $(DIST)/bin/updater $(DIST)/bin/updater.app/Contents/MacOS - rm -f $(DIST)/bin/updater -endif diff --git a/onlineupdate/source/update/updater/archivereader.cxx b/onlineupdate/source/update/updater/archivereader.cxx deleted file mode 100644 index d669211437e9..000000000000 --- a/onlineupdate/source/update/updater/archivereader.cxx +++ /dev/null @@ -1,349 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> -#include "bzlib.h" -#include "archivereader.h" -#include "errors.h" -#ifdef _WIN32 -#include "updatehelper.h" -#endif - -// These are generated at compile time based on the DER file for the channel -// being used -#ifdef VERIFY_MAR_SIGNATURE -#ifdef TEST_UPDATER -#include "../xpcshellCert.h" -#else -#include "onlineupdate/primaryCert.h" -#include "onlineupdate/secondaryCert.h" -#endif -#endif - -#if defined(_WIN32) -#define UPDATER_NO_STRING_GLUE_STL -#endif -#include "nsVersionComparator.h" -#undef UPDATER_NO_STRING_GLUE_STL - -#if defined(UNIX) -# include <sys/types.h> -#elif defined(_WIN32) -# include <io.h> -#endif - -static int inbuf_size = 262144; -static int outbuf_size = 262144; -static char *inbuf = nullptr; -static char *outbuf = nullptr; - -/** - * Performs a verification on the opened MAR file with the passed in - * certificate name ID and type ID. - * - * @param archive The MAR file to verify the signature on. - * @param certData The certificate data. - * @return OK on success, CERT_VERIFY_ERROR on failure. -*/ -template<uint32_t SIZE> -int -VerifyLoadedCert(MarFile *archive, const uint8_t (&certData)[SIZE]) -{ - (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; - } -#endif - - return OK; -} - -/** - * Performs a verification on the opened MAR file. Both the primary and backup - * keys stored are stored in the current process and at least the primary key - * will be tried. Success will be returned as long as one of the two - * signatures verify. - * - * @return OK on success -*/ -int -ArchiveReader::VerifySignature() -{ - if (!mArchive) - { - return ARCHIVE_NOT_OPEN; - } - -#ifndef VERIFY_MAR_SIGNATURE - return OK; -#else -#ifdef TEST_UPDATER - int rv = VerifyLoadedCert(mArchive, xpcshellCertData); -#else - int rv = VerifyLoadedCert(mArchive, primaryCertData); - if (rv != OK) - { - rv = VerifyLoadedCert(mArchive, secondaryCertData); - } -#endif - return rv; -#endif -} - -/** - * Verifies that the MAR file matches the current product, channel, and version - * - * @param MARChannelID The MAR channel name to use, only updates from MARs - * with a matching MAR channel name will succeed. - * If an empty string is passed, no check will be done - * for the channel name in the product information block. - * If a comma separated list of values is passed then - * one value must match. - * @param appVersion The application version to use, only MARs with an - * application version >= to appVersion will be applied. - * @return OK on success - * COULD_NOT_READ_PRODUCT_INFO_BLOCK if the product info block - * could not be read. - * MARCHANNEL_MISMATCH_ERROR if update-settings.ini's MAR - * channel ID doesn't match the MAR - * file's MAR channel ID. - * VERSION_DOWNGRADE_ERROR if the application version for - * this updater is newer than the - * one in the MAR. - */ -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 (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; -} - -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 (!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); -#else - mArchive = mar_open(path); -#endif - if (!mArchive) - return READ_ERROR; - - return OK; -} - -void -ArchiveReader::Close() -{ - 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; - -#ifdef _WIN32 - FILE* fp = _wfopen(dest, L"wb+"); -#else - int fd = creat(dest, item->flags); - if (fd == -1) - return WRITE_ERROR; - - FILE *fp = fdopen(fd, "wb"); -#endif - if (!fp) - return WRITE_ERROR; - - int rv = ExtractItemToStream(item, fp); - - 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; - - 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; - } - } - - BZ2_bzDecompressEnd(&strm); - return ret; -} diff --git a/onlineupdate/source/update/updater/archivereader.h b/onlineupdate/source/update/updater/archivereader.h deleted file mode 100644 index 090b787f9cf5..000000000000 --- a/onlineupdate/source/update/updater/archivereader.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef ArchiveReader_h__ -#define ArchiveReader_h__ - -#include <stdio.h> -#include <onlineupdate/mar.h> -#include "types.hxx" - -// This class provides an API to extract files from an update archive. -class ArchiveReader -{ -public: - ArchiveReader() : mArchive(nullptr) {} - ~ArchiveReader() - { - 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); - -private: - int ExtractItemToStream(const MarItem *item, FILE *fp); - - MarFile *mArchive; -}; - -#endif // ArchiveReader_h__ diff --git a/onlineupdate/source/update/updater/bspatch.cxx b/onlineupdate/source/update/updater/bspatch.cxx deleted file mode 100644 index 219c4d74cafa..000000000000 --- a/onlineupdate/source/update/updater/bspatch.cxx +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * Copyright 2003,2004 Colin Percival - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Changelog: - * 2005-04-26 - Define the header as a C structure, add a CRC32 checksum to - * the header, and make all the types 32-bit. - * --Benjamin Smedberg <benjamin@smedbergs.us> - */ - -#include "bspatch.h" -#include "errors.h" - -#include <algorithm> -#include <sys/stat.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <limits.h> - -#if defined(_WIN32) -# include <io.h> -#else -# include <unistd.h> -#endif - -#ifdef _WIN32 -# include <winsock2.h> -#else -# include <arpa/inet.h> -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX LONG_MAX -#endif - -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; -} - -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 = std::min(r, size_t(SSIZE_MAX)); - size_t c = fread(wb, 1, count, patchFile); - if (c != count) - { - rv = READ_ERROR; - goto end; - } - - r -= c; - wb += c; - } - - { - 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; - - 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); -#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); - } - -end: - free(buf); - return rv; -} diff --git a/onlineupdate/source/update/updater/gen_cert_header.py b/onlineupdate/source/update/updater/gen_cert_header.py deleted file mode 100755 index 3f3798cfb425..000000000000 --- a/onlineupdate/source/update/updater/gen_cert_header.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function -import os -import sys -import binascii - -try: - from configparser import ConfigParser -except ImportError: - from ConfigParser import SafeConfigParser as ConfigParser - -def file_byte_generator(filename): - with open(filename, "rb") as f: - block = f.read() - return block - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - -def create_header(array_name, in_filename): - if sys.version_info >= (3,0): - hexified = ["0x" + binascii.hexlify(bytes([inp])).decode('ascii') for inp in file_byte_generator(in_filename)] - else: - hexified = ["0x" + binascii.hexlify(inp).decode('ascii') for inp in file_byte_generator(in_filename)] - print("const uint8_t " + array_name + "[] = {") - print(", ".join(hexified)) - print("};") - return 0 - -if __name__ == '__main__': - if len(sys.argv) < 3: - eprint('ERROR: usage: gen_cert_header.py array_name update_config_file') - sys.exit(1) - - if not os.path.exists(sys.argv[2]): - eprint('The config file %s does not exist'%(sys.argv[2])) - sys.exit(1) - - config = ConfigParser() - config.read(sys.argv[2]) - sys.exit(create_header(sys.argv[1], config.get('Updater', 'certificate-der'))) diff --git a/onlineupdate/source/update/updater/launchchild_osx.mm b/onlineupdate/source/update/updater/launchchild_osx.mm deleted file mode 100644 index 9e4e08d372fe..000000000000 --- a/onlineupdate/source/update/updater/launchchild_osx.mm +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <Cocoa/Cocoa.h> -#include <CoreServices/CoreServices.h> -#include <crt_externs.h> -#include <stdlib.h> -#include <stdio.h> -#include <spawn.h> -#include "readstrings.h" - -// Prefer the currently running architecture (this is the same as the -// architecture that launched the updater) and fallback to CPU_TYPE_ANY if it -// is no longer available after the update. -static cpu_type_t pref_cpu_types[2] = { -#if defined(__i386__) - CPU_TYPE_X86, -#elif defined(__x86_64__) - CPU_TYPE_X86_64, -#elif defined(__ppc__) - CPU_TYPE_POWERPC, -#endif - CPU_TYPE_ANY }; - -void LaunchChild(int argc, char **argv) -{ - // Initialize spawn attributes. - posix_spawnattr_t spawnattr; - if (posix_spawnattr_init(&spawnattr) != 0) { - printf("Failed to init posix spawn attribute."); - return; - } - - // Set spawn attributes. - size_t attr_count = 2; - size_t attr_ocount = 0; - if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, pref_cpu_types, &attr_ocount) != 0 || - attr_ocount != attr_count) { - printf("Failed to set binary preference on posix spawn attribute."); - posix_spawnattr_destroy(&spawnattr); - return; - } - - // "posix_spawnp" uses null termination for arguments rather than a count. - // Note that we are not duplicating the argument strings themselves. - char** argv_copy = (char**)malloc((argc + 1) * sizeof(char*)); - if (!argv_copy) { - printf("Failed to allocate memory for arguments."); - posix_spawnattr_destroy(&spawnattr); - return; - } - for (int i = 0; i < argc; i++) { - argv_copy[i] = argv[i]; - } - argv_copy[argc] = NULL; - - // Pass along our environment. - char** envp = NULL; - char*** cocoaEnvironment = _NSGetEnviron(); - if (cocoaEnvironment) { - envp = *cocoaEnvironment; - } - - int result = posix_spawnp(NULL, argv_copy[0], NULL, &spawnattr, argv_copy, envp); - - free(argv_copy); - posix_spawnattr_destroy(&spawnattr); - - if (result != 0) { - printf("Process spawn failed with code %d!", result); - } -} - -void -LaunchMacPostProcess(const char* aAppBundle) -{ - // Launch helper to perform post processing for the update; this is the Mac - // analogue of LaunchWinPostProcess (PostUpdateWin). - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString* iniPath = [NSString stringWithUTF8String:aAppBundle]; - iniPath = - [iniPath stringByAppendingPathComponent:@"Contents/Resources/updater.ini"]; - - NSFileManager* fileManager = [NSFileManager defaultManager]; - if (![fileManager fileExistsAtPath:iniPath]) { - // the file does not exist; there is nothing to run - [pool release]; - return; - } - - int readResult; - char values[2][MAX_TEXT_LEN]; - readResult = ReadStrings([iniPath UTF8String], - "ExeRelPath\0ExeArg\0", - 2, - values, - "PostUpdateMac"); - if (readResult) { - [pool release]; - return; - } - - NSString *exeRelPath = [NSString stringWithUTF8String:values[0]]; - NSString *exeArg = [NSString stringWithUTF8String:values[1]]; - if (!exeArg || !exeRelPath) { - [pool release]; - return; - } - - NSString* exeFullPath = [NSString stringWithUTF8String:aAppBundle]; - exeFullPath = [exeFullPath stringByAppendingPathComponent:exeRelPath]; - - char optVals[1][MAX_TEXT_LEN]; - readResult = ReadStrings([iniPath UTF8String], - "ExeAsync\0", - 1, - optVals, - "PostUpdateMac"); - - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:exeFullPath]; - [task setArguments:[NSArray arrayWithObject:exeArg]]; - [task launch]; - if (!readResult) { - NSString *exeAsync = [NSString stringWithUTF8String:optVals[0]]; - if ([exeAsync isEqualToString:@"false"]) { - [task waitUntilExit]; - } - } - // ignore the return value of the task, there's nothing we can do with it - [task release]; - - [pool release]; -} diff --git a/onlineupdate/source/update/updater/loaddlls.cxx b/onlineupdate/source/update/updater/loaddlls.cxx deleted file mode 100644 index 6a0c8a61ee91..000000000000 --- a/onlineupdate/source/update/updater/loaddlls.cxx +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#ifdef _WIN32 -#ifndef UNICODE -#define UNICODE -#endif -#include <windows.h> - -// Delayed load libraries are loaded when the first symbol is used. -// The following ensures that we load the delayed loaded libraries from the -// 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""); - - 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; - } - } - - // TODO: moggi: do we need all that code? - // 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" - }; - -#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" - }; -#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); - - // 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); - } - } -} loadDLLs; -#endif diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Info.plist b/onlineupdate/source/update/updater/macbuild/Contents/Info.plist deleted file mode 100644 index f104b55b9920..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Info.plist +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>updater</string> - <key>CFBundleIconFile</key> - <string>updater.icns</string> - <key>CFBundleIdentifier</key> - <string>org.mozilla.updater</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>NSMainNibFile</key> - <string>MainMenu</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> - <key>LSMinimumSystemVersion</key> - <string>10.5</string> - <key>LSMinimumSystemVersionByArchitecture</key> - <dict> - <key>i386</key> - <string>10.5.0</string> - <key>x86_64</key> - <string>10.6.0</string> - </dict> -</dict> -</plist> diff --git a/onlineupdate/source/update/updater/macbuild/Contents/PkgInfo b/onlineupdate/source/update/updater/macbuild/Contents/PkgInfo deleted file mode 100644 index bd04210fb49f..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/PkgInfo +++ /dev/null @@ -1 +0,0 @@ -APPL????
\ No newline at end of file diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in deleted file mode 100644 index bca4022e755a..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in +++ /dev/null @@ -1,7 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Localized versions of Info.plist keys */ - -CFBundleName = "%APP_NAME% Software Update"; diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib b/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib deleted file mode 100644 index 6cfb50406bcf..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib +++ /dev/null @@ -1,19 +0,0 @@ -{ - IBClasses = ( - { - CLASS = FirstResponder; - LANGUAGE = ObjC; - SUPERCLASS = NSObject; -}, - { - CLASS = UpdaterUI; - LANGUAGE = ObjC; - OUTLETS = { - progressBar = NSProgressIndicator; - progressTextField = NSTextField; - }; - SUPERCLASS = NSObject; -} - ); - IBVersion = 1; -}
\ No newline at end of file diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib b/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib deleted file mode 100644 index 15091783707b..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBDocumentLocation</key> - <string>111 162 356 240 0 0 1440 878 </string> - <key>IBEditorPositions</key> - <dict> - <key>29</key> - <string>106 299 84 44 0 0 1440 878 </string> - </dict> - <key>IBFramework Version</key> - <string>489.0</string> - <key>IBOpenObjects</key> - <array> - <integer>21</integer> - <integer>29</integer> - </array> - <key>IBSystem Version</key> - <string>10J567</string> -</dict> -</plist> diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib b/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib Binary files differdeleted file mode 100644 index 61ff026009dc..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib +++ /dev/null diff --git a/onlineupdate/source/update/updater/macbuild/Contents/Resources/updater.icns b/onlineupdate/source/update/updater/macbuild/Contents/Resources/updater.icns Binary files differdeleted file mode 100644 index d7499c6692db..000000000000 --- a/onlineupdate/source/update/updater/macbuild/Contents/Resources/updater.icns +++ /dev/null diff --git a/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx b/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx deleted file mode 100644 index 2878aa2f0bb7..000000000000 --- a/onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=8 et : - */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <assert.h> -#include <stdio.h> - -#include <string> - -#include "android/log.h" - -#include "progressui.h" - -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoUpdater" , ## args) - -int InitProgressUI(int *argc, char ***argv) -{ - return 0; -} - -int ShowProgressUI() -{ - LOG("Starting to apply update ...\n"); - return 0; -} - -void QuitProgressUI() -{ - 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; - std::string bars(numBars, '='); - std::string spaces(numSpaces, ' '); - LOG("Progress [ %s%s ]\n", bars.c_str(), spaces.c_str()); -} diff --git a/onlineupdate/source/update/updater/progressui-unused/progressui_osx.mm b/onlineupdate/source/update/updater/progressui-unused/progressui_osx.mm deleted file mode 100644 index 8e3ce01eb836..000000000000 --- a/onlineupdate/source/update/updater/progressui-unused/progressui_osx.mm +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#import <Cocoa/Cocoa.h> -#include <stdio.h> -#include <unistd.h> -#include "progressui.h" -#include "readstrings.h" -#include "errors.h" - -#define TIMER_INTERVAL 0.2 - -static float sProgressVal; // between 0 and 100 -static BOOL sQuit = FALSE; -static StringTable sLabels; -static const char *sUpdatePath; - -@interface UpdaterUI : NSObject -{ - IBOutlet NSProgressIndicator *progressBar; - IBOutlet NSTextField *progressTextField; -} -@end - -@implementation UpdaterUI - --(void)awakeFromNib -{ - NSWindow *w = [progressBar window]; - - [w setTitle:[NSString stringWithUTF8String:sLabels.title]]; - [progressTextField setStringValue:[NSString stringWithUTF8String:sLabels.info]]; - - NSRect origTextFrame = [progressTextField frame]; - [progressTextField sizeToFit]; - - int widthAdjust = progressTextField.frame.size.width - origTextFrame.size.width; - - if (widthAdjust > 0) { - NSRect f; - f.size.width = w.frame.size.width + widthAdjust; - f.size.height = w.frame.size.height; - [w setFrame:f display:YES]; - } - - [w center]; - - [progressBar setIndeterminate:NO]; - [progressBar setDoubleValue:0.0]; - - [[NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self - selector:@selector(updateProgressUI:) - userInfo:nil repeats:YES] retain]; - - // Make sure we are on top initially - [NSApp activateIgnoringOtherApps:YES]; -} - -// called when the timer goes off --(void)updateProgressUI:(NSTimer *)aTimer -{ - if (sQuit) { - [aTimer invalidate]; - [aTimer release]; - - // It seems to be necessary to activate and hide ourselves before we stop, - // otherwise the "run" method will not return until the user focuses some - // other app. The activate step is necessary if we are not the active app. - // This is a big hack, but it seems to do the trick. - [NSApp activateIgnoringOtherApps:YES]; - [NSApp hide:self]; - [NSApp stop:self]; - } - - float progress = sProgressVal; - - [progressBar setDoubleValue:(double)progress]; -} - -// leave this as returning a BOOL instead of NSApplicationTerminateReply -// for backward compatibility -- (BOOL)applicationShouldTerminate:(NSApplication *)sender -{ - return sQuit; -} - -@end - -int -InitProgressUI(int *pargc, char ***pargv) -{ - sUpdatePath = (*pargv)[1]; - - return 0; -} - -int -ShowProgressUI() -{ - // 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; - - char path[PATH_MAX]; - snprintf(path, sizeof(path), "%s/updater.ini", sUpdatePath); - if (ReadStrings(path, &sLabels) != OK) - return -1; - - // Continue the update without showing the Progress UI if any of the supplied - // strings are larger than MAX_TEXT_LEN (Bug 628829). - if (!(strlen(sLabels.title) < MAX_TEXT_LEN - 1 && - strlen(sLabels.info) < MAX_TEXT_LEN - 1)) - return -1; - - [NSApplication sharedApplication]; - [NSBundle loadNibNamed:@"MainMenu" owner:NSApp]; - [NSApp run]; - - return 0; -} - -// Called on a background thread -void -QuitProgressUI() -{ - sQuit = TRUE; -} - -// Called on a background thread -void -UpdateProgressUI(float progress) -{ - sProgressVal = progress; // 32-bit writes are atomic -} diff --git a/onlineupdate/source/update/updater/progressui.h b/onlineupdate/source/update/updater/progressui.h deleted file mode 100644 index a3e4913fc32f..000000000000 --- a/onlineupdate/source/update/updater/progressui.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef PROGRESSUI_H__ -#define PROGRESSUI_H__ - -#include "updatedefines.h" -#include "types.hxx" - -#if defined(_WIN32) -#define NS_main wmain -#else -#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(); -#else -// Called on the main thread at startup -int ShowProgressUI(); -#endif -// May be called from any thread -void QuitProgressUI(); - -// May be called from any thread: progress is a number between 0 and 100 -void UpdateProgressUI(float progress); - -#endif // PROGRESSUI_H__ diff --git a/onlineupdate/source/update/updater/progressui_gtk.cxx b/onlineupdate/source/update/updater/progressui_gtk.cxx deleted file mode 100644 index 961e4cdd92b9..000000000000 --- a/onlineupdate/source/update/updater/progressui_gtk.cxx +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(UNIX) || defined(MACOSX) -#include <stdio.h> -#include <gtk/gtk.h> -#include <unistd.h> -#include "progressui.h" -#include "readstrings.h" -#include "errors.h" -#include <string.h> -#include "progressui_gtk_icon.h" - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -#define TIMER_INTERVAL 100 - -static float sProgressVal; // between 0 and 100 -static gboolean sQuit = FALSE; -static gboolean sEnableUI; -static guint sTimerID; - -static GtkWidget *sWin; -static GtkWidget *sLabel; -static GtkWidget *sProgressBar; - -static const char *sProgramPath; - -static gboolean -UpdateDialog(gpointer /*data*/) -{ - if (sQuit) - { - gtk_widget_hide(sWin); - gtk_main_quit(); - } - - float progress = sProgressVal; - - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sProgressBar), - progress / 100.0); - - return TRUE; -} - -static gboolean -OnDeleteEvent(GtkWidget * /*widget*/, GdkEvent * /*event*/, gpointer /*user_data*/) -{ - return TRUE; -} - -int -InitProgressUI(int *pargc, char ***pargv) -{ - sProgramPath = (*pargv)[0]; - - sEnableUI = gtk_init_check(pargc, pargv); - return 0; -} - -int -ShowProgressUI() -{ - 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); - - if (sQuit || sProgressVal > 70.0f) - return 0; - - char ini_path[PATH_MAX]; - snprintf(ini_path, sizeof(ini_path), "%s.ini", sProgramPath); - - StringTable strings; - if (ReadStrings(ini_path, &strings) != OK) - { - strcpy(strings.title, "LibreOffice Update"); - strcpy(strings.info, "Please wait while we update your installation."); - } - - sWin = gtk_window_new(GTK_WINDOW_TOPLEVEL); - if (!sWin) - return -1; - - static GdkPixbuf *pixbuf; - - 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_xpm_data (icon_data); - gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf); - g_object_unref(pixbuf); - - GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_box_set_homogeneous(GTK_BOX(vbox), true); - 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); - - 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_main(); - return 0; -} - -// Called on a background thread -void -QuitProgressUI() -{ - sQuit = TRUE; -} - -// Called on a background thread -void -UpdateProgressUI(float progress) -{ - sProgressVal = progress; // 32-bit writes are atomic -} - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -#endif // defined(UNIX) || defined(MACOSX) diff --git a/onlineupdate/source/update/updater/progressui_gtk_icon.h b/onlineupdate/source/update/updater/progressui_gtk_icon.h deleted file mode 100644 index 6660c071f0b1..000000000000 --- a/onlineupdate/source/update/updater/progressui_gtk_icon.h +++ /dev/null @@ -1,205 +0,0 @@ -/* XPM */ -static const char *icon_data[] = { -/* columns rows colors chars-per-pixel */ -"32 32 167 2 ", -" c #915B05", -". c #955F0C", -"X c #95610D", -"o c #8F6013", -"O c #8C601D", -"+ c #966311", -"@ c #9A6615", -"# c #9A6817", -"$ c #9C6B1D", -"% c #8B652A", -"& c #966B26", -"* c #976D28", -"= c #9C7129", -"- c #8E6D34", -"; c #A17025", -": c #A2752E", -"> c #AB7A2B", -", c #A77A34", -"< c #A97C33", -"1 c #8D7751", -"2 c #8D7A57", -"3 c #8A7658", -"4 c #A17D42", -"5 c #8E7E63", -"6 c #AE823B", -"7 c #B88635", -"8 c #B2853B", -"9 c #BB8A3A", -"0 c #C08B36", -"q c #AA864A", -"w c #AF894D", -"e c #BC8D42", -"r c #AA8B57", -"t c #B38F56", -"y c #B79256", -"u c #968468", -"i c #958A73", -"p c #9B8970", -"a c #938D7D", -"s c #9D927A", -"d c #A3916F", -"f c #AD966D", -"g c #B1996D", -"h c #BF9F6E", -"j c #A89473", -"k c #B59D75", -"l c #BEA375", -"z c #C08F42", -"x c #D29E4B", -"c c #C69C5C", -"v c #DBA44D", -"b c #D5A351", -"n c #DCA651", -"m c #DFAA56", -"M c #D8A75A", -"N c #DCAA5B", -"B c #C79E60", -"V c #C09F6E", -"C c #C8A162", -"Z c #CCA66A", -"A c #DEAE62", -"S c #D6AD6E", -"D c #DEB16A", -"F c #C1A272", -"G c #C6AA7E", -"H c #D3AE73", -"J c #D8AF71", -"K c #DEB676", -"L c #D8B47C", -"P c #E2B266", -"I c #E3B36A", -"U c #E5B974", -"Y c #E3BB7C", -"T c #8B8C85", -"R c #8D8E88", -"E c #918F83", -"W c #8F908C", -"Q c #9A9483", -"! c #92938E", -"~ c #98968B", -"^ c #9E9788", -"/ c #939591", -"( c #969894", -") c #9C9A94", -"_ c #9C9E99", -"` c #A19C94", -"' c #A29E99", -"] c #9FA19C", -"[ c #ADA189", -"{ c #B9A486", -"} c #AEA695", -"| c #A1A29C", -" . c #A9A89F", -".. c #B7AE98", -"X. c #A4A6A2", -"o. c #A6A9A4", -"O. c #AAABA7", -"+. c #ACACA9", -"@. c #AEB1AB", -"#. c #B0B2AE", -"$. c #B3B5B1", -"%. c #B6B8B2", -"&. c #B9BBB7", -"*. c #BBBCBA", -"=. c #C3AD8A", -"-. c #CDB288", -";. c #C9B495", -":. c #D3BC96", -">. c #E3BD84", -",. c #E1BF88", -"<. c #D2BEA0", -"1. c #C8BFB0", -"2. c #BFC1BB", -"3. c #D8C095", -"4. c #E5C087", -"5. c #EAC385", -"6. c #E6C289", -"7. c #E8C288", -"8. c #E4C492", -"9. c #E6C99B", -"0. c #EBCD9E", -"q. c #D4C1A5", -"w. c #D8C5A7", -"e. c #CBC2B1", -"r. c #C1C4BE", -"t. c #D1C7B7", -"y. c #DFCEB4", -"u. c #E7CDA5", -"i. c #EDD0A3", -"p. c #E6D0AF", -"a. c #EED5AC", -"s. c #E6D2B0", -"d. c #EDD6B3", -"f. c #EBD7B9", -"g. c #ECD9BC", -"h. c #F3DBB5", -"j. c #C4C5C3", -"k. c #C6C9C3", -"l. c #C9CCC6", -"z. c #CCCDCA", -"x. c #D4CFC3", -"c. c #CFD0CC", -"v. c #D1D2CF", -"b. c #D3D4D3", -"n. c #D6D8D5", -"m. c #DADAD6", -"M. c #DADBDA", -"N. c #E7D8C0", -"B. c #ECDCC2", -"V. c #DFE1DE", -"C. c #F3E1C3", -"Z. c #F2E4CC", -"A. c #ECE2D4", -"S. c #EEE7DA", -"D. c #F1E5D2", -"F. c #F7E9D6", -"G. c #F0E8DC", -"H. c #E3E3E3", -"J. c #E7E8E7", -"K. c #E8E8E7", -"L. c #ECECEB", -"P. c #F4EFE6", -"I. c #F5F1EB", -"U. c #F3F4F3", -"Y. c #F8F5F1", -"T. c #FAF9F7", -"R. c #FFFFFF", -/* pixels */ -"R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.F X ; A.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.< u.H # S.R.R.R.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.T.y.F l R., d.a.Z # G.R.R.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.R.R.R.A.V , + w :., y.< f.Y 8.C # P.R.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.R.R.G : -.N.I.Y.T.t X . f.5.n 4.e # T.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.R.R.$ p.F.Z.Z.D.Y.F ..l s.h.U D 6.# :.R.R.", -"R.R.R.R.R.R.R.R.R.R.R.U.l.* u.d.i.d.B.I.y k 3., C.5.N >.> h R.R.", -"R.R.R.R.R.R.R.R.R.U.%.W ] , 8.0.0.| R T T T T T T ~ Q >.< h R.R.", -"R.R.R.R.R.R.R.R.n.W ] 2.k.q 3.h.a.| v.U.U.L.L.L.L.U.o.9.< V R.R.", -"R.R.R.R.R.R.R.z.R @.j.k.z.q K 6 ) M.R.R.R.R.R.R.R.o.L > F R.R.", -"R.R.R.R.R.R.M.W $.2.k.l.j.r 0.8.6.! b.R.R.R.R.R.R.R.o.p.8 -.R.R.", -"R.R.R.R.R.T.! @.2.k.l.O.W 6 4.I N E j.R.R.R.R.R.$./ T J 9 w.R.R.", -"R.R.R.R.R.*._ 2.r.l.] X.U., Y A v a k.R.R.L.R.R.U.E 0 x 7 w.R.R.", -"R.R.R.R.R.! %.r.k.@.| T.R., Y N v a j.R.R.@.U.R.R.*.r b 7 <.R.R.", -"R.R.R.R.n.! r.k.k.W L.R.R., Y A v f M.R.R.O.&.R.R.H.a M 9 ;.T.R.", -"R.R.R.R.&.X.j.l.$.O.R.R.T., Y P n g M.R.R.o.W R.R.R.R D 9 { L.T.", -"R.R.w + 2 @.l.c. .1 + . q.: >.P m g ! ! / T E L.R.R._ K e j H.R.", -"R.R.6 Z. .%.c.b.' <.a.c =.= Y P m N M M M M s H.R.R.X.>.z u n.T.", -"R.R., Z.} $.v.n.O.=.i.c { * U 7.7.5.7.4.4.4.Q L.R.R.] ,.8 5 n.T.", -"R.R.6 Z...@.n.M.&.[ i.B =.5 . @ @ @ @ @ @ # R T.R.R.! @ o ] V.T.", -"R.R., A.x._ m.V.m.! G.:.;.z.+.' ` ` ` ^ ) W $.R.R.K.T ) $.b.U.R.", -"R.T., L K R m.H.K.#.[ y ;.U.J.H.H.H.H.H.b.W L.R.R.j.+.H.L.U.R.R.", -"R.M.& H A j #.K.L.L.| 1 + # # # # # $ t./ c.R.R.T./ H.R.T.R.R.R.", -"L.O.O S 8.6.W M.U.T.Y.O.) e.g.f.a.w.d ! b.R.R.R.&.+.R.R.R.R.R.R.", -"U.2.% - ( U.T.R.R.M.+.W R T _ *.U.R.R.R.b.( U.R.R.R.R.R.R.", -"R.U.V.n.b.b.b.o._ L.R.R.R.R.R.T.R.R.R.R.R.R.z./ J.R.R.R.R.R.R.R.", -"R.R.R.R.T.R.R.T.j./ c.R.R.R.R.R.R.R.R.R.U.#.( L.R.R.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.R.T.4 ^ ) j.J.T.R.R.U.M.$.! &.T.R.R.R.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.T.M.& H Z g a T R T E i Q L.R.R.R.R.R.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.U.+.O S ,.>.7.>.7.,.6.< 3 H.R.R.R.R.R.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.U.2.% # $ & $ $ $ $ & X p L.R.R.R.R.R.R.R.R.R.R.R.", -"R.R.R.R.R.R.R.R.Y.m.e.1.1.1.1.1.1.e.t.L.R.R.R.R.R.R.R.R.R.R.R.R." -}; diff --git a/onlineupdate/source/update/updater/progressui_null.cxx b/onlineupdate/source/update/updater/progressui_null.cxx deleted file mode 100644 index 66d294a133a0..000000000000 --- a/onlineupdate/source/update/updater/progressui_null.cxx +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if !defined(MACOSX) && !defined(UNIX) && !defined(_WIN32) -#include "progressui.h" - -int InitProgressUI(int *argc, char ***argv) -{ - return 0; -} - -int ShowProgressUI() -{ - return 0; -} - -void QuitProgressUI() -{ -} - -void UpdateProgressUI(float progress) -{ -} -#endif // !defined(MACOSX) && !defined(UNIX) && !defined(_WIN32) diff --git a/onlineupdate/source/update/updater/progressui_win.cxx b/onlineupdate/source/update/updater/progressui_win.cxx deleted file mode 100644 index 7ef23cfabfdf..000000000000 --- a/onlineupdate/source/update/updater/progressui_win.cxx +++ /dev/null @@ -1,348 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#include <stdio.h> -#ifndef UNICODE -#define UNICODE -#endif -#include <windows.h> -#include <commctrl.h> -#include <process.h> -#include <io.h> - -#include "resource.h" -#include "progressui.h" -#include "readstrings.h" -#include "errors.h" - -#define TIMER_ID 1 -#define TIMER_INTERVAL 100 - -#define RESIZE_WINDOW(hwnd, extrax, extray) \ - { \ - RECT windowSize; \ - GetWindowRect(hwnd, &windowSize); \ - SetWindowPos(hwnd, 0, 0, 0, windowSize.right - windowSize.left + extrax, \ - windowSize.bottom - windowSize.top + extray, \ - SWP_NOMOVE | SWP_NOZORDER); \ - } - -#define MOVE_WINDOW(hwnd, dx, dy) \ - { \ - RECT rc; \ - POINT pt; \ - GetWindowRect(hwnd, &rc); \ - pt.x = rc.left; \ - pt.y = rc.top; \ - ScreenToClient(GetParent(hwnd), &pt); \ - SetWindowPos(hwnd, 0, pt.x + dx, pt.y + dy, 0, 0, \ - SWP_NOSIZE | SWP_NOZORDER); \ - } - -static float sProgress; // between 0 and 100 -static BOOL sQuit = FALSE; -static BOOL sIndeterminate = FALSE; -static StringTable sUIStrings; - -static BOOL -GetStringsFile(WCHAR filename[MAX_PATH]) -{ - if (!GetModuleFileNameW(nullptr, filename, MAX_PATH)) - return FALSE; - - WCHAR *dot = wcsrchr(filename, '.'); - if (!dot || wcsicmp(dot + 1, L"exe")) - return FALSE; - - 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, 0); -} - -// The code in this function is from MSDN: -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/usingdialogboxes.asp -static void -CenterDialog(HWND hDlg) -{ - RECT rc, rcOwner, rcDlg; - - // Get the owner window and dialog box rectangles. - HWND desktop = GetDesktopWindow(); - - 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. - - 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. - - 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 ); - } - - // 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); - - ReleaseDC(hWndInfo, hDCInfo); - - CenterDialog(hDlg); // make dialog appear in the center of the screen - - 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); - } - return TRUE; - - case WM_COMMAND: - return TRUE; - } - return FALSE; -} - -int -InitProgressUI(int* /*argc*/, WCHAR*** /*argv*/) -{ - return 0; -} - -/** - * Initializes the progress UI strings - * - * @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)) - { - strcpy(sUIStrings.title, "LibreOffice Update"); - strcpy(sUIStrings.info, "Please wait while we update your installation."); - return 0; - } - - if (_waccess(filename, 04)) - { - strcpy(sUIStrings.title, "LibreOffice Update"); - strcpy(sUIStrings.info, "Please wait while we update your installation."); - return 0; - } - - // If the updater.ini doesn't have the required strings, then we should not - // bother showing UI. - if (ReadStrings(filename, &sUIStrings) != OK) - { - strcpy(sUIStrings.title, "LibreOffice Update"); - strcpy(sUIStrings.info, "Please wait while we update your installation."); - } - - 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; - } - - if (wcslen(appPath) + wcslen(L".Local") >= MAX_PATH) - { - return -1; - } - - wcscat(appPath, L".Local"); - - if (!_waccess(appPath, 04)) - { - return -1; - } - - // 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; - } - - // 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); - } - - 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; -} - -void -QuitProgressUI() -{ - sQuit = TRUE; -} - -void -UpdateProgressUI(float progress) -{ - sProgress = progress; // 32-bit writes are atomic -} -#endif // _WIN32 diff --git a/onlineupdate/source/update/updater/resource.h b/onlineupdate/source/update/updater/resource.h deleted file mode 100644 index 6b6091c7b8bb..000000000000 --- a/onlineupdate/source/update/updater/resource.h +++ /dev/null @@ -1,29 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by updater.rc -// -#define IDD_DIALOG 101 -#define IDC_PROGRESS 1000 -#define IDC_INFO 1002 -#define IDI_DIALOG 1003 -#define TYPE_CERT 512 -#define IDR_PRIMARY_CERT 1004 -#define IDR_BACKUP_CERT 1005 -#define IDS_UPDATER_IDENTITY 1006 -#define IDR_XPCSHELL_CERT 1007 -#define IDR_COMCTL32_MANIFEST 17 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1008 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/onlineupdate/source/update/updater/updater-common.build b/onlineupdate/source/update/updater/updater-common.build deleted file mode 100644 index 6516a4843c43..000000000000 --- a/onlineupdate/source/update/updater/updater-common.build +++ /dev/null @@ -1,119 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -srcs = [ - 'archivereader.cpp', - 'bspatch.cpp', - 'updater.cpp', -] - -have_progressui = 0 - -if CONFIG['VERIFY_MAR_SIGNATURE']: - USE_LIBS += [ - 'verifymar', - ] - -if CONFIG['OS_ARCH'] == 'WINNT': - have_progressui = 1 - srcs += [ - 'loaddlls.cpp', - 'progressui_win.cpp', - 'win_dirent.cpp', - ] - RCINCLUDE = '%supdater.rc' % updater_rel_path - DEFINES['UNICODE'] = True - DEFINES['_UNICODE'] = True - DEFINES['NOMINMAX'] = True - USE_STATIC_LIBS = True - - # Pick up nsWindowsRestart.cpp - LOCAL_INCLUDES += [ - '/toolkit/xre', - ] - USE_LIBS += [ - 'updatecommon-standalone', - ] - OS_LIBS += [ - 'comctl32', - 'ws2_32', - 'shell32', - 'shlwapi', - 'crypt32', - 'advapi32', - ] -elif CONFIG['OS_ARCH'] == 'Linux' and CONFIG['VERIFY_MAR_SIGNATURE']: - USE_LIBS += [ - 'nss', - 'signmar', - 'updatecommon', - ] - OS_LIBS += CONFIG['NSPR_LIBS'] -else: - USE_LIBS += [ - 'updatecommon', - ] - -USE_LIBS += [ - 'mar', -] - -if CONFIG['MOZ_NATIVE_BZ2']: - OS_LIBS += CONFIG['MOZ_BZ2_LIBS'] -else: - USE_LIBS += [ - 'bz2', - ] - -if CONFIG['MOZ_ENABLE_GTK']: - have_progressui = 1 - srcs += [ - 'progressui_gtk.cpp', - ] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - have_progressui = 1 - srcs += [ - 'launchchild_osx.mm', - 'progressui_osx.mm', - ] - OS_LIBS += [ - '-framework Cocoa', - '-framework Security', - ] - -if have_progressui == 0: - srcs += [ - 'progressui_null.cpp', - ] - -SOURCES += sorted(srcs) - -DEFINES['NS_NO_XPCOM'] = True -DISABLE_STL_WRAPPING = True -for var in ('MAR_CHANNEL_ID', 'MOZ_APP_VERSION'): - DEFINES[var] = '"%s"' % CONFIG[var] - -LOCAL_INCLUDES += [ - '/toolkit/mozapps/update/common', - '/xpcom/glue', -] - -DELAYLOAD_DLLS += [ - 'crypt32.dll', - 'comctl32.dll', - 'userenv.dll', - 'wsock32.dll', -] - -if CONFIG['_MSC_VER']: - WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup'] -elif CONFIG['OS_ARCH'] == 'WINNT': - WIN32_EXE_LDFLAGS += ['-municode'] - -if CONFIG['MOZ_WIDGET_GTK']: - CXXFLAGS += CONFIG['TK_CFLAGS'] - OS_LIBS += CONFIG['TK_LIBS'] diff --git a/onlineupdate/source/update/updater/updater-xpcshell/Makefile.in b/onlineupdate/source/update/updater/updater-xpcshell/Makefile.in deleted file mode 100644 index 21364883435f..000000000000 --- a/onlineupdate/source/update/updater/updater-xpcshell/Makefile.in +++ /dev/null @@ -1,32 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# For changes here, also consider ../Makefile.in - -XPCSHELLTESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/toolkit/mozapps/update/tests -MOCHITESTROOT = $(abspath $(DEPTH))/_tests/testing/mochitest/chrome/toolkit/mozapps/update/tests - -include $(topsrcdir)/config/rules.mk - -libs:: -ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) - # Copy for xpcshell tests - $(NSINSTALL) -D $(XPCSHELLTESTROOT)/data/updater-xpcshell.app - rsync -a -C --exclude '*.in' $(srcdir)/../macbuild/Contents $(XPCSHELLTESTROOT)/data/updater-xpcshell.app - sed -e 's/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/' $(srcdir)/../macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \ - iconv -f UTF-8 -t UTF-16 > $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/Resources/English.lproj/InfoPlist.strings - $(NSINSTALL) -D $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/MacOS/updater-xpcshell - $(NSINSTALL) $(PROGRAM) $(XPCSHELLTESTROOT)/data/updater-xpcshell.app/Contents/MacOS - rm -f $(PROGRAM) - rm -Rf $(XPCSHELLTESTROOT)/data/updater.app - mv $(XPCSHELLTESTROOT)/data/updater-xpcshell.app $(XPCSHELLTESTROOT)/data/updater.app - mv $(XPCSHELLTESTROOT)/data/updater.app/Contents/MacOS/updater-xpcshell $(XPCSHELLTESTROOT)/data/updater.app/Contents/MacOS/updater - - # Copy for mochitest chrome tests - rsync -a -C $(XPCSHELLTESTROOT)/data/updater.app $(MOCHITESTROOT)/data/updater.app -else - cp $(PROGRAM) $(XPCSHELLTESTROOT)/data/updater$(BIN_SUFFIX) - cp $(PROGRAM) $(MOCHITESTROOT)/data/updater$(BIN_SUFFIX) -endif diff --git a/onlineupdate/source/update/updater/updater-xpcshell/moz.build b/onlineupdate/source/update/updater/updater-xpcshell/moz.build deleted file mode 100644 index ba5c844cfc10..000000000000 --- a/onlineupdate/source/update/updater/updater-xpcshell/moz.build +++ /dev/null @@ -1,13 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -Program('updater-xpcshell') - -updater_rel_path = '../' -DIST_INSTALL = False -DEFINES['TEST_UPDATER'] = True -include('../updater-common.build') -FAIL_ON_WARNINGS = True diff --git a/onlineupdate/source/update/updater/updater.cxx b/onlineupdate/source/update/updater/updater.cxx deleted file mode 100644 index 321d43a53936..000000000000 --- a/onlineupdate/source/update/updater/updater.cxx +++ /dev/null @@ -1,4594 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Manifest Format - * --------------- - * - * contents = 1*( line ) - * line = method LWS *( param LWS ) CRLF - * CRLF = "\r\n" - * LWS = 1*( " " | "\t" ) - * - * Available methods for the manifest file: - * - * updatev2.manifest - * ----------------- - * method = "add" | "add-if" | "patch" | "patch-if" | "remove" | - * "rmdir" | "rmrfdir" | type - * - * 'type' is the update type (e.g. complete or partial) and when present MUST - * be the first entry in the update manifest. The type is used to support - * downgrades by causing the actions defined in precomplete to be performed. - * - * updatev3.manifest - * ----------------- - * method = "add" | "add-if" | "add-if-not" | "patch" | "patch-if" | - * "remove" | "rmdir" | "rmrfdir" | type - * - * 'add-if-not' adds a file if it doesn't exist. - * - * precomplete - * ----------- - * method = "remove" | "rmdir" - */ -#include "bspatch.h" -#include "progressui.h" -#include "archivereader.h" -#include "readstrings.h" -#include "errors.h" -#include "bzlib.h" -#include <thread> -#include <vector> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <limits.h> -#include <errno.h> -#include <algorithm> -#include <memory> - -#include <config_version.h> - -#include "updatelogging.h" - -#include <onlineupdate/mozilla/Compiler.h> -#include <onlineupdate/mozilla/Types.h> - -#ifdef _WIN32 -#include <comphelper/windowsStart.hxx> -#include "uachelper.h" -#include "pathhash.h" - -// TODO:moggi taken from the mozilla code -- find a better solution -#define INVALID_APPLYTO_DIR_ERROR 74 -#define REMOVE_FILE_SPEC_ERROR 71 -#define INVALID_APPLYTO_DIR_STAGED_ERROR 72 - -#endif - - -// Amount of the progress bar to use in each of the 3 update stages, -// should total 100.0. -#define PROGRESS_PREPARE_SIZE 20.0f -#define PROGRESS_EXECUTE_SIZE 75.0f -#define PROGRESS_FINISH_SIZE 5.0f - -// Amount of time in ms to wait for the parent process to close -#ifdef _WIN32 -#define PARENT_WAIT 5000 -#endif - -#if defined(MACOSX) -// These functions are defined in launchchild_osx.mm -void CleanupElevatedMacUpdate(bool aFailureOccurred); -bool IsOwnedByGroupAdmin(const char* aAppBundle); -bool IsRecursivelyWritable(const char* aPath); -void LaunchChild(int argc, const char** argv); -void LaunchMacPostProcess(const char* aAppBundle); -bool ObtainUpdaterArguments(int* argc, char*** argv); -bool ServeElevatedUpdate(int argc, const char** argv); -void SetGroupOwnershipAndPermissions(const char* aAppBundle); -struct UpdateServerThreadArgs -{ - int argc; - const NS_tchar** argv; -}; -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX LONG_MAX -#endif - -// We want to use execv to invoke the callback executable on platforms where -// we were launched using execv. See nsUpdateDriver.cpp. -#if defined(UNIX) && !defined(MACOSX) -#define USE_EXECV -#endif - -#if defined(VERIFY_MAR_SIGNATURE) && !defined(_WIN32) && !defined(MACOSX) -#include <nss.h> -#include <nspr.h> -#endif - -#ifdef _WIN32 -#ifdef MAINTENANCE_SERVICE -#include "registrycertificates.h" -#endif -BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra); -BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, - LPCWSTR siblingFilePath, - LPCWSTR newFileName); -#include "updatehelper.h" - -// Closes the handle if valid and if the updater is elevated returns with the -// return code specified. This prevents multiple launches of the callback -// application by preventing the elevated process from launching the callback. -#define EXIT_WHEN_ELEVATED(path, handle, retCode) \ -{ \ - if (handle != INVALID_HANDLE_VALUE) { \ - CloseHandle(handle); \ - } \ - if (_waccess(path, F_OK) == 0 && NS_tremove(path) != 0) { \ - LogFinish(); \ - return retCode; \ - } \ -} -#endif - -//----------------------------------------------------------------------------- - -// This variable lives in libbz2. It's declared in bzlib_private.h, so we just -// declare it here to avoid including that entire header file. -#if defined __GNUC__ -extern "C" __attribute__((visibility("default"))) unsigned int BZ2_crc32Table[256]; -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -extern "C" __global unsigned int BZ2_crc32Table[256]; -#else -extern "C" unsigned int BZ2_crc32Table[256]; -#endif - -static unsigned int -crc32(const unsigned char *buf, unsigned int len) -{ - unsigned int crc = 0xffffffffL; - - const unsigned char *end = buf + len; - for (; buf != end; ++buf) - crc = (crc << 8) ^ BZ2_crc32Table[(crc >> 24) ^ *buf]; - - crc = ~crc; - return crc; -} - -//----------------------------------------------------------------------------- - -// A simple stack based container for a FILE struct that closes the -// file descriptor from its destructor. -class AutoFile -{ -public: - explicit AutoFile(FILE* file = nullptr) - : mFile(file) - { - } - - ~AutoFile() - { - if (mFile != nullptr) - fclose(mFile); - } - - AutoFile &operator=(FILE* file) - { - if (mFile != 0) - fclose(mFile); - mFile = file; - return *this; - } - - operator FILE*() - { - return mFile; - } - - FILE* get() - { - return mFile; - } - -private: - FILE* mFile; -}; - -struct MARChannelStringTable -{ - MARChannelStringTable() - { - MARChannelID[0] = '\0'; - } - - char MARChannelID[MAX_TEXT_LEN]; -}; - -//----------------------------------------------------------------------------- - -static NS_tchar* gPatchDirPath; -static NS_tchar gInstallDirPath[MAXPATHLEN]; -static NS_tchar gWorkingDirPath[MAXPATHLEN]; -static bool gSucceeded = false; -static bool sStagedUpdate = false; -static bool sReplaceRequest = false; -static bool sUsingService = false; - -#ifdef _WIN32 -// The current working directory specified in the command line. -static NS_tchar* gDestPath; -static NS_tchar gCallbackRelPath[MAXPATHLEN]; -static NS_tchar gCallbackBackupPath[MAXPATHLEN]; -static NS_tchar gDeleteDirPath[MAXPATHLEN]; -#endif - -static const NS_tchar kWhitespace[] = NS_T(" \t"); -static const NS_tchar kNL[] = NS_T("\r\n"); -static const NS_tchar kQuote[] = NS_T("\""); - -static NS_tchar* -mstrtok(const NS_tchar *delims, NS_tchar **str) -{ - if (!*str || !**str) - { - *str = nullptr; - return nullptr; - } - - // skip leading "whitespace" - NS_tchar *ret = *str; - const NS_tchar *d; - do - { - for (d = delims; *d != NS_T('\0'); ++d) - { - if (*ret == *d) - { - ++ret; - break; - } - } - } - while (*d); - - if (!*ret) - { - *str = ret; - return nullptr; - } - - NS_tchar *i = ret; - do - { - for (d = delims; *d != NS_T('\0'); ++d) - { - if (*i == *d) - { - *i = NS_T('\0'); - *str = ++i; - return ret; - } - } - ++i; - } - while (*i); - - *str = nullptr; - return ret; -} - -#if defined(_WIN32) && defined(MAINTENANCE_SERVICE) -static bool -EnvHasValue(const char *name) -{ - const char *val = getenv(name); - return (val && *val); -} -#endif - -/** - * Converts a relative update path to an absolute path related to the working - * or install directory. Allocates a new NS_tchar[] based path! - * - * @param relpath - * The relative path to convert to a full path. - * @return valid filesystem full path or nullptr if memory allocation fails. - */ -static NS_tchar* -new_absolute_path(const NS_tchar *relpath) -{ - NS_tchar *destpath = sStagedUpdate ? gWorkingDirPath : gInstallDirPath; - size_t lendestpath = NS_tstrlen(destpath); - size_t lenrelpath = NS_tstrlen(relpath); - NS_tchar *s = new NS_tchar[lendestpath + lenrelpath + 2]; - - NS_tchar *c = s; - - NS_tstrcpy(c, destpath); - c += lendestpath; - NS_tstrcat(c, NS_T("/")); - c++; - - NS_tstrcat(c, relpath); - c += lenrelpath; - *c = NS_T('\0'); - return s; -} - -namespace { - -bool is_userprofile_in_instdir() -{ - return false; - /* - // the algorithm is: - // 1.) if userprofile path length is smaller than installation dir, - // the profile is surely not in instdir - // 2.) else comparing the two paths looking only at the installation dir - // characters should yield an equal string - NS_tchar userprofile[MAXPATHLEN]; - NS_tstrcpy(userprofile, gPatchDirPath); - NS_tchar *slash = (NS_tchar *) NS_tstrrchr(userprofile, NS_T('/')); - if (slash) - *slash = NS_T('\0'); - - size_t userprofile_len = NS_tstrlen(userprofile); - size_t installdir_len = NS_tstrlen(gInstallDirPath); - - if (userprofile_len < installdir_len) - return false; - - return NS_tstrncmp(userprofile, gInstallDirPath, installdir_len) == 0; - */ -} - -} - -/** - * Get a pointer in the absolute path, relative to the working or install - * directory. Returns itself, if not absolute or outside of the directory. - * - * @param abs_path - * An absolute path. - * return pointer to the location within fullpath where the relative path starts - * or fullpath itself if it already looks relative. - */ -static const NS_tchar* -get_relative_offset(const NS_tchar *abs_path) -{ - // If the path isn't absolute, just return it as-is. -#ifdef _WIN32 - if (abs_path[1] != ':' && abs_path[2] != '\\') - { -#else - if (abs_path[0] != '/') - { -#endif - return abs_path; - } - - NS_tchar *prefix = sStagedUpdate ? gWorkingDirPath : gInstallDirPath; - - size_t len = NS_tstrlen(prefix); - if (NS_tstrlen(abs_path) <= len) - return abs_path; - if (0 != NS_tstrncmp(abs_path, prefix, len)) - return abs_path; - return abs_path + len + 1; -} - -/** - * Gets the platform specific path and performs simple checks to the path. If - * the path checks don't pass nullptr will be returned. - * - * @param line - * The line from the manifest that contains the path. - * @param isdir - * Whether the path is a directory path. Defaults to false. - * @return valid filesystem path or nullptr if the path checks fail. - */ -static NS_tchar* -get_valid_path(NS_tchar **line, bool isdir = false) -{ - NS_tchar *path = mstrtok(kQuote, line); - 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('/')) - { - 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(':')) - { - LOG(("get_valid_path: path must be relative: " LOG_S, path)); - return nullptr; - } -#endif - - if (isdir) - { - // Directory paths must have a trailing forward slash. - if (path[NS_tstrlen(path) - 1] != NS_T('/')) - { - LOG(("get_valid_path: directory paths must have a trailing forward " \ - "slash: " LOG_S, path)); - return nullptr; - } - - // Remove the trailing forward slash because stat on Windows will return - // ENOENT if the path has a trailing slash. - path[NS_tstrlen(path) - 1] = NS_T('\0'); - } - - // Don't allow relative paths that resolve to a parent directory. - if (NS_tstrstr(path, NS_T("..")) != nullptr) - { - LOG(("get_valid_path: paths must not contain '..': " LOG_S, path)); - return nullptr; - } - - return path; -} - -static NS_tchar* -get_quoted_path(const NS_tchar *path) -{ - size_t lenQuote = NS_tstrlen(kQuote); - size_t lenPath = NS_tstrlen(path); - size_t len = lenQuote + lenPath + lenQuote + 1; - - NS_tchar *s = (NS_tchar *) malloc(len * sizeof(NS_tchar)); - if (!s) - return nullptr; - - NS_tchar *c = s; - NS_tstrcpy(c, kQuote); - c += lenQuote; - NS_tstrcat(c, path); - c += lenPath; - NS_tstrcat(c, kQuote); - c += lenQuote; - *c = NS_T('\0'); - c++; - return s; -} - -static void ensure_write_permissions(const NS_tchar *path) -{ -#ifdef _WIN32 - (void) _wchmod(path, _S_IREAD | _S_IWRITE); -#else - struct stat fs; - if (!stat(path, &fs) && !(fs.st_mode & S_IWUSR)) - { - (void)chmod(path, fs.st_mode | S_IWUSR); - } -#endif -} - -static int ensure_remove(const NS_tchar *path) -{ - ensure_write_permissions(path); - int rv = NS_tremove(path); - if (rv) - LOG(("ensure_remove: failed to remove file: " LOG_S ", rv: %d, err: %d", - 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) -{ - // 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) - { - // This error is benign - return rv; - } - if (!S_ISDIR(sInfo.st_mode)) - { - return ensure_remove(path); - } - - NS_tDIR *dir; - NS_tdirent *entry; - - dir = NS_topendir(path); - if (!dir) - { - LOG(("ensure_remove_recursive: unable to open directory: " LOG_S - ", rv: %d, err: %d", path, rv, errno)); - return rv; - } - - while ((entry = NS_treaddir(dir)) != 0) - { - if (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); - rv = ensure_remove_recursive(childPath); - if (rv && !continueEnumOnFailure) - { - break; - } - } - } - - NS_tclosedir(dir); - - if (rv == OK) - { - ensure_write_permissions(path); - rv = NS_trmdir(path); - if (rv) - { - LOG(("ensure_remove_recursive: unable to remove directory: " LOG_S - ", rv: %d, err: %d", path, rv, errno)); - } - } - return rv; -} - -static bool is_read_only(const NS_tchar *flags) -{ - size_t length = NS_tstrlen(flags); - if (length == 0) - return false; - - // Make sure the string begins with "r" - if (flags[0] != NS_T('r')) - return false; - - // Look for "r+" or "r+b" - if (length > 1 && flags[1] == NS_T('+')) - return false; - - // Look for "rb+" - if (NS_tstrcmp(flags, NS_T("rb+")) == 0) - return false; - - return true; -} - -static FILE* ensure_open(const NS_tchar *path, const NS_tchar *flags, unsigned int options) -{ - ensure_write_permissions(path); - FILE* f = NS_tfopen(path, 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) - { - fclose(f); - } - return nullptr; - } - struct NS_tstat_t ss; - if (NS_tstat(path, &ss) != 0 || ss.st_mode != options) - { - if (f != nullptr) - { - fclose(f); - } - return nullptr; - } - return f; -} - -// Ensure that the directory containing this file exists. -static int ensure_parent_dir(const NS_tchar *path) -{ - int rv = OK; - - NS_tchar *slash = (NS_tchar *) NS_tstrrchr(path, NS_T('/')); - 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) - { - rv = NS_tmkdir(path, 0755); - // If the directory already exists, then ignore the error. - if (rv < 0 && errno != EEXIST) - { - LOG(("ensure_parent_dir: failed to create directory: " LOG_S ", " \ - "err: %d", path, errno)); - rv = WRITE_ERROR; - } - else - { - rv = OK; - } - } - *slash = NS_T('/'); - } - return rv; -} - -#ifdef UNIX -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) - { - LOG(("ensure_copy_symlink: failed to read the link: " LOG_S ", err: %d", - path, errno)); - return READ_ERROR; - } - rv = symlink(target, dest); - if (rv == -1) - { - LOG(("ensure_copy_symlink: failed to create the new link: " LOG_S ", target: " LOG_S " err: %d", - dest, target, errno)); - return READ_ERROR; - } - return 0; -} -#endif - -// Copy the file named path onto a new file named dest. -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) - { - LOG(("ensure_copy: failed to copy the file " LOG_S " over to " LOG_S ", lasterr: %x", - path, dest, GetLastError())); - return WRITE_ERROR_FILE_COPY; - } - return OK; -#else - struct NS_tstat_t ss; - int rv = NS_tlstat(path, &ss); - if (rv) - { - LOG(("ensure_copy: failed to read file status info: " LOG_S ", err: %d", - path, errno)); - return READ_ERROR; - } - -#ifdef UNIX - if (S_ISLNK(ss.st_mode)) - { - return ensure_copy_symlink(path, dest); - } -#endif - - AutoFile infile(ensure_open(path, NS_T("rb"), ss.st_mode)); - if (!infile) - { - LOG(("ensure_copy: failed to open the file for reading: " LOG_S ", err: %d", - path, errno)); - return READ_ERROR; - } - AutoFile outfile(ensure_open(dest, NS_T("wb"), ss.st_mode)); - if (!outfile) - { - LOG(("ensure_copy: failed to open the file for writing: " LOG_S ", err: %d", - dest, errno)); - return WRITE_ERROR; - } - - // This block size was chosen pretty arbitrarily but seems like a reasonable - // compromise. For example, the optimal block size on a modern macOS machine - // is 100k */ - const int blockSize = 32 * 1024; - void* buffer = malloc(blockSize); - if (!buffer) - return UPDATER_MEM_ERROR; - - while (!feof(infile.get())) - { - size_t read = fread(buffer, 1, blockSize, infile); - if (ferror(infile.get())) - { - LOG(("ensure_copy: failed to read the file: " LOG_S ", err: %d", - path, errno)); - free(buffer); - return READ_ERROR; - } - - size_t written = 0; - - while (written < read) - { - size_t nCount = read - written; - size_t chunkWritten = fwrite(buffer, 1, nCount, outfile); - if (chunkWritten != nCount) - { - LOG(("ensure_copy: failed to write the file: " LOG_S ", err: %d", - dest, errno)); - free(buffer); - return WRITE_ERROR_FILE_COPY; - } - - written += chunkWritten; - } - } - - rv = NS_tchmod(dest, ss.st_mode); - - free(buffer); - return rv; -#endif -} - -template <unsigned N> -struct copy_recursive_skiplist -{ - NS_tchar paths[N][MAXPATHLEN]; - - void append(unsigned index, const NS_tchar *path, const NS_tchar *suffix) - { - NS_tsnprintf(paths[index], MAXPATHLEN, NS_T("%s/%s"), path, suffix); - } - - void append(unsigned index, const NS_tchar* path) - { - NS_tstrcpy(paths[index], 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; - } - } - return false; - } -}; - -// Copy all of the files and subdirectories under path to a new directory named dest. -// 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) -{ - struct NS_tstat_t sInfo; - int rv = NS_tlstat(path, &sInfo); - if (rv) - { - LOG(("ensure_copy_recursive: path doesn't exist: " LOG_S ", rv: %d, err: %d", - path, rv, errno)); - return READ_ERROR; - } - -#ifdef UNIX - if (S_ISLNK(sInfo.st_mode)) - { - return ensure_copy_symlink(path, dest); - } -#endif - - if (!S_ISDIR(sInfo.st_mode)) - { - return ensure_copy(path, dest); - } - - rv = NS_tmkdir(dest, sInfo.st_mode); - if (rv < 0 && errno != EEXIST) - { - LOG(("ensure_copy_recursive: could not create destination directory: " LOG_S ", rv: %d, err: %d", - path, rv, errno)); - return WRITE_ERROR; - } - - NS_tDIR *dir; - NS_tdirent *entry; - - dir = NS_topendir(path); - if (!dir) - { - LOG(("ensure_copy_recursive: path is not a directory: " LOG_S ", rv: %d, err: %d", - path, rv, errno)); - return READ_ERROR; - } - - while ((entry = NS_treaddir(dir)) != 0) - { - if (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)) - { - continue; - } - NS_tchar childPathDest[MAXPATHLEN]; - NS_tsnprintf(childPathDest, sizeof(childPathDest)/sizeof(childPathDest[0]), - NS_T("%s/%s"), dest, entry->d_name); - rv = ensure_copy_recursive(childPath, childPathDest, skiplist); - if (rv) - { - break; - } - } - } - NS_tclosedir(dir); - return rv; -} - -// 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) -{ - int rv = ensure_parent_dir(dpath); - if (rv) - return rv; - - struct NS_tstat_t spathInfo; - rv = NS_tstat(spath, &spathInfo); - if (rv) - { - LOG(("rename_file: failed to read file status info: " LOG_S ", " \ - "err: %d", spath, errno)); - return READ_ERROR; - } - - 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)); - return RENAME_ERROR_EXPECTED_FILE; - } - else - { - LOG(("rename_file: proceeding to rename the directory")); - } - } - - if (!NS_taccess(dpath, F_OK)) - { - if (ensure_remove(dpath)) - { - LOG(("rename_file: destination file exists and could not be " \ - "removed: " LOG_S, dpath)); - return WRITE_ERROR_DELETE_FILE; - } - } - - if (NS_trename(spath, dpath) != 0) - { - LOG(("rename_file: failed to rename file - src: " LOG_S ", " \ - "dst:" LOG_S ", err: %d", spath, dpath, errno)); - return WRITE_ERROR; - } - - return OK; -} - -#ifdef _WIN32 -// Remove the directory pointed to by path and all of its files and -// sub-directories. If a file is in use move it to the tobedeleted directory -// and attempt to schedule removal of the file on reboot -static int remove_recursive_on_reboot(const NS_tchar *path, const NS_tchar *deleteDir) -{ - struct NS_tstat_t sInfo; - int rv = NS_tlstat(path, &sInfo); - if (rv) - { - // This error is benign - return rv; - } - - 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)) - { - LOG(("remove_recursive_on_reboot: file will be removed on OS reboot: " - LOG_S, rv ? path : tmpDeleteFile)); - } - else - { - LOG(("remove_recursive_on_reboot: failed to schedule OS reboot removal of " - "file: " LOG_S, rv ? path : tmpDeleteFile)); - } - return rv; - } - - NS_tDIR *dir; - NS_tdirent *entry; - - dir = NS_topendir(path); - if (!dir) - { - LOG(("remove_recursive_on_reboot: unable to open directory: " LOG_S - ", rv: %d, err: %d", - path, rv, errno)); - return rv; - } - - while ((entry = NS_treaddir(dir)) != 0) - { - if (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); - // 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 - // no need to log the value since it will have already been logged. - remove_recursive_on_reboot(childPath, deleteDir); - } - } - - NS_tclosedir(dir); - - if (rv == OK) - { - ensure_write_permissions(path); - rv = NS_trmdir(path); - if (rv) - { - LOG(("remove_recursive_on_reboot: unable to remove directory: " LOG_S - ", rv: %d, err: %d", path, rv, errno)); - } - } - return rv; -} -#endif - -//----------------------------------------------------------------------------- - -// Create a backup of the specified file by renaming it. -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); - - return rename_file(path, backup); -} - -// Rename the backup of the specified file that was created by renaming it back -// to the original file. -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_tchar relBackup[MAXPATHLEN]; - NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]), - NS_T("%s") BACKUP_EXT, relPath); - - if (NS_taccess(backup, F_OK)) - { - LOG(("backup_restore: backup file doesn't exist: " LOG_S, relBackup)); - return OK; - } - - return rename_file(backup, path); -} - -// Discard the backup of the specified file that was created by renaming it. -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_tchar relBackup[MAXPATHLEN]; - NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]), - NS_T("%s") BACKUP_EXT, relPath); - - // Nothing to discard - if (NS_taccess(backup, F_OK)) - { - return OK; - } - - int rv = ensure_remove(backup); -#if defined(_WIN32) - 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)) - { - LOG(("backup_discard: failed to rename file:" LOG_S ", dst:" LOG_S, - relBackup, relPath)); - return WRITE_ERROR_DELETE_BACKUP; - } - // The MoveFileEx call to remove the file 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 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)) - { - LOG(("backup_discard: file renamed and will be removed on OS " \ - "reboot: " LOG_S, relPath)); - } - else - { - LOG(("backup_discard: failed to schedule OS reboot removal of " \ - "file: " LOG_S, relPath)); - } - } -#else - if (rv) - return WRITE_ERROR_DELETE_BACKUP; -#endif - - return OK; -} - -// Helper function for post-processing a temporary backup. -static void backup_finish(const NS_tchar *path, const NS_tchar *relPath, - int status) -{ - if (status == OK) - backup_discard(path, relPath); - else - backup_restore(path, relPath); -} - -//----------------------------------------------------------------------------- - -static int DoUpdate(ArchiveReader& ArchiveReader); - -class Action -{ -public: - Action() : mProgressCost(1), mNext(nullptr) { } - virtual ~Action() { } - - virtual int Parse(NS_tchar *line) = 0; - - // Do any preprocessing to ensure that the action can be performed. Execute - // will be called if this Action and all others return OK from this method. - virtual int Prepare() = 0; - - // Perform the operation. Return OK to indicate success. After all actions - // have been executed, Finish will be called. A requirement of Execute is - // that its operation be reversible from Finish. - virtual int Execute() = 0; - - // Finish is called after execution of all actions. If status is OK, then - // all actions were successfully executed. Otherwise, some action failed. - virtual void Finish(int status) = 0; - - int mProgressCost; -private: - Action* mNext; - - friend class ActionList; -}; - -class RemoveFile : public Action -{ -public: - RemoveFile() : mSkip(0) { } - - int Parse(NS_tchar *line); - int Prepare(); - int Execute(); - void Finish(int status); - -private: - std::unique_ptr<const NS_tchar[]> mFile; - std::unique_ptr<NS_tchar[]> mRelPath; - int mSkip; -}; - -int -RemoveFile::Parse(NS_tchar *line) -{ - // format "<deadfile>" - - NS_tchar* validPath = get_valid_path(&line); - if (!validPath) - return PARSE_ERROR; - - mRelPath.reset(new NS_tchar[MAXPATHLEN]); - NS_tstrcpy(mRelPath.get(), validPath); - - mFile.reset(new_absolute_path(validPath)); - if (!mFile) - { - return PARSE_ERROR; - } - - return OK; -} - -int -RemoveFile::Prepare() -{ - // Skip the file if it already doesn't exist. - int rv = NS_taccess(mFile.get(), F_OK); - if (rv) - { - mSkip = 1; - mProgressCost = 0; - return OK; - } - - LOG(("PREPARE REMOVEFILE " LOG_S, mRelPath.get())); - - // Make sure that we're actually a file... - struct NS_tstat_t fileInfo; - rv = NS_tstat(mFile.get(), &fileInfo); - if (rv) - { - LOG(("failed to read file status info: " LOG_S ", err: %d", mFile.get(), - errno)); - return READ_ERROR; - } - - 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) - { - *slash = NS_T('\0'); - rv = NS_taccess(mFile.get(), W_OK); - *slash = NS_T('/'); - } - else - { - rv = NS_taccess(NS_T("."), W_OK); - } - - if (rv) - { - LOG(("access failed: %d", errno)); - return WRITE_ERROR_FILE_ACCESS_DENIED; - } - - return OK; -} - -int -RemoveFile::Execute() -{ - if (mSkip) - return OK; - - LOG(("EXECUTE REMOVEFILE " LOG_S, mRelPath.get())); - - // 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) - { - LOG(("file cannot be removed because it does not exist; skipping")); - mSkip = 1; - return OK; - } - - // Rename the old file. It will be removed in Finish. - rv = backup_create(mFile.get()); - if (rv) - { - LOG(("backup_create failed: %d", rv)); - return rv; - } - - return OK; -} - -void -RemoveFile::Finish(int status) -{ - if (mSkip) - return; - - LOG(("FINISH REMOVEFILE " LOG_S, mRelPath.get())); - - backup_finish(mFile.get(), mRelPath.get(), status); -} - -class RemoveDir : public Action -{ -public: - RemoveDir() : mSkip(0) { } - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); // check that the source dir exists - virtual int Execute(); - virtual void Finish(int status); - -private: - std::unique_ptr<NS_tchar[]> mDir; - std::unique_ptr<NS_tchar[]> mRelPath; - int mSkip; -}; - -int -RemoveDir::Parse(NS_tchar *line) -{ - // format "<deaddir>/" - - NS_tchar* validPath = get_valid_path(&line, true); - if (!validPath) - return PARSE_ERROR; - - mRelPath.reset(new NS_tchar[MAXPATHLEN]); - NS_tstrcpy(mRelPath.get(), validPath); - - mDir.reset(new_absolute_path(validPath)); - if (!mDir) - { - return PARSE_ERROR; - } - - return OK; -} - -int -RemoveDir::Prepare() -{ - // We expect the directory to exist if we are to remove it. - int rv = NS_taccess(mDir.get(), F_OK); - if (rv) - { - mSkip = 1; - mProgressCost = 0; - return OK; - } - - LOG(("PREPARE REMOVEDIR " LOG_S "/", mRelPath.get())); - - // Make sure that we're actually a dir. - struct NS_tstat_t dirInfo; - rv = NS_tstat(mDir.get(), &dirInfo); - if (rv) - { - LOG(("failed to read directory status info: " LOG_S ", err: %d", mRelPath.get(), - errno)); - return READ_ERROR; - } - - 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) - { - LOG(("access failed: %d, %d", rv, errno)); - return WRITE_ERROR_DIR_ACCESS_DENIED; - } - - return OK; -} - -int -RemoveDir::Execute() -{ - if (mSkip) - return OK; - - LOG(("EXECUTE REMOVEDIR " LOG_S "/", mRelPath.get())); - - // 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) - { - LOG(("directory no longer exists; skipping")); - mSkip = 1; - } - - return OK; -} - -void -RemoveDir::Finish(int status) -{ - if (mSkip || status != OK) - return; - - LOG(("FINISH REMOVEDIR " LOG_S "/", mRelPath.get())); - - // 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) - { - LOG(("directory no longer exists; skipping")); - return; - } - - - if (status == OK) - { - if (NS_trmdir(mDir.get())) - { - LOG(("non-fatal error removing directory: " LOG_S "/, rv: %d, err: %d", - mRelPath.get(), rv, errno)); - } - } -} - -class AddFile : public Action -{ -public: - AddFile(ArchiveReader& ar) : mAdded(false), mArchiveReader(ar) { } - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); - virtual int Execute(); - virtual void Finish(int status); - -private: - std::unique_ptr<NS_tchar[]> mFile; - std::unique_ptr<NS_tchar[]> mRelPath; - bool mAdded; - ArchiveReader& mArchiveReader; -}; - -int -AddFile::Parse(NS_tchar *line) -{ - // format "<newfile>" - - NS_tchar* validPath = get_valid_path(&line); - if (!validPath) - return PARSE_ERROR; - - mRelPath.reset(new NS_tchar[MAXPATHLEN]); - NS_tstrcpy(mRelPath.get(), validPath); - - mFile.reset(new_absolute_path(validPath)); - if (!mFile) - { - return PARSE_ERROR; - } - - return OK; -} - -int -AddFile::Prepare() -{ - LOG(("PREPARE ADD " LOG_S, mRelPath.get())); - - return OK; -} - -int -AddFile::Execute() -{ - LOG(("EXECUTE ADD " LOG_S, mRelPath.get())); - - int rv; - - // First make sure that we can actually get rid of any existing file. - rv = NS_taccess(mFile.get(), F_OK); - if (rv == 0) - { - rv = backup_create(mFile.get()); - if (rv) - return rv; - } - else - { - rv = ensure_parent_dir(mFile.get()); - if (rv) - return rv; - } - -#ifdef _WIN32 - char sourcefile[MAXPATHLEN]; - if (!WideCharToMultiByte(CP_UTF8, 0, mRelPath.get(), -1, sourcefile, - MAXPATHLEN, nullptr, nullptr)) - { - LOG(("error converting wchar to utf8: %d", GetLastError())); - return STRING_CONVERSION_ERROR; - } - - rv = mArchiveReader.ExtractFile(sourcefile, mFile.get()); -#else - rv = mArchiveReader.ExtractFile(mRelPath.get(), mFile.get()); -#endif - if (!rv) - { - mAdded = true; - } - return rv; -} - -void -AddFile::Finish(int status) -{ - LOG(("FINISH ADD " LOG_S, mRelPath.get())); - // When there is an update failure and a file has been added it is removed - // here since there might not be a backup to replace it. - if (status && mAdded) - NS_tremove(mFile.get()); - backup_finish(mFile.get(), mRelPath.get(), status); -} - -class PatchFile : public Action -{ -public: - PatchFile(ArchiveReader& ar) : mPatchFile(nullptr), mPatchIndex(-1), buf(nullptr), mArchiveReader(ar) { } - - virtual ~PatchFile(); - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); // should check for patch file and for checksum here - virtual int Execute(); - virtual void Finish(int status); - -private: - int LoadSourceFile(FILE* ofile); - - static int sPatchIndex; - - const NS_tchar *mPatchFile; - std::unique_ptr<NS_tchar> mFile; - std::unique_ptr<NS_tchar> mFileRelPath; - int mPatchIndex; - MBSPatchHeader header; - unsigned char *buf; - NS_tchar spath[MAXPATHLEN]; - AutoFile mPatchStream; - ArchiveReader& mArchiveReader; -}; - -int PatchFile::sPatchIndex = 0; - -PatchFile::~PatchFile() -{ - // Make sure mPatchStream gets unlocked on Windows; the system will do that, - // but not until some indeterminate future time, and we want determinism. - // 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) - { - UnlockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), (DWORD)0, (DWORD)0, (DWORD)-1, (DWORD)-1); - } -#endif - - // delete the temporary patch file - if (spath[0]) - NS_tremove(spath); - - if (buf) - free(buf); -} - -int -PatchFile::LoadSourceFile(FILE* ofile) -{ - struct stat os; - int rv = fstat(fileno((FILE *)ofile), &os); - if (rv) - { - LOG(("LoadSourceFile: unable to stat destination file: " LOG_S ", " \ - "err: %d", mFileRelPath.get(), errno)); - return READ_ERROR; - } - - 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)); - return LOADSOURCE_ERROR_WRONG_SIZE; - } - - buf = (unsigned char *) malloc(header.slen); - if (!buf) - return UPDATER_MEM_ERROR; - - size_t r = header.slen; - unsigned char *rb = buf; - while (r) - { - const size_t count = std::min<size_t>(SSIZE_MAX, r); - size_t c = fread(rb, 1, count, ofile); - if (c != count) - { - LOG(("LoadSourceFile: error reading destination file: " LOG_S, - mFileRelPath.get())); - return READ_ERROR; - } - - r -= c; - rb += c; - } - - // Verify that the contents of the source file correspond to what we expect. - - unsigned int crc = crc32(buf, header.slen); - - if (crc != header.scrc32) - { - LOG(("LoadSourceFile: destination file crc %d does not match expected " \ - "crc %d", crc, header.scrc32)); - return CRC_ERROR; - } - - return OK; -} - -int -PatchFile::Parse(NS_tchar *line) -{ - // format "<patchfile>" "<filetopatch>" - - // Get the path to the patch file inside of the mar - mPatchFile = mstrtok(kQuote, &line); - if (!mPatchFile) - return PARSE_ERROR; - - // consume whitespace between args - NS_tchar *q = mstrtok(kQuote, &line); - if (!q) - return PARSE_ERROR; - - NS_tchar* validPath = get_valid_path(&line); - if (!validPath) - return PARSE_ERROR; - mFileRelPath.reset(new NS_tchar[MAXPATHLEN]); - NS_tstrcpy(mFileRelPath.get(), validPath); - - mFile.reset(new_absolute_path(validPath)); - if (!mFile) - { - return PARSE_ERROR; - } - - return OK; -} - -int -PatchFile::Prepare() -{ - LOG(("PREPARE PATCH " LOG_S, mFileRelPath.get())); - - // extract the patch to a temporary file - mPatchIndex = sPatchIndex++; - - int nWrittenBytes = NS_tsnprintf(spath, sizeof(spath)/sizeof(spath[0]), - NS_T("%s/updating/%d.patch"), gWorkingDirPath, mPatchIndex); - (void) nWrittenBytes; - - NS_tremove(spath); - - mPatchStream = NS_tfopen(spath, NS_T("wb+")); - if (!mPatchStream) - return WRITE_ERROR; - -#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)) - { - 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)) - { - LOG(("error converting wchar to utf8: %d", GetLastError())); - return STRING_CONVERSION_ERROR; - } - - int rv = mArchiveReader.ExtractFileToStream(sourcefile, mPatchStream); -#else - int rv = mArchiveReader.ExtractFileToStream(mPatchFile, mPatchStream); -#endif - - return rv; -} - -int -PatchFile::Execute() -{ - LOG(("EXECUTE PATCH " LOG_S, mFileRelPath.get())); - - fseek(mPatchStream, 0, SEEK_SET); - - int rv = MBS_ReadHeader(mPatchStream, &header); - if (rv) - return rv; - - FILE *origfile = nullptr; -#ifdef _WIN32 - 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 - { - origfile = NS_tfopen(mFile.get(), NS_T("rb")); - } -#else - origfile = NS_tfopen(mFile.get(), NS_T("rb")); -#endif - - if (!origfile) - { - LOG(("unable to open destination file: " LOG_S ", err: %d", - mFileRelPath.get(), errno)); - return READ_ERROR; - } - - rv = LoadSourceFile(origfile); - fclose(origfile); - if (rv) - { - LOG(("LoadSourceFile failed")); - return rv; - } - - // Rename the destination file if it exists before proceeding so it can be - // 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) - { - LOG(("failed to read file status info: " LOG_S ", err: %d", - mFileRelPath.get(), errno)); - return READ_ERROR; - } - - rv = backup_create(mFile.get()); - if (rv) - return rv; - -#if defined(HAVE_POSIX_FALLOCATE) - AutoFile ofile(ensure_open(mFile.get(), NS_T("wb+"), ss.st_mode)); - posix_fallocate(fileno((FILE *)ofile), 0, header.dlen); -#elif defined(_WIN32) - bool shouldTruncate = true; - // Creating the file, setting the size, and then closing the file handle - // lessens fragmentation more than any other method tested. Other methods that - // have been tested are: - // 1. _chsize / _chsize_s reduced fragmentation though not completely. - // 2. _get_osfhandle and then setting the size reduced fragmentation though - // 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) - { - if (SetFilePointer(hfile, header.dlen, - 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)); -#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) - { - // 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) - { - ftruncate(fileno((FILE *)ofile), header.dlen); - } -#else - AutoFile ofile(ensure_open(mFile.get(), NS_T("wb+"), ss.st_mode)); -#endif - - if (ofile == nullptr) - { - LOG(("unable to create new file: " LOG_S ", err: %d", mFileRelPath.get(), - errno)); - return WRITE_ERROR_OPEN_PATCH_FILE; - } - -#ifdef _WIN32 - if (!shouldTruncate) - { - fseek(ofile, 0, SEEK_SET); - } -#endif - - rv = MBS_ApplyPatch(&header, mPatchStream, buf, ofile); - - // Go ahead and do a bit of cleanup now to minimize runtime overhead. - // Make sure mPatchStream gets unlocked on Windows; the system will do that, - // but not until some indeterminate future time, and we want determinism. -#ifdef _WIN32 - UnlockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), (DWORD)0, (DWORD)0, (DWORD)-1, (DWORD)-1); -#endif - // Set mPatchStream to nullptr to make AutoFile close the file, - // so it can be deleted on Windows. - mPatchStream = nullptr; - NS_tremove(spath); - spath[0] = NS_T('\0'); - free(buf); - buf = nullptr; - return rv; -} - -void -PatchFile::Finish(int status) -{ - LOG(("FINISH PATCH " LOG_S, mFileRelPath.get())); - - backup_finish(mFile.get(), mFileRelPath.get(), status); -} - -class AddIfFile : public AddFile -{ -public: - AddIfFile(ArchiveReader& archiveReader); - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); - virtual int Execute(); - virtual void Finish(int status); - -protected: - std::unique_ptr<NS_tchar[]> mTestFile; -}; - -AddIfFile::AddIfFile(ArchiveReader& archiveReader): - AddFile(archiveReader) -{ -} - -int -AddIfFile::Parse(NS_tchar *line) -{ - // format "<testfile>" "<newfile>" - - mTestFile.reset(new_absolute_path(get_valid_path(&line))); - if (!mTestFile) - return PARSE_ERROR; - - // consume whitespace between args - NS_tchar *q = mstrtok(kQuote, &line); - if (!q) - return PARSE_ERROR; - - return AddFile::Parse(line); -} - -int -AddIfFile::Prepare() -{ - // If the test file does not exist, then skip this action. - if (NS_taccess(mTestFile.get(), F_OK)) - { - mTestFile = nullptr; - return OK; - } - - return AddFile::Prepare(); -} - -int -AddIfFile::Execute() -{ - if (!mTestFile) - return OK; - - return AddFile::Execute(); -} - -void -AddIfFile::Finish(int status) -{ - if (!mTestFile) - return; - - AddFile::Finish(status); -} - -class AddIfNotFile : public AddFile -{ -public: - AddIfNotFile(ArchiveReader& archiveReader); - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); - virtual int Execute(); - virtual void Finish(int status); - -protected: - std::unique_ptr<NS_tchar[]> mTestFile; -}; - -AddIfNotFile::AddIfNotFile(ArchiveReader& archiveReader): - AddFile(archiveReader) -{ -} - -int -AddIfNotFile::Parse(NS_tchar *line) -{ - // format "<testfile>" "<newfile>" - - mTestFile.reset(new_absolute_path(get_valid_path(&line))); - if (!mTestFile) - return PARSE_ERROR; - - // consume whitespace between args - NS_tchar *q = mstrtok(kQuote, &line); - if (!q) - return PARSE_ERROR; - - return AddFile::Parse(line); -} - -int -AddIfNotFile::Prepare() -{ - // If the test file exists, then skip this action. - if (!NS_taccess(mTestFile.get(), F_OK)) - { - mTestFile = NULL; - return OK; - } - - return AddFile::Prepare(); -} - -int -AddIfNotFile::Execute() -{ - if (!mTestFile) - return OK; - - return AddFile::Execute(); -} - -void -AddIfNotFile::Finish(int status) -{ - if (!mTestFile) - return; - - AddFile::Finish(status); -} - -class PatchIfFile : public PatchFile -{ -public: - PatchIfFile(ArchiveReader& archiveReader); - - virtual int Parse(NS_tchar *line); - virtual int Prepare(); // should check for patch file and for checksum here - virtual int Execute(); - virtual void Finish(int status); - -private: - std::unique_ptr<NS_tchar[]> mTestFile; -}; - -PatchIfFile::PatchIfFile(ArchiveReader& archiveReader): - PatchFile(archiveReader) -{ -} - -int -PatchIfFile::Parse(NS_tchar *line) -{ - // format "<testfile>" "<patchfile>" "<filetopatch>" - - mTestFile.reset(new_absolute_path(get_valid_path(&line))); - if (!mTestFile) - return PARSE_ERROR; - - // consume whitespace between args - NS_tchar *q = mstrtok(kQuote, &line); - if (!q) - return PARSE_ERROR; - - return PatchFile::Parse(line); -} - -int -PatchIfFile::Prepare() -{ - // If the test file does not exist, then skip this action. - if (NS_taccess(mTestFile.get(), F_OK)) - { - mTestFile = nullptr; - return OK; - } - - return PatchFile::Prepare(); -} - -int -PatchIfFile::Execute() -{ - if (!mTestFile) - return OK; - - return PatchFile::Execute(); -} - -void -PatchIfFile::Finish(int status) -{ - if (!mTestFile) - return; - - PatchFile::Finish(status); -} - -//----------------------------------------------------------------------------- - -#ifdef _WIN32 - -/** - * Launch the post update application (helper.exe). It takes in the path of the - * callback application to calculate the path of helper.exe. For service updates - * this is called from both the system account and the current user account. - * - * @param installationDir The path to the callback application binary. - * @param updateInfoDir The directory where update info is stored. - * @return true if there was no error starting the process. - */ -bool -LaunchWinPostProcess(const WCHAR *installationDir, - const WCHAR *updateInfoDir) -{ - WCHAR workingDirectory[MAX_PATH + 1] = { L'\0' }; - wcsncpy(workingDirectory, installationDir, MAX_PATH); - - // TODO: moggi: needs adaptation for LibreOffice - // Most likely we don't have the helper method yet. Check if we really need it. - - // 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; - } - - // Verify that exeFile doesn't contain relative paths - if (wcsstr(exefile, L"..") != nullptr) - { - return false; - } - - WCHAR exefullpath[MAX_PATH + 1] = { L'\0' }; - wcsncpy(exefullpath, installationDir, MAX_PATH); - if (!PathAppendSafe(exefullpath, exefile)) - { - return false; - } - -#if !defined(TEST_UPDATER) && defined(MAINTENANCE_SERVICE) - if (sUsingService && - !DoesBinaryMatchAllowedCertificates(installationDir, exefullpath)) - { - return false; - } -#endif - - 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 (sUsingService || - !_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 = 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; -} - -#endif - -static void -LaunchCallbackApp(const NS_tchar *workingDir, - int argc, - NS_tchar **argv, - bool usingService) -{ - putenv(const_cast<char*>("NO_EM_RESTART=")); - putenv(const_cast<char*>("MOZ_LAUNCHED_CHILD=1")); - - // 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) - { - LOG(("Warning: chdir failed")); - } - -#if defined(USE_EXECV) - (void) argc; - (void) usingService; // avoid warnings - execv(argv[0], argv); -#elif defined(MACOSX) - LaunchChild(argc, (const char**)argv); -#elif defined(_WIN32) - // 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) - { - WinLaunchChild(argv[0], argc, argv, nullptr); - } -#else -# warning "Need implementation of LaunchCallbackApp" -#endif -} - -static bool -WriteStatusFile(const char* aStatus) -{ - NS_tchar filename[MAXPATHLEN] = {NS_T('\0')}; -#if defined(_WIN32) - // The temp file is not removed on failure since there is client code that - // will remove it. - GetTempFileNameW(gPatchDirPath, L"sta", 0, filename); -#else - NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]), - NS_T("%s/update.status"), gPatchDirPath); -#endif - - // Make sure that the directory for the update status file exists - if (ensure_parent_dir(filename)) - return false; - - // This is scoped to make the AutoFile close the file so it is possible to - // move the temp file to the update.status file on Windows. - { - AutoFile file(NS_tfopen(filename, NS_T("wb+"))); - if (file == nullptr) - { - return false; - } - - if (fwrite(aStatus, strlen(aStatus), 1, file) != 1) - { - return false; - } - } - -#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) - { - return false; - } -#endif - - return true; -} - -static void -WriteStatusFile(int status) -{ - const char *text; - - char buf[32]; - if (status == OK) - { - if (sStagedUpdate) - { - text = "applied\n"; - } - else - { - text = "succeeded\n"; - } - } - else - { - snprintf(buf, sizeof(buf)/sizeof(buf[0]), "failed: %d\n", status); - text = buf; - } - - WriteStatusFile(text); -} - -#ifdef MAINTENANCE_SERVICE -/* - * Read the update.status file and sets isPendingService to true if - * the status is set to pending-service. - * - * @param isPendingService Out parameter for specifying if the status - * is set to pending-service or not. - * @return true if the information was retrieved and it is pending - * or pending-service. - */ -static bool -IsUpdateStatusPendingService() -{ - NS_tchar filename[MAXPATHLEN]; - NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]), - NS_T("%s/update.status"), gPatchDirPath); - - AutoFile file(NS_tfopen(filename, NS_T("rb"))); - if (file == nullptr) - return false; - - char buf[32] = { 0 }; - fread(buf, sizeof(buf), 1, file); - - const char kPendingService[] = "pending-service"; - const char kAppliedService[] = "applied-service"; - - return (strncmp(buf, kPendingService, - sizeof(kPendingService) - 1) == 0) || - (strncmp(buf, kAppliedService, - sizeof(kAppliedService) - 1) == 0); -} -#endif - -#ifdef _WIN32 -/* - * Read the update.status file and sets isSuccess to true if - * the status is set to succeeded. - * - * @param isSucceeded Out parameter for specifying if the status - * is set to succeeded or not. - * @return true if the information was retrieved and it is succeeded. - */ -static bool -IsUpdateStatusSucceeded(bool &isSucceeded) -{ - isSucceeded = false; - NS_tchar filename[MAXPATHLEN]; - NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]), - NS_T("%s/update.status"), gPatchDirPath); - - AutoFile file(NS_tfopen(filename, NS_T("rb"))); - if (file == nullptr) - return false; - - char buf[32] = { 0 }; - fread(buf, sizeof(buf), 1, file); - - const char kSucceeded[] = "succeeded"; - isSucceeded = strncmp(buf, kSucceeded, - sizeof(kSucceeded) - 1) == 0; - return true; -} -#endif - -/* - * Copy the entire contents of the application installation directory to the - * destination directory for the update process. - * - * @return 0 if successful, an error code otherwise. - */ -static int -CopyInstallDirToDestDir() -{ - // These files should not be copied over to the updated app -#ifdef _WIN32 -#define SKIPLIST_COUNT 4 -#elif defined(MACOSX) -#define SKIPLIST_COUNT 1 -#else -#define SKIPLIST_COUNT 3 -#endif - copy_recursive_skiplist<SKIPLIST_COUNT> skiplist; - - std::unique_ptr<NS_tchar[]> pUserProfile(new NS_tchar[MAXPATHLEN]); - NS_tstrcpy(pUserProfile.get(), gPatchDirPath); - NS_tchar *slash = (NS_tchar *) NS_tstrrchr(pUserProfile.get(), NS_T('/')); - if (slash) - *slash = NS_T('\0'); - - LOG(("ignore user profile directory during copy: " LOG_S, pUserProfile.get())); - - skiplist.append(0, pUserProfile.get()); -#ifndef MACOSX - skiplist.append(1, gInstallDirPath, NS_T("updated")); - skiplist.append(2, gInstallDirPath, NS_T("updates/0")); -#ifdef _WIN32 - skiplist.append(4, gInstallDirPath, NS_T("updated.update_in_progress.lock")); -#endif -#endif - - return ensure_copy_recursive(gInstallDirPath, gWorkingDirPath, skiplist); -} - -/* - * Replace the application installation directory with the destination - * directory in order to finish a staged update task - * - * @return 0 if successful, an error code otherwise. - */ -static int -ProcessReplaceRequest() -{ - // TODO: moggi: handle the user profile in the installation dir also - // during the replacement request - // The replacement algorithm is like this: - // 1. Move destDir to tmpDir. In case of failure, abort. - // 2. Move newDir to destDir. In case of failure, revert step 1 and abort. - // 3. Delete tmpDir (or defer it to the next reboot). - -#ifdef MACOSX - NS_tchar destDir[MAXPATHLEN]; - NS_tsnprintf(destDir, sizeof(destDir)/sizeof(destDir[0]), - NS_T("%s/Contents"), gInstallDirPath); -#elif defined(_WIN32) - // Windows preserves the case of the file/directory names. We use the - // GetLongPathName API in order to get the correct case for the directory - // name, so that if the user has used a different case when launching the - // application, the installation directory's name does not change. - NS_tchar destDir[MAXPATHLEN]; - if (!GetLongPathNameW(gInstallDirPath, destDir, - sizeof(destDir)/sizeof(destDir[0]))) - { - return NO_INSTALLDIR_ERROR; - } -#else - NS_tchar* destDir = gInstallDirPath; -#endif - - NS_tchar tmpDir[MAXPATHLEN]; - NS_tsnprintf(tmpDir, sizeof(tmpDir)/sizeof(tmpDir[0]), - NS_T("%s.bak"), destDir); - - // First try to remove the possibly existing temp directory, because if this - // directory exists, we will fail to rename destDir. - // No need to error check here because if this fails, we will fail in the - // next step anyways. - ensure_remove_recursive(tmpDir); - - LOG(("Begin moving destDir (" LOG_S ") to tmpDir (" LOG_S ")", - destDir, tmpDir)); - LogFlush(); - int rv = rename_file(destDir, tmpDir, true); -#ifdef _WIN32 - // On Windows, if Firefox is launched using the shortcut, it will hold a handle - // to its installation directory open, which might not get released in time. - // Therefore we wait a little bit here to see if the handle is released. - // 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)) - { - LOG(("PerformReplaceRequest: destDir rename attempt %d failed. " \ - "File: " LOG_S ". Last error: %d, err: %d", retries, - destDir, GetLastError(), rv)); - - Sleep(100); - - rv = rename_file(destDir, tmpDir, true); - } -#endif - 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)); - return rv; - } - - NS_tchar newDir[MAXPATHLEN]; - if (is_userprofile_in_instdir()) - { - LOG(("user profile in instdir")); - NS_tstrcpy(newDir, tmpDir); - NS_tstrcat(newDir, gWorkingDirPath + NS_tstrlen(gInstallDirPath)); - LOG((LOG_S, newDir)); - } - else - { - NS_tsnprintf(newDir, sizeof(newDir)/sizeof(newDir[0]), - NS_T("%s"), - gWorkingDirPath); - } - - LOG(("Begin moving newDir (" LOG_S ") to destDir (" LOG_S ")", - newDir, destDir)); - rv = rename_file(newDir, destDir, true); -#ifdef MACOSX - if (rv) - { - LOG(("Moving failed. Begin copying newDir (" LOG_S ") to destDir (" LOG_S ")", - newDir, destDir)); - copy_recursive_skiplist<0> skiplist; - rv = ensure_copy_recursive(newDir, destDir, skiplist); - } -#endif - 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) - { - 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 - // in returning an error specific for this failure. - return rv; - } - - if (is_userprofile_in_instdir()) - { - // 1.) calculate path of the user profile in the backup directory - // 2.) move the user profile from the backup to the install directory - NS_tchar backup_user_profile[MAXPATHLEN]; - NS_tchar userprofile[MAXPATHLEN]; - - NS_tstrcpy(userprofile, gPatchDirPath); - NS_tchar* slash = (NS_tchar *) NS_tstrrchr(userprofile, NS_T('/')); - if (slash) - *slash = NS_T('\0'); - NS_tstrcpy(backup_user_profile, tmpDir); - size_t installdir_len = NS_tstrlen(destDir); - - NS_tstrcat(backup_user_profile, userprofile + installdir_len); - LOG(("copy user profile back from " LOG_S " to " LOG_S, backup_user_profile, userprofile)); - int rv2 = rename_file(backup_user_profile, userprofile); - if (rv2) - { - LOG(("failed to copy user profile back")); - } - if (slash) - *slash = NS_T('/'); - } - -#if !defined(_WIN32) && !defined(MACOSX) - // Platforms that have their updates directory in the installation directory - // need to have the last-update.log and backup-update.log files moved from the - // old installation directory to the new installation directory. - NS_tchar tmpLog[MAXPATHLEN]; - int nWrittenBytes = NS_tsnprintf(tmpLog, sizeof(tmpLog)/sizeof(tmpLog[0]), - NS_T("%s/updates/last-update.log"), tmpDir); - (void) nWrittenBytes; - 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_tremove(destLog); - NS_trename(tmpLog, destLog); - } -#endif - - LOG(("Now, remove the tmpDir")); - rv = ensure_remove_recursive(tmpDir, true); - 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); - // Attempt to remove the tobedeleted directory and then recreate it if it - // was successfully removed. - _wrmdir(deleteDir); - if (NS_taccess(deleteDir, F_OK)) - { - NS_tmkdir(deleteDir, 0755); - } - remove_recursive_on_reboot(tmpDir, deleteDir); -#endif - } - -#ifdef MACOSX - // On macOS, we need to remove the staging directory after its Contents - // directory has been moved. - NS_tchar updatedAppDir[MAXPATHLEN]; - NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir)/sizeof(updatedAppDir[0]), - NS_T("%s/Updated.app"), gPatchDirPath); - ensure_remove_recursive(updatedAppDir); -#endif - - gSucceeded = true; - - return 0; -} - -#ifdef _WIN32 -static void -WaitForServiceFinishThread(void* /*param*/) -{ - // We wait at most 10 minutes, we already waited 5 seconds previously - // before deciding to show this UI. - WaitForServiceStop(SVC_NAME, 595); - QuitProgressUI(); -} -#endif - -#ifdef VERIFY_MAR_SIGNATURE -/** - * This function reads in the ACCEPTED_MAR_CHANNEL_IDS from update-settings.ini - * - * @param path The path to the ini file that is to be read - * @param results A pointer to the location to store the read strings - * @return OK on success - */ -static int -ReadMARChannelIDs(const NS_tchar *path, MARChannelStringTable *results) -{ - // TODO: moggi: needs adaptation for LibreOffice - // Check where this function gets its parameters from - const unsigned int kNumStrings = 1; - const char *kUpdaterKeys = "ACCEPTED_MAR_CHANNEL_IDS\0"; - char updater_strings[kNumStrings][MAX_TEXT_LEN]; - - int result = ReadStrings(path, kUpdaterKeys, kNumStrings, - updater_strings, "Settings"); - - strncpy(results->MARChannelID, updater_strings[0], MAX_TEXT_LEN - 1); - results->MARChannelID[MAX_TEXT_LEN - 1] = 0; - - return result; -} -#endif - -static int -GetUpdateFileNames(std::vector<tstring>& fileNames) -{ - NS_tchar fileName[MAXPATHLEN]; - NS_tsnprintf(fileName, MAXPATHLEN, - NS_T("%s/update.mar"), gPatchDirPath); - fileNames.push_back(fileName); - - // add the language packs - NS_tDIR* dir = NS_topendir(gPatchDirPath); - if (!dir) - { - LOG(("Could not open directory " LOG_S, gPatchDirPath)); - return READ_ERROR; - } - - NS_tdirent* entry; - while ((entry = NS_treaddir(dir)) != nullptr) - { - if (NS_tstrcmp(entry->d_name, NS_T(".")) && - NS_tstrcmp(entry->d_name, NS_T("..")) && - NS_tstrcmp(entry->d_name, NS_T("update.mar"))) - { - if (NS_tstrncmp(entry->d_name, NS_T("update"), 6) == 0) - { - NS_tchar *dot = NS_tstrrchr(entry->d_name, NS_T('.')); - if (dot && !NS_tstrcmp(dot, NS_T(".mar"))) - { - NS_tchar updatePath[MAXPATHLEN]; - NS_tsnprintf(updatePath, sizeof(updatePath)/sizeof(updatePath[0]), - NS_T("%s/%s"), gPatchDirPath, entry->d_name); - - LOG (("Found language update file: " LOG_S, updatePath)); - fileNames.push_back(updatePath); - } - } - } - } - return OK; -} - -static int -CheckSignature(ArchiveReader& archiveReader) -{ -#ifdef VERIFY_MAR_SIGNATURE -#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) - { - 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) - { - wchar_t rasenhFullPath[] = L"%SystemRoot%\\System32\\rsaenh.dll"; - if (RegSetValueExW(baseKey, valueName, 0, REG_SZ, - (const BYTE*)rasenhFullPath, - sizeof(rasenhFullPath)) == ERROR_SUCCESS) - { - reset = true; - } - } - } - } -#endif - int rv = archiveReader.VerifySignature(); -#ifdef _WIN32 - if (baseKey) - { - if (reset) - { - RegSetValueExW(baseKey, valueName, 0, REG_SZ, - (const BYTE*)rasenh, - sizeof(rasenh)); - } - RegCloseKey(baseKey); - } -#endif - - - if (rv == OK) - { - if (rv == OK) - { - NS_tchar updateSettingsPath[MAX_TEXT_LEN]; - - // TODO: moggi: needs adaptation for LibreOffice - // These paths need to be adapted for us. - int nWrittenBytes = NS_tsnprintf(updateSettingsPath, - sizeof(updateSettingsPath) / sizeof(updateSettingsPath[0]), -#ifdef MACOSX - NS_T("%s/Contents/Resources/update-settings.ini"), -#else - NS_T("%s/update-settings.ini"), -#endif - gWorkingDirPath); - (void) nWrittenBytes; - MARChannelStringTable MARStrings; - 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'; - } - - rv = archiveReader.VerifyProductInformation(MARStrings.MARChannelID, - LIBO_VERSION_DOTTED); - } - } -#endif - - return rv; -} - -static void -UpdateThreadFunc(void * /*param*/) -{ - // open ZIP archive and process... - int rv = OK; - if (sReplaceRequest) - { - rv = ProcessReplaceRequest(); - } - else - { - std::vector<tstring> fileNames; - GetUpdateFileNames(fileNames); - - for (auto& fileName: fileNames) - { - ArchiveReader archiveReader; - rv = archiveReader.Open(fileName.c_str()); - if (rv != OK) - { - LOG(("Could not open " LOG_S, fileName.c_str())); - break; - } - - rv = CheckSignature(archiveReader); - if (rv != OK) - { - LOG(("Could not verify the signature of " LOG_S, fileName.c_str())); - break; - } - } - - if (rv == OK && sStagedUpdate) - { - rv = CopyInstallDirToDestDir(); - } - - if (rv == OK) - { - for (auto& fileName: fileNames) - { - ArchiveReader archiveReader; - archiveReader.Open(fileName.c_str()); - rv = DoUpdate(archiveReader); - } - NS_tchar updatingDir[MAXPATHLEN]; - int nWrittenBytes = NS_tsnprintf(updatingDir, sizeof(updatingDir)/sizeof(updatingDir[0]), - NS_T("%s/updating"), gWorkingDirPath); - (void) nWrittenBytes; - ensure_remove_recursive(updatingDir); - } - } - - 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) - { - NS_tchar sysDir[MAX_PATH + 1] = { L'\0' }; - if (GetSystemDirectoryW(sysDir, MAX_PATH + 1)) - { - NS_tchdir(sysDir); - } - } -#endif - ensure_remove_recursive(gWorkingDirPath); - // When attempting to replace the application, we should fall back - // to non-staged updates in case of a failure. We do this by - // setting the status to pending, exiting the updater, and - // launching the callback application. The callback application's - // startup path will see the pending status, and will start the - // updater application again in order to apply the update without - // staging. - if (sReplaceRequest) - { - WriteStatusFile(sUsingService ? "pending-service" : "pending"); - } - 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) - { - LOG(("failed: %d", rv)); - } - else - { -#ifdef MACOSX - // If the update was successful we need to update the timestamp on the - // top-level macOS bundle directory so that macOS's Launch Services - // picks up any major changes when the bundle is updated. - if (!sStagedUpdate && utimes(gInstallDirPath, nullptr) != 0) - { - LOG(("Couldn't set access/modification time on application bundle.")); - } -#endif - - LOG(("succeeded")); - } - WriteStatusFile(rv); - } - - LOG(("calling QuitProgressUI")); - QuitProgressUI(); -} - -#ifdef MACOSX -static void -ServeElevatedUpdateThreadFunc(void* param) -{ - UpdateServerThreadArgs* threadArgs = (UpdateServerThreadArgs*)param; - gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv); - if (!gSucceeded) - { - WriteStatusFile(ELEVATION_CANCELED); - } - QuitProgressUI(); -} - -void freeArguments(int argc, char** argv) -{ - for (int i = 0; i < argc; i++) - { - free(argv[i]); - } - free(argv); -} -#endif - -int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv, - int callbackIndex -#ifdef _WIN32 - , const WCHAR* elevatedLockFilePath - , HANDLE updateLockFileHandle -#elif defined(MACOSX) - , bool isElevated -#endif - ) -{ - if (argc > callbackIndex) - { -#if defined(_WIN32) - if (gSucceeded) - { - if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) - { - fprintf(stderr, "The post update process was not launched"); - } - - // The service update will only be executed if it is already installed. - // For first time installs of the service, the install will happen from - // the PostUpdate process. We do the service update process here - // because it's possible we are updating with updater.exe without the - // 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) - { - StartServiceUpdate(gInstallDirPath); - } - } - EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 0); -#elif defined(MACOSX) - if (!isElevated) - { - if (gSucceeded) - { - LaunchMacPostProcess(gInstallDirPath); - } -#endif - - LaunchCallbackApp(argv[5], - argc - callbackIndex, - argv + callbackIndex, - sUsingService); -#ifdef XP_MACOSX - } // if (!isElevated) -#endif /* XP_MACOSX */ -} -return 0; -} - -int NS_main(int argc, NS_tchar **argv) -{ - // The callback is the remaining arguments starting at callbackIndex. - // The argument specified by callbackIndex is the callback executable and the - // argument prior to callbackIndex is the working directory. - const int callbackIndex = 6; - -#ifdef MACOSX - // TODO: moggi: needs adaptation for LibreOffice - bool isElevated = - strstr(argv[0], "/Library/PrivilegedHelperTools/org.mozilla.updater") != 0; - if (isElevated) - { - if (!ObtainUpdaterArguments(&argc, &argv)) - { - // Won't actually get here because ObtainUpdaterArguments will terminate - // the current process on failure. - return 1; - } - } -#endif - -#if defined(VERIFY_MAR_SIGNATURE) && !defined(_WIN32) && !defined(MACOSX) - // On Windows and Mac we rely on native APIs to do verifications so we don't - // need to initialize NSS at all there. - // Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS - // databases. - if (!NSS_IsInitialized()) - { - if (NSS_NoDB_Init(NULL) != SECSuccess) - { - PRErrorCode error = PR_GetError(); - fprintf(stderr, "Could not initialize NSS: %s (%d)", - PR_ErrorToName(error), (int) error); - _exit(1); - } - } -#endif - -#ifdef MACOSX - if (!isElevated) - { -#endif - InitProgressUI(&argc, &argv); -#ifdef MACOSX - } -#endif - - // To process an update the updater command line must at a minimum have the - // directory path containing the updater.mar file to process as the first - // argument, the install directory as the second argument, and the directory - // to apply the update to as the third argument. When the updater is launched - // by another process the PID of the parent process should be provided in the - // optional fourth argument and the updater will wait on the parent process to - // exit if the value is non-zero and the process is present. This is necessary - // due to not being able to update files that are in use on Windows. The - // optional fifth argument is the callback's working directory and the - // optional sixth argument is the callback path. The callback is the - // application to launch after updating and it will be launched when these - // 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) - { - fprintf(stderr, "Usage: updater patch-dir install-dir apply-to-dir [wait-pid [callback-working-dir callback-path args...]]\n"); -#ifdef MACOSX - if (isElevated) - { - freeArguments(argc, argv); - CleanupElevatedMacUpdate(true); - } -#endif - return 1; - } - - // The directory containing the update information. - gPatchDirPath = argv[1]; - - // The directory we're going to update to. - // We copy this string because we need to remove trailing slashes. The C++ - // standard says that it's always safe to write to strings pointed to by argv - // elements, but I don't necessarily believe it. - NS_tstrncpy(gInstallDirPath, argv[2], MAXPATHLEN); - gInstallDirPath[MAXPATHLEN - 1] = NS_T('\0'); - NS_tchar *slash = NS_tstrrchr(gInstallDirPath, NS_SLASH); - if (slash && !slash[1]) - { - *slash = NS_T('\0'); - } - -#ifdef _WIN32 - bool useService = false; - bool testOnlyFallbackKeyExists = false; - bool noServiceFallback = false; - - // We never want the service to be used unless we build with - // the maintenance service. -#ifdef MAINTENANCE_SERVICE - useService = IsUpdateStatusPendingService(); - // 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. - testOnlyFallbackKeyExists = DoesFallbackKeyExist(); -#endif - - // Remove everything except close window from the context menu - { - // TODO: moggi: needs adaptation 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); - 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) - { - 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); - RegCloseKey(hkApp); - } - } -#endif - - // If there is a PID specified and it is not '0' then wait for the process to exit. -#ifdef _WIN32 - __int64 pid = 0; -#else - int pid = 0; -#endif - if (argc > 4) - { -#ifdef _WIN32 - pid = _wtoi64(argv[4]); -#else - pid = atoi(argv[4]); -#endif - 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"))) - { - // We're processing a request to replace the application with a staged - // update. - sReplaceRequest = true; - } - } - - // The directory we're going to update to. - // We copy this string because we need to remove trailing slashes. The C++ - // standard says that it's always safe to write to strings pointed to by argv - // elements, but I don't necessarily believe it. - NS_tstrncpy(gWorkingDirPath, argv[3], MAXPATHLEN); - gWorkingDirPath[MAXPATHLEN - 1] = NS_T('\0'); - slash = NS_tstrrchr(gWorkingDirPath, NS_SLASH); - if (slash && !slash[1]) - { - *slash = NS_T('\0'); - } - -#ifdef MACOSX - if (!isElevated && !IsRecursivelyWritable(argv[2])) - { - // If the app directory isn't recursively writeable, an elevated update is - // required. - UpdateServerThreadArgs threadArgs; - threadArgs.argc = argc; - threadArgs.argv = const_cast<const NS_tchar**>(argv); - - Thread t1; - if (t1.Run(ServeElevatedUpdateThreadFunc, &threadArgs) == 0) - { - // Show an indeterminate progress bar while an elevated update is in - // progress. - ShowProgressUI(true); - } - t1.Join(); - - LaunchCallbackAndPostProcessApps(argc, argv, callbackIndex, false); - return gSucceeded ? 0 : 1; - } -#endif - - LogInit(gPatchDirPath, NS_T("update.log")); - - if (!WriteStatusFile("applying")) - { - LOG(("failed setting status to 'applying'")); -#ifdef MACOSX - if (isElevated) - { - freeArguments(argc, argv); - CleanupElevatedMacUpdate(true); - } -#endif - return 1; - } - - if (sStagedUpdate) - { - LOG(("Performing a staged update")); - } - else if (sReplaceRequest) - { - LOG(("Performing a replace request")); - } - - LOG(("PATCH DIRECTORY " LOG_S, gPatchDirPath)); - LOG(("INSTALLATION DIRECTORY " LOG_S, gInstallDirPath)); - LOG(("WORKING DIRECTORY " LOG_S, gWorkingDirPath)); - -#ifdef _WIN32 - 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.")); - LogFinish(); - return 1; - } - - NS_tchar workingDirParent[MAX_PATH]; - NS_tsnprintf(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) - { - WriteStatusFile(INVALID_APPLYTO_DIR_STAGED_ERROR); - LOG(("The apply-to directory must be the same as or " - "a child of the installation directory! Exiting.")); - LogFinish(); - return 1; - } - } -#endif - - -#ifdef _WIN32 - 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) - { - DWORD waitTime = PARENT_WAIT; - DWORD result = WaitForSingleObject(parent, waitTime); - CloseHandle(parent); - if (result != WAIT_OBJECT_0) - return 1; - } - } -#else - if (pid > 0) - waitpid(pid, nullptr, 0); -#endif - -#if defined(_WIN32) -#ifdef MAINTENANCE_SERVICE - sUsingService = EnvHasValue("USING_SERVICE"); - putenv(const_cast<char*>("USING_SERVICE=")); -#endif - // lastFallbackError keeps track of the last error for the service not being - // used, in case of an error when fallback is not enabled we write the - // error to the update.status file. - // When fallback is disabled (MOZ_NO_SERVICE_FALLBACK does not exist) then - // we will instead fallback to not using the service and display a UAC prompt. - int lastFallbackError = FALLBACKKEY_UNKNOWN_ERROR; - - // Launch a second instance of the updater with the runas verb on Windows - // when write access is denied to the installation directory. - HANDLE updateLockFileHandle = INVALID_HANDLE_VALUE; - NS_tchar elevatedLockFilePath[MAXPATHLEN] = {NS_T('\0')}; - if (!sUsingService && - (argc > callbackIndex || sStagedUpdate || sReplaceRequest)) - { - NS_tchar updateLockFilePath[MAXPATHLEN]; - 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) - { - // When processing a replace request, the lock file is: - // <install_dir>\..\moz_update_in_progress.lock - NS_tchar installDir[MAXPATHLEN]; - NS_tstrcpy(installDir, gInstallDirPath); - 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 - { - // 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]); - } - - // 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) - { - // Try to fall back to the old way of doing updates if a staged - // update fails. - 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"); - } - LOG(("Update already in progress! Exiting")); - return 1; - } - - updateLockFileHandle = CreateFileW(updateLockFilePath, - 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); - - // Even if a file has no sharing access, you can still get its attributes - bool startedFromUnelevatedUpdater = - GetFileAttributesW(elevatedLockFilePath) != INVALID_FILE_ATTRIBUTES; - - // If we're running from the service, then we were started with the same - // token as the service so the permissions are already dropped. If we're - // running from an elevated updater that was started from an unelevated - // 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) - { - // 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)) - { - if (!_waccess(elevatedLockFilePath, F_OK) && - 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) - { - LOG(("Unable to create elevated lock file! Exiting")); - return 1; - } - - wchar_t *cmdLine = MakeCommandLine(argc - 1, argv + 1); - if (!cmdLine) - { - CloseHandle(elevatedFileHandle); - return 1; - } - - // 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) - { - BOOL isLocal = FALSE; - useService = IsLocalFile(argv[0], isLocal) && isLocal; - } - - // If we have unprompted elevation we should NOT use the service - // for the update. Service updates happen with the SYSTEM account - // which has more privs than we need to update with. - // 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) - { - BOOL 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) - { - WCHAR maintenanceServiceKey[MAX_PATH + 1]; - // TODO: moggi: needs adaptation for LibreOffice - // Most likely the registry part is not correct yet - if (CalculateRegistryPathFromFilePath(gInstallDirPath, - maintenanceServiceKey)) - { - HKEY baseKey = nullptr; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, - maintenanceServiceKey, 0, - KEY_READ | KEY_WOW64_64KEY, - &baseKey) == ERROR_SUCCESS) - { - RegCloseKey(baseKey); - } - else - { -#ifdef TEST_UPDATER - useService = testOnlyFallbackKeyExists; -#endif - if (!useService) - { - lastFallbackError = FALLBACKKEY_NOKEY_ERROR; - } - } - } - else - { - useService = false; - lastFallbackError = FALLBACKKEY_REGPATH_ERROR; - } - } - - // Originally we used to write "pending" to update.status before - // launching the service command. This is no longer needed now - // since the service command is launched from updater.exe. If anything - // fails in between, we can fall back to using the normal update process - // on our own. - - // If we still want to use the service try to launch the service - // command for the update. - 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) - { - bool showProgressUI = false; - // Never show the progress UI when staging updates. - 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. - showProgressUI = !InitProgressUIStrings(); - } - - // 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) - { - std::thread waitThread(WaitForServiceFinishThread, nullptr); - if (showProgressUI) - { - ShowProgressUI(true, false); - } - waitThread.join(); - } - - lastState = WaitForServiceStop(SVC_NAME, 1); - 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 - { - lastFallbackError = FALLBACKKEY_LAUNCH_ERROR; - } - } - - // 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) - { - CloseHandle(updateLockFileHandle); - } - WriteStatusFile("pending"); - return 0; - } - - // If we started the service command, and it finished, check the - // update.status file to make sure it succeeded, and if it did - // we need to manually start the PostUpdate process from the - // current user's session of this unelevated updater.exe the - // 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) - { - bool updateStatusSucceeded = false; - if (IsUpdateStatusSucceeded(updateStatusSucceeded) && - updateStatusSucceeded) - { - if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) - { - fprintf(stderr, "The post update process which runs as the user" - " for service update could not be launched."); - } - } - } - - // If we didn't want to use the service at all, or if an update was - // already happening, or launching the service command failed, then - // launch the elevated updater.exe as we do without the service. - // We don't launch the elevated updater in the case that we did have - // 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) - { - 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; - sinfo.hwnd = nullptr; - sinfo.lpFile = argv[0]; - sinfo.lpParameters = cmdLine; - sinfo.lpVerb = L"runas"; - sinfo.nShow = SW_SHOWNORMAL; - - bool result = ShellExecuteEx(&sinfo); - free(cmdLine); - - if (result) - { - WaitForSingleObject(sinfo.hProcess, INFINITE); - CloseHandle(sinfo.hProcess); - } - else - { - WriteStatusFile(ELEVATION_CANCELED); - } - } - - if (argc > callbackIndex) - { - LaunchCallbackApp(argv[5], argc - callbackIndex, - argv + callbackIndex, sUsingService); - } - - CloseHandle(elevatedFileHandle); - - if (!useService && !noServiceFallback && - 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) - { - // The service command was launched. The service is responsible for - // writing out the update.status file. - if (updateLockFileHandle != INVALID_HANDLE_VALUE) - { - CloseHandle(updateLockFileHandle); - } - return 0; - } - 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 - // have fallback disabled (MOZ_NO_SERVICE_FALLBACK env var exists). - // We only currently use this env var from XPCShell tests. - CloseHandle(updateLockFileHandle); - WriteStatusFile(lastFallbackError); - return 0; - } - } - } -#endif - - if (sStagedUpdate) - { - // When staging updates, blow away the old installation directory and create - // it from scratch. - ensure_remove_recursive(gWorkingDirPath); - } - if (!sReplaceRequest) - { - // Try to create the destination directory if it doesn't exist - int rv = NS_tmkdir(gWorkingDirPath, 0755); - if (rv != OK && errno != EEXIST) - { -#ifdef MACOSX - if (isElevated) - { - freeArguments(argc, argv); - CleanupElevatedMacUpdate(true); - } -#endif - return 1; - } - } - -#ifdef _WIN32 - // For replace requests, we don't need to do any real updates, so this is not - // necessary. - 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)); - if (!destpath) - return 1; - - NS_tchar *c = destpath; - NS_tstrcpy(c, gWorkingDirPath); - c += NS_tstrlen(gWorkingDirPath); - if (gWorkingDirPath[NS_tstrlen(gWorkingDirPath) - 1] != NS_T('/') && - gWorkingDirPath[NS_tstrlen(gWorkingDirPath) - 1] != NS_T('\\')) - { - NS_tstrcat(c, NS_T("/")); - c += NS_tstrlen(NS_T("/")); - } - *c = NS_T('\0'); - c++; - - gDestPath = destpath; - } - - NS_tchar applyDirLongPath[MAXPATHLEN]; - if (!GetLongPathNameW(gWorkingDirPath, applyDirLongPath, - 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) - { - LaunchCallbackApp(argv[5], argc - callbackIndex, - argv + callbackIndex, sUsingService); - } - return 1; - } - - HANDLE callbackFile = INVALID_HANDLE_VALUE; - 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 - // apply-to dir. If we don't have a fully null'ed out buffer it can lead - // to stack corruption which causes crashes and other problems. - NS_tchar callbackLongPath[MAXPATHLEN]; - ZeroMemory(callbackLongPath, sizeof(callbackLongPath)); - NS_tchar *targetPath = argv[callbackIndex]; - NS_tchar buffer[MAXPATHLEN * 2] = { NS_T('\0') }; - size_t bufferLeft = MAXPATHLEN * 2; - 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); - NS_tchar *p = buffer; - NS_tstrncpy(p, argv[callbackIndex], commonPrefixLength); - p += commonPrefixLength; - bufferLeft -= commonPrefixLength; - NS_tstrncpy(p, gInstallDirPath + commonPrefixLength, bufferLeft); - - size_t len = NS_tstrlen(gInstallDirPath + commonPrefixLength); - p += len; - bufferLeft -= len; - *p = NS_T('\\'); - ++p; - bufferLeft--; - *p = NS_T('\0'); - NS_tchar installDir[MAXPATHLEN]; - NS_tstrcpy(installDir, gInstallDirPath); - size_t callbackPrefixLength = PathCommonPrefixW(argv[callbackIndex], - installDir, - nullptr); - NS_tstrncpy(p, argv[callbackIndex] + std::max(callbackPrefixLength, - commonPrefixLength), bufferLeft); - targetPath = buffer; - } - if (!GetLongPathNameW(targetPath, callbackLongPath, - 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) - { - LaunchCallbackApp(argv[5], - argc - callbackIndex, - argv + callbackIndex, - sUsingService); - } - return 1; - } - - // Doing this is only necessary when we're actually applying a patch. - if (!sReplaceRequest) - { - int len = NS_tstrlen(applyDirLongPath); - NS_tchar *s = callbackLongPath; - NS_tchar *d = gCallbackRelPath; - // advance to the apply to directory and advance past the trailing backslash - // if present. - s += len; - if (*s == NS_T('\\')) - ++s; - - // Copy the string and replace backslashes with forward slashes along the - // way. - do - { - if (*s == NS_T('\\')) - *d = NS_T('/'); - else - *d = *s; - ++s; - ++d; - } - 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]); - NS_tremove(gCallbackBackupPath); - 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)); - LogFinish(); - if (copyFileError == ERROR_ACCESS_DENIED) - { - WriteStatusFile(WRITE_ERROR_ACCESS_DENIED); - } - 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 without 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])); - } - } - } - - // 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 -#ifdef XP_MACOSX - && !isElevated -#endif - ) - { - 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 (!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 /* _WIN32 */ - - -#ifdef MACOSX - // When the update is successful remove the precomplete file in the root of - // 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) - { - NS_tchar oldPrecomplete[MAXPATHLEN]; - NS_tsnprintf(oldPrecomplete, sizeof(oldPrecomplete)/sizeof(oldPrecomplete[0]), - 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); - int rv = NS_taccess(oldDistDir, F_OK); - if (!rv) - { - NS_tchar newDistDir[MAXPATHLEN]; - NS_tsnprintf(newDistDir, sizeof(newDistDir)/sizeof(newDistDir[0]), - NS_T("%s/Contents/Resources/distribution"), gInstallDirPath); - rv = NS_taccess(newDistDir, F_OK); - if (!rv) - { - LOG(("New distribution directory already exists... removing old " \ - "distribution directory: " LOG_S, oldDistDir)); - rv = ensure_remove_recursive(oldDistDir); - if (rv) - { - LOG(("Removing old distribution directory failed - err: %d", rv)); - } - } - else - { - LOG(("Moving old distribution directory to new location. src: " LOG_S \ - ", dst:" LOG_S, oldDistDir, newDistDir)); - rv = rename_file(oldDistDir, newDistDir, true); - if (rv) - { - LOG(("Moving old distribution directory to new location failed - " \ - "err: %d", rv)); - } - } - } - } - - if (isElevated) - { - SetGroupOwnershipAndPermissions(gInstallDirPath); - freeArguments(argc, argv); - CleanupElevatedMacUpdate(false); - } - 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 - // for the group to not break updates in the future. - SetGroupOwnershipAndPermissions(gInstallDirPath); - } -#endif /* MACOSX */ - - LogFinish(); - - int retVal = LaunchCallbackAndPostProcessApps(argc, argv, callbackIndex -#ifdef _WIN32 - , elevatedLockFilePath - , updateLockFileHandle -#elif defined(MACOSX) - , isElevated -#endif - ); - - return retVal ? retVal : (gSucceeded ? 0 : 1); -} - -class ActionList -{ -public: - ActionList() : mFirst(nullptr), mLast(nullptr), mCount(0) { } - ~ActionList(); - - void Append(Action* action); - int Prepare(); - int Execute(); - void Finish(int status); - -private: - Action *mFirst; - Action *mLast; - int mCount; -}; - -ActionList::~ActionList() -{ - Action* a = mFirst; - while (a) - { - Action *b = a; - a = a->mNext; - delete b; - } -} - -void -ActionList::Append(Action *action) -{ - if (mLast) - mLast->mNext = action; - else - mFirst = action; - - mLast = action; - mCount++; -} - -int -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) - { - LOG(("empty action list")); - return MAR_ERROR_EMPTY_ACTION_LIST; - } - - Action *a = mFirst; - int i = 0; - while (a) - { - int rv = a->Prepare(); - if (rv) - return rv; - - float percent = float(++i) / float(mCount); - UpdateProgressUI(PROGRESS_PREPARE_SIZE * percent); - - a = a->mNext; - } - - return OK; -} - -int -ActionList::Execute() -{ - int currentProgress = 0, maxProgress = 0; - Action *a = mFirst; - while (a) - { - maxProgress += a->mProgressCost; - a = a->mNext; - } - - a = mFirst; - while (a) - { - int rv = a->Execute(); - if (rv) - { - LOG(("### execution failed")); - return rv; - } - - currentProgress += a->mProgressCost; - float percent = float(currentProgress) / float(maxProgress); - UpdateProgressUI(PROGRESS_PREPARE_SIZE + - PROGRESS_EXECUTE_SIZE * percent); - - a = a->mNext; - } - - return OK; -} - -void -ActionList::Finish(int status) -{ - Action *a = mFirst; - int i = 0; - while (a) - { - a->Finish(status); - - float percent = float(++i) / float(mCount); - UpdateProgressUI(PROGRESS_PREPARE_SIZE + - PROGRESS_EXECUTE_SIZE + - PROGRESS_FINISH_SIZE * percent); - - a = a->mNext; - } - - if (status == OK) - gSucceeded = true; -} - - -#ifdef _WIN32 -int add_dir_entries(const NS_tchar *dirpath, ActionList *list) -{ - int rv = OK; - WIN32_FIND_DATAW finddata; - HANDLE hFindFile; - NS_tchar searchspec[MAXPATHLEN]; - NS_tchar foundpath[MAXPATHLEN]; - - NS_tsnprintf(searchspec, sizeof(searchspec)/sizeof(searchspec[0]), - NS_T("%s*"), dirpath); - std::unique_ptr<const NS_tchar[]> pszSpec(new_absolute_path(searchspec)); - - hFindFile = FindFirstFileW(pszSpec.get(), &finddata); - 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_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]), - NS_T("%s/"), foundpath); - // Recurse into the directory. - rv = add_dir_entries(foundpath, list); - if (rv) - { - LOG(("add_dir_entries error: " LOG_S ", err: %d", foundpath, rv)); - return rv; - } - } - else - { - // Add the file to be removed to the ActionList. - NS_tchar *quotedpath = get_quoted_path(foundpath); - if (!quotedpath) - return PARSE_ERROR; - - Action *action = new RemoveFile(); - rv = action->Parse(quotedpath); - if (rv) - { - LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d", - quotedpath, rv)); - return rv; - } - free(quotedpath); - - list->Append(action); - } - } - while (FindNextFileW(hFindFile, &finddata) != 0); - - FindClose(hFindFile); - { - // Add the directory to be removed to the ActionList. - NS_tchar *quotedpath = get_quoted_path(dirpath); - if (!quotedpath) - return PARSE_ERROR; - - Action *action = new RemoveDir(); - rv = action->Parse(quotedpath); - if (rv) - LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d", - quotedpath, rv)); - else - list->Append(action); - free(quotedpath); - } - } - - return rv; -} - -#elif defined(__sun) -int add_dir_entries(const NS_tchar *dirpath, ActionList *list) -{ - int rv = OK; - NS_tchar foundpath[MAXPATHLEN]; - struct - { - dirent dent_buffer; - char chars[MAXNAMLEN]; - } ent_buf; - struct dirent* ent; - std::unique_ptr<NS_tchar[]> searchpath(new_absolute_path(dirpath)); - - DIR* dir = opendir(searchpath.get()); - if (!dir) - { - LOG(("add_dir_entries error on opendir: " LOG_S ", err: %d", searchpath.get(), - errno)); - return UNEXPECTED_FILE_OPERATION_ERROR; - } - - 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); - struct stat64 st_buf; - int test = stat64(foundpath, &st_buf); - if (test) - { - closedir(dir); - return UNEXPECTED_FILE_OPERATION_ERROR; - } - if (S_ISDIR(st_buf.st_mode)) - { - NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]), - NS_T("%s/"), foundpath); - // Recurse into the directory. - rv = add_dir_entries(foundpath, list); - if (rv) - { - LOG(("add_dir_entries error: " LOG_S ", err: %d", foundpath, rv)); - closedir(dir); - return rv; - } - } - else - { - // Add the file to be removed to the ActionList. - NS_tchar *quotedpath = get_quoted_path(get_relative_offset(foundpath)); - if (!quotedpath) - { - closedir(dir); - return PARSE_ERROR; - } - - Action *action = new RemoveFile(); - rv = action->Parse(quotedpath); - if (rv) - { - LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d", - quotedpath, rv)); - closedir(dir); - return rv; - } - - list->Append(action); - } - } - closedir(dir); - - // Add the directory to be removed to the ActionList. - NS_tchar *quotedpath = get_quoted_path(get_relative_offset(dirpath)); - if (!quotedpath) - return PARSE_ERROR; - - Action *action = new RemoveDir(); - rv = action->Parse(quotedpath); - if (rv) - { - LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d", - quotedpath, rv)); - } - else - { - list->Append(action); - } - - return rv; -} - -#else - -int add_dir_entries(const NS_tchar *dirpath, ActionList *list) -{ - int rv = OK; - FTS *ftsdir; - FTSENT *ftsdirEntry; - std::unique_ptr<NS_tchar[]> searchpath(new_absolute_path(dirpath)); - - // Remove the trailing slash so the paths don't contain double slashes. The - // existence of the slash has already been checked in DoUpdate. - searchpath.get()[NS_tstrlen(searchpath.get()) - 1] = NS_T('\0'); - char* const pathargv[] = {searchpath.get(), nullptr}; - - // 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))) - return UNEXPECTED_FILE_OPERATION_ERROR; - - while ((ftsdirEntry = fts_read(ftsdir)) != nullptr) - { - NS_tchar foundpath[MAXPATHLEN]; - NS_tchar *quotedpath = nullptr; - Action *action = nullptr; - - 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 - - // 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); - quotedpath = get_quoted_path(get_relative_offset(foundpath)); - if (!quotedpath) - { - rv = UPDATER_QUOTED_PATH_MEM_ERROR; - break; - } - action = new RemoveFile(); - rv = action->Parse(quotedpath); - free(quotedpath); - if (!rv) - list->Append(action); - 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); - quotedpath = get_quoted_path(get_relative_offset(foundpath)); - if (!quotedpath) - { - rv = UPDATER_QUOTED_PATH_MEM_ERROR; - break; - } - - action = new RemoveDir(); - rv = action->Parse(quotedpath); - free(quotedpath); - if (!rv) - list->Append(action); - break; - - // Errors - case FTS_DNR: - case FTS_NS: - // 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) - { - rv = OK; - break; - } - // 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; - - case FTS_DC: - rv = UNEXPECTED_FILE_OPERATION_ERROR; - LOG(("add_dir_entries: fts_read() returned FT_DC: " LOG_S, - ftsdirEntry->fts_path)); - break; - - default: - // FTS_D is ignored and FTS_DP is used instead (post-order). - rv = OK; - break; - } - - if (rv != OK) - break; - } - - fts_close(ftsdir); - - return rv; -} -#endif - -static NS_tchar* -GetManifestContents(const NS_tchar *manifest) -{ - AutoFile mfile(NS_tfopen(manifest, NS_T("rb"))); - 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) - { - LOG(("GetManifestContents: error stating manifest file: " LOG_S, manifest)); - return nullptr; - } - - char *mbuf = (char *) malloc(ms.st_size + 1); - if (!mbuf) - return nullptr; - - size_t r = ms.st_size; - char *rb = mbuf; - while (r) - { - const size_t count = std::min<size_t>(SSIZE_MAX, r); - size_t c = fread(rb, 1, count, mfile); - if (c != count) - { - LOG(("GetManifestContents: error reading manifest file: " LOG_S, manifest)); - free(mbuf); - return nullptr; - } - - r -= c; - rb += c; - } - mbuf[ms.st_size] = '\0'; - rb = mbuf; - -#ifndef _WIN32 - return rb; -#else - NS_tchar *wrb = (NS_tchar *) malloc((ms.st_size + 1) * sizeof(NS_tchar)); - if (!wrb) - { - free(mbuf); - return nullptr; - } - - if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, rb, -1, wrb, - ms.st_size + 1)) - { - LOG(("GetManifestContents: error converting utf8 to utf16le: %d", GetLastError())); - free(mbuf); - free(wrb); - return nullptr; - } - free(mbuf); - - return wrb; -#endif -} - -int AddPreCompleteActions(ActionList *list) -{ -#ifdef MACOSX - std::unique_ptr<NS_tchar[]> manifestPath(new_absolute_path( - NS_T("Contents/Resources/precomplete"))); -#else - std::unique_ptr<NS_tchar[]> manifestPath(new_absolute_path( - NS_T("precomplete"))); -#endif - - NS_tchar *rb = GetManifestContents(manifestPath.get()); - if (rb == nullptr) - { - LOG(("AddPreCompleteActions: error getting contents of precomplete " \ - "manifest")); - // Applications aren't required to have a precomplete manifest. The mar - // generation scripts enforce the presence of a precomplete manifest. - return OK; - } - - int rv; - NS_tchar *line; - while ((line = mstrtok(kNL, &rb)) != 0) - { - // skip comments - if (*line == NS_T('#')) - continue; - - NS_tchar *token = mstrtok(kWhitespace, &line); - 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 - { - action = new RemoveFile(); - } - 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 - { - action = new RemoveDir(); - } - else - { - LOG(("AddPreCompleteActions: unknown token: " LOG_S, token)); - return PARSE_ERROR; - } - - if (!action) - return BAD_ACTION_ERROR; - - rv = action->Parse(line); - if (rv) - return rv; - - list->Append(action); - } - - return OK; -} - -int DoUpdate(ArchiveReader& archiveReader) -{ - NS_tchar manifest[MAXPATHLEN]; - int nWrittenBytes = NS_tsnprintf(manifest, sizeof(manifest)/sizeof(manifest[0]), - NS_T("%s/updating/update.manifest"), gWorkingDirPath); - (void) nWrittenBytes; - ensure_parent_dir(manifest); - - // extract the manifest - // TODO: moggi: needs adaptation for LibreOffice - // Why would we need the manifest? Even if we need it why would we need 2? - int rv = archiveReader.ExtractFile("updatev3.manifest", manifest); - if (rv) - { - rv = archiveReader.ExtractFile("updatev2.manifest", manifest); - if (rv) - { - LOG(("DoUpdate: error extracting manifest file")); - return rv; - } - } - - NS_tchar *rb = GetManifestContents(manifest); - NS_tremove(manifest); - if (rb == nullptr) - { - LOG(("DoUpdate: error opening manifest file: " LOG_S, manifest)); - return READ_ERROR; - } - - ActionList list; - NS_tchar *line; - bool isFirstAction = true; - - while ((line = mstrtok(kNL, &rb)) != 0) - { - // skip comments - if (*line == NS_T('#')) - continue; - - NS_tchar *token = mstrtok(kWhitespace, &line); - if (!token) - { - LOG(("DoUpdate: token not found in manifest")); - return PARSE_ERROR; - } - - 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) - { - const NS_tchar *type = mstrtok(kQuote, &line); - LOG(("UPDATE TYPE " LOG_S, type)); - if (NS_tstrcmp(type, NS_T("complete")) == 0) - { - rv = AddPreCompleteActions(&list); - if (rv) - return rv; - } - continue; - } - } - - Action *action = nullptr; - 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 - { - action = new RemoveDir(); - } - else if (NS_tstrcmp(token, NS_T("rmrfdir")) == 0) // rmdir recursive - { - const NS_tchar *reldirpath = mstrtok(kQuote, &line); - if (!reldirpath) - return PARSE_ERROR; - - if (reldirpath[NS_tstrlen(reldirpath) - 1] != NS_T('/')) - return PARSE_ERROR; - - rv = add_dir_entries(reldirpath, &list); - if (rv) - return rv; - - continue; - } - else if (NS_tstrcmp(token, NS_T("add")) == 0) - { - action = new AddFile(archiveReader); - } - else if (NS_tstrcmp(token, NS_T("patch")) == 0) - { - action = new PatchFile(archiveReader); - } - else if (NS_tstrcmp(token, NS_T("add-if")) == 0) // Add if exists - { - action = new AddIfFile(archiveReader); - } - else if (NS_tstrcmp(token, NS_T("add-if-not")) == 0) // Add if not exists - { - action = new AddIfNotFile(archiveReader); - } - else if (NS_tstrcmp(token, NS_T("patch-if")) == 0) // Patch if exists - { - action = new PatchIfFile(archiveReader); - } - else - { - LOG(("DoUpdate: unknown token: " LOG_S, token)); - return PARSE_ERROR; - } - - if (!action) - return BAD_ACTION_ERROR; - - rv = action->Parse(line); - if (rv) - return rv; - - list.Append(action); - } - - rv = list.Prepare(); - if (rv) - return rv; - - rv = list.Execute(); - - list.Finish(rv); - return rv; -} diff --git a/onlineupdate/source/update/updater/updater.exe.comctl32.manifest b/onlineupdate/source/update/updater/updater.exe.comctl32.manifest deleted file mode 100644 index 9a6cdb565fe1..000000000000 --- a/onlineupdate/source/update/updater/updater.exe.comctl32.manifest +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> -<assemblyIdentity - version="1.0.0.0" - processorArchitecture="*" - name="Updater" - type="win32" -/> -<description>Updater</description> -<dependency> - <dependentAssembly> - <assemblyIdentity - type="win32" - name="Microsoft.Windows.Common-Controls" - version="6.0.0.0" - processorArchitecture="*" - publicKeyToken="6595b64144ccf1df" - language="*" - /> - </dependentAssembly> -</dependency> -<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> - <ms_asmv3:security> - <ms_asmv3:requestedPrivileges> - <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" /> - </ms_asmv3:requestedPrivileges> - </ms_asmv3:security> -</ms_asmv3:trustInfo> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - </application> - </compatibility> -</assembly> diff --git a/onlineupdate/source/update/updater/updater.exe.manifest b/onlineupdate/source/update/updater/updater.exe.manifest deleted file mode 100644 index cd229c954109..000000000000 --- a/onlineupdate/source/update/updater/updater.exe.manifest +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> -<assemblyIdentity - version="1.0.0.0" - processorArchitecture="*" - name="Updater" - type="win32" -/> -<description>Updater</description> -<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> - <ms_asmv3:security> - <ms_asmv3:requestedPrivileges> - <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" /> - </ms_asmv3:requestedPrivileges> - </ms_asmv3:security> -</ms_asmv3:trustInfo> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - </application> - </compatibility> -</assembly> diff --git a/onlineupdate/source/update/updater/updater.ico b/onlineupdate/source/update/updater/updater.ico Binary files differdeleted file mode 100644 index 7b20ba3ec3ce..000000000000 --- a/onlineupdate/source/update/updater/updater.ico +++ /dev/null diff --git a/onlineupdate/source/update/updater/updater.png b/onlineupdate/source/update/updater/updater.png Binary files differdeleted file mode 100644 index 9d8c6df7789a..000000000000 --- a/onlineupdate/source/update/updater/updater.png +++ /dev/null diff --git a/onlineupdate/source/update/updater/updater.rc b/onlineupdate/source/update/updater/updater.rc deleted file mode 100644 index d77cea2fee90..000000000000 --- a/onlineupdate/source/update/updater/updater.rc +++ /dev/null @@ -1,137 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Microsoft Visual C++ generated resource script. -// -#ifdef TEST_UPDATER -#include "../resource.h" -#define MANIFEST_PATH "../updater.exe.manifest" -#define COMCTL32_MANIFEST_PATH "../updater.exe.comctl32.manifest" -#define ICON_PATH "../updater.ico" -#else -#include "resource.h" -#define MANIFEST_PATH "updater.exe.manifest" -#define COMCTL32_MANIFEST_PATH "updater.exe.comctl32.manifest" -#define ICON_PATH "updater.ico" -#endif - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winresrc.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// RT_MANIFEST -// - -1 RT_MANIFEST MANIFEST_PATH -IDR_COMCTL32_MANIFEST RT_MANIFEST COMCTL32_MANIFEST_PATH - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -IDI_DIALOG ICON ICON_PATH - - -///////////////////////////////////////////////////////////////////////////// -// -// Embedded an identifier to uniquely identify this as a Mozilla updater. -// - -STRINGTABLE -{ - IDS_UPDATER_IDENTITY, "libreoffice-updater.exe-7bab28a0-0599-4f37-9efe-f7f8b71f05e3" -} - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_DIALOG DIALOGEX 0, 0, 253, 41 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,24,239,10 - LTEXT "",IDC_INFO,7,8,239,13,SS_NOPREFIX -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 246 - TOPMARGIN, 7 - BOTTOMMARGIN, 39 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winresrc.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/onlineupdate/source/update/updater/updater.svg b/onlineupdate/source/update/updater/updater.svg deleted file mode 100644 index 6a3e88563283..000000000000 --- a/onlineupdate/source/update/updater/updater.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="32" viewBox="0 0 32 32.000001" width="32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="5" cy="13.375" gradientTransform="matrix(2.6502653 .00000002 0 1.1249099 -5.937606 7.116442)" gradientUnits="userSpaceOnUse" r="5" xlink:href="#b"/><linearGradient id="b"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity=".487603"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="312.625" x2="312.0625" xlink:href="#d" y1="196.541335" y2="191.797335"/><linearGradient id="d"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><filter id="e" color-interpolation-filters="sRGB" height="1.588154" width="1.259382" x="-.129691" y="-.294077"><feGaussianBlur stdDeviation=".86460582"/></filter><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="17.92817" x2="17.92817" y1="8.43984" y2="5.29526"><stop offset="0" stop-color="#e9b96e"/><stop offset="1" stop-color="#eeeeec"/></linearGradient><linearGradient id="g" gradientTransform="matrix(.06998908 0 0 .06896555 12.18409 2.80365)" gradientUnits="userSpaceOnUse" x1="174.01562" x2="30" y1="236" y2="64"><stop offset="0" stop-color="#c17d11"/><stop offset="1" stop-color="#e9b96e"/></linearGradient><radialGradient id="h" cx="321.86331" cy="70.499977" gradientTransform="matrix(.6227245 0 0 .09677408 -177.2342 3.75694)" gradientUnits="userSpaceOnUse" r="15.500023"><stop offset="0" stop-color="#faefde"/><stop offset=".68321055" stop-color="#e9b96e"/><stop offset="1" stop-color="#e9b96e" stop-opacity="0"/></radialGradient><radialGradient id="i" cx="321.7785" cy="91.857727" gradientTransform="matrix(2.0837843 0 0 .3006166 -644.48535 -10.03444)" gradientUnits="userSpaceOnUse" r="15.5"><stop offset="0" stop-color="#e9b96e"/><stop offset="1" stop-color="#e9b96e" stop-opacity="0"/></radialGradient><radialGradient id="j" cx="323.89844" cy="70.5" gradientTransform="matrix(.3715153 0 0 .3516126 -97.26516 -14.20919)" gradientUnits="userSpaceOnUse" r="15.5" xlink:href="#b"/><linearGradient id="k" gradientTransform="matrix(.3791614 0 0 .6106884 -99.96394 -32.72591)" gradientUnits="userSpaceOnUse" x1="316.90683" x2="322.41666" xlink:href="#d" y1="69.553268" y2="69.553268"/><linearGradient id="l" gradientTransform="matrix(.970062 -.2428574 0 1 -362.71624 -176.92048)" gradientUnits="userSpaceOnUse" x1="394.59244" x2="389.02057" y1="277.23956" y2="280.54391"><stop offset="0" stop-color="#eeeeec"/><stop offset="1" stop-color="#e9b96e"/></linearGradient><linearGradient id="m" gradientTransform="matrix(.3925197 0 0 .6106884 -104.79786 -32.72591)" gradientUnits="userSpaceOnUse" x1="333.88629" x2="326.32867" xlink:href="#d" y1="69.490768" y2="69.490768"/><linearGradient id="n" gradientTransform="matrix(1.0000001 1.0190348 0 1.0165713 -342.71627 -558.00916)" gradientUnits="userSpaceOnUse" x1="373.8385" x2="375.07596" y1="187.7484" y2="181.79832"><stop offset="0" stop-color="#e9b96e"/><stop offset="1" stop-color="#c17d11"/></linearGradient><linearGradient id="o" gradientUnits="userSpaceOnUse" x1="19.53376" x2="22.28376" xlink:href="#b" y1="14.70452" y2="5.98577"/><linearGradient id="p" gradientUnits="userSpaceOnUse" x1="24.81501" x2="27.63508" xlink:href="#b" y1="5.51702" y2="7.37133"/><linearGradient id="q" gradientTransform="matrix(.970062 -.2428574 0 1 -362.71624 -176.92048)" gradientUnits="userSpaceOnUse" x1="391.0188" x2="389.73026" xlink:href="#b" y1="277.72043" y2="279.4614"/><filter id="r" color-interpolation-filters="sRGB" height="1.86087" width="1.2475" x="-.12375" y="-.430435"><feGaussianBlur stdDeviation=".515625"/></filter><radialGradient id="s" cx="5" cy="13.375" gradientTransform="matrix(2.6502653 .00000002 0 1.1249099 1.062394 13.293218)" gradientUnits="userSpaceOnUse" r="5" xlink:href="#b"/><linearGradient id="t" gradientTransform="matrix(1.2807984 0 0 1.2807976 -376.53809 -266.21095)" gradientUnits="userSpaceOnUse" x1="305.62964" x2="299.38138" y1="222.08656" y2="217.11935"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#babdb6"/></linearGradient><rect fill="url(#c)" filter="url(#e)" height="7.056155" opacity=".753425" rx="1.3125" transform="matrix(1.0441942 0 0 1 -306.59321 -176.92048)" width="16" x="306" y="190.17233"/><rect filter="url(#r)" height="2.875" opacity=".579208" rx="1.25" ry="1.4375" transform="matrix(1.15 0 0 1 -591.83312 5.636224)" width="10" x="515.875" y="16.625"/><rect fill="#d9a452" fill-rule="evenodd" height="8.000001" rx=".09427" ry=".094274" stroke="#8f5902" width="9.015612" x="2.798108" y="16.474611"/><rect fill="#e8c48d" fill-rule="evenodd" height="4.1875" rx=".09427" ry=".094274" transform="scale(-1 1)" width="8.125" x="-11.37622" y="16.912111"/><path d="m3.75122 17.412112v6.125h7.125v-6.125z" fill="none" opacity=".439759" stroke="url(#a)"/><path d="m4.2582637 17.108049 7.3125003-.151651-.170181.91895-6.9783737.173896-.1639456 2.064009 7.0710683-.08839.08839 1.149048-8.1317282-.08839-.088388-4.154253z" fill="#f5efe4" fill-rule="evenodd"/><rect filter="url(#r)" height="2.875" opacity=".579208" rx="1.25" ry="1.4375" transform="matrix(1.15 0 0 1 -584.83312 11.636224)" width="10" x="515.875" y="16.625"/><rect fill="#d9a452" fill-rule="evenodd" height="8.000001" rx=".09427" ry=".094274" stroke="#8f5902" width="9.015612" x="9.798108" y="22.651388"/><rect fill="#e8c48d" fill-rule="evenodd" height="4.1875" rx=".09427" ry=".094274" transform="scale(-1 1)" width="8.125" x="-18.376221" y="23.088888"/><path d="m10.75122 23.588888v6.125h7.125v-6.125z" fill="none" opacity=".439759" stroke="url(#s)"/><path d="m11.258264 23.284825 7.3125-.151651-7.18713.986747-.12537 2.170108 7.071068-.08839.08839 1.149048-8.131727-.08839-.08839-4.154253 1.060661.176777z" fill="#f5efe4" fill-rule="evenodd"/><rect fill="url(#f)" height="14.999985" rx="1.016466" stroke="#8f5902" stroke-dashoffset=".5" stroke-linecap="round" stroke-linejoin="round" width="15" x="13.78376" y="4.579536"/><path d="m18.28175 8.07952h7.90593v1.00676h-7.90593z" fill="#fff" opacity=".2"/><path d="m14.7037 10.07952c-.23265 0-.41994.18455-.41994.41378v7.89657.27586c0 .22924.18729.41379.41994.41379h13.16012c.23265 0 .41994-.18455.41994-.41379v-8.17243c0-.22923-.18729-.41378-.41994-.41378z" fill="url(#g)" fill-rule="evenodd"/><path d="m14.78376 5.57952h13v13.00002h-13z" style="opacity:.342342;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:.5;stroke:url(#o)"/><path d="m14.34513 9.07952-.0562 2.96875 13.98983.0312-.0562-3h-13.87753z" fill="url(#h)" fill-rule="evenodd" opacity=".5"/><path d="m14.7037 10.07952c-.23265 0-.41994.18454-.41994.41379v7.89655.27587c0 .22925.18729.41379.41994.41379h13.16012c.23265 0 .41994-.18455.41994-.41379v-8.17242c0-.22925-.18729-.41379-.41994-.41379z" fill="url(#i)" fill-rule="evenodd" opacity=".815315"/><path d="m14.28376 10.07952h14v1h-14z" fill="url(#j)" opacity=".747748"/><path d="m18.28175 7.07952h6.18718v1.00676h-6.18718z" fill="#c17d11" opacity=".40991"/><path d="m16.3849 5.07952c-.0485 0-.0757.0294-.11659.11449-.0409.0851-.0772.2227-.10363.3626l-.88092 4.52291h7v-5z" fill="url(#k)" fill-rule="evenodd" opacity=".468468"/><path d="m13.783748 9.4403349v-3.97196c0-.56176.453339-1.1275045 1.01646-1.2684833l4.955804-1.2406977c.563131-.1409811 1.01647.1977743 1.01647.7595343v3.97196c0 .56176-.453339 1.1275046-1.01647 1.2684857l-4.03474.6503971" fill="url(#l)" stroke="#8f5902" stroke-dashoffset=".5" stroke-linecap="round" stroke-linejoin="round"/><path d="m22.28376 5.07952v5h5l-.99706-4.59925c-.0288-.13456-.0614-.26033-.10264-.32442-.04126-.06408-.0783-.07633-.14664-.07633z" fill="url(#m)" fill-rule="evenodd" opacity=".468468"/><path d="m28.78376 10.14202v-4.03125c0-.57245-.46814-1.48866-1.03125-2.0625l-2.9375-3.03125s-.48496-.76809-1.71875-.4375c-.18373-.00045-.3125.15128-.3125.4375v4.03125c0 .57245.46812 1.48866 1.03125 2.0625l3.00562 2.51312" fill="url(#n)" stroke="#8f5902" stroke-dashoffset=".5" stroke-linecap="round" stroke-linejoin="round"/><path d="m13.271484 6.2226562c-5.2651384 1.0467841-9.271484 5.7180798-9.271484 11.2773438 0 6.321666 5.1783326 11.5 11.5 11.5 6.321667 0 11.5-5.178334 11.5-11.5 0-4.428937-2.546314-8.2880167-6.242188-10.2070312v6.3710932c.779838 1.072341 1.242188 2.393081 1.242188 3.835938 0 3.619464-2.880531 6.5-6.5 6.5s-6.5-2.880536-6.5-6.5c0-2.833183 1.768714-5.206891 4.271484-6.107422z" fill="#888a85"/><g fill="none"><g stroke-linecap="round"><path d="m23.75251 1.52093v3.52734c0 .0439.36048.96696.74609 1.37109l2.77344 2.31055.54297.14649v-2.76563c0-.0443-.36385-.98728-.75391-1.38477a.96884687.96884687 0 0 1 -.004-.004l-2.9375-3.03125a.96884687.96884687 0 0 1 -.12305-.15625s.0335.0321-.043-.01c-.0253-.0139-.15681.009-.20117-.004z" opacity=".572072" stroke="url(#p)" stroke-dashoffset=".5" stroke-linejoin="round"/><path d="m23.69001 1.32952c.14068 1.70518-.31678 3.76924.5625 5.03125" opacity=".414414" stroke="#fff"/><path d="m14.819765 5.2499556v3.16797l1.115949.097569 3.794989-.6258648v-3.86914z" opacity=".716216" stroke="url(#q)" stroke-dashoffset=".5"/></g><path d="m24.78174 9.58626h-5v5" stroke="#888a85" stroke-linecap="square" stroke-width="5"/></g><path d="m13.322266 7.2519531c-4.740376 1.0081786-8.322266 5.2153889-8.322266 10.2480469 0 5.781225 4.7187725 10.5 10.5 10.5 5.781228 0 10.5-4.718775 10.5-10.5 0-4.918766-3.420176-9.0588504-8-10.1875v3.119141c2.91831 1.024849 5 3.787879 5 7.068359 0 4.159904-3.340092 7.499999-7.5 7.5-4.159908 0-7.5-3.340096-7.5-7.5 0-3.399893 2.235404-6.239226 5.322266-7.166016z" fill="url(#t)"/><path d="m24.78174 9.58626h-5v5" fill="none" stroke="#fff" stroke-linecap="square" stroke-width="3"/><path d="m17.281748 7.0863v1 6h1v-6h7v-1h-7z" fill="#888a85"/></svg>
\ No newline at end of file diff --git a/onlineupdate/source/update/updater/win_dirent.cxx b/onlineupdate/source/update/updater/win_dirent.cxx deleted file mode 100644 index 2368613ee42b..000000000000 --- a/onlineupdate/source/update/updater/win_dirent.cxx +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef _WIN32 -#include "win_dirent.h" -#include <errno.h> -#include <string.h> - -// This file implements the minimum set of dirent APIs used by updater.cpp on -// Windows. If updater.cpp is modified to use more of this API, we need to -// implement those parts here too. - -static dirent gDirEnt; - -DIR::DIR(const WCHAR* path) - : 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); -} - -DIR::~DIR() -{ - if (findHandle != INVALID_HANDLE_VALUE) - { - FindClose(findHandle); - } -} - -dirent::dirent() -{ - d_name[0] = L'\0'; -} - -DIR* -opendir(const WCHAR* path) -{ - return new DIR(path); -} - -int -closedir(DIR* dir) -{ - 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; - } - } - 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; -} -#endif diff --git a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx deleted file mode 100644 index 17ee57ec400f..000000000000 --- a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.cxx +++ /dev/null @@ -1,429 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsVersionComparator.h" - -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#if defined(_WIN32) && !defined(UPDATER_NO_STRING_GLUE_STL) -#include <wchar.h> -#include "Char16.h" -#endif - -#ifdef _WIN32 -// from Mozilla's nsAlgorithm.h -template <class T> inline const T& XPCOM_MIN(const T& aA, const T& aB) { return aB < aA ? aB : aA; } -#endif - -struct VersionPart -{ - int32_t numA; - - const char* strB; // NOT null-terminated, can be a null pointer - uint32_t strBlen; - - int32_t numC; - - char* extraD; // null-terminated -}; - -#ifdef _WIN32 -struct VersionPartW -{ - int32_t numA; - - wchar_t* strB; // NOT null-terminated, can be a null pointer - uint32_t strBlen; - - int32_t numC; - - wchar_t* extraD; // null-terminated -}; -#endif - -/** - * Parse a version part into a number and "extra text". - * - * @returns A pointer to the next versionpart, or null if none. - */ -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) - { - 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 = nullptr; - } - } - - return dot; -} - -/** - * Parse a version part into a number and "extra text". - * - * @returns A pointer to the next versionpart, or null if none. - */ -#ifdef _WIN32 -static wchar_t* ParseVP(wchar_t* aPart, VersionPartW& aResult) -{ - wchar_t* dot; - - aResult.numA = 0; - aResult.strB = nullptr; - aResult.strBlen = 0; - aResult.numC = 0; - aResult.extraD = nullptr; - - if (!aPart) - { - return aPart; - } - - 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 (!*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 = nullptr; - } - } - - return dot; -} -#endif - -// compare two null-terminated strings, which may be null pointers -static int32_t ns_strcmp(const char* aStr1, const char* aStr2) -{ - // any string is *before* no string - if (!aStr1) - { - return aStr2 != 0; - } - - if (!aStr2) - { - return -1; - } - - return strcmp(aStr1, aStr2); -} - -// compare two length-specified string, which may be null pointers -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; - } - - 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; - } - - return 1; -} - -// compare two int32_t -static int32_t ns_cmp(int32_t aNum1, int32_t aNum2) -{ - if (aNum1 < aNum2) - { - return -1; - } - - return aNum1 != aNum2; -} - -/** - * Compares two VersionParts - */ -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); -} - -/** - * Compares two VersionParts - */ -#ifdef _WIN32 -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); -} -#endif - -namespace mozilla -{ -#ifdef _WIN32 -int32_t CompareVersions(const wchar_t* aStrA, const wchar_t* aStrB) -{ - wchar_t* A2 = wcsdup(aStrA); - if (!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; - - do - { - VersionPartW va, vb; - - a = ParseVP(a, va); - b = ParseVP(b, vb); - - result = CompareVP(va, vb); - if (result) - { - break; - } - - } while (a || b); - - free(A2); - free(B2); - - return result; -} -#endif - -int32_t CompareVersions(const char* aStrA, const char* aStrB) -{ - char* A2 = strdup(aStrA); - if (!A2) - { - return 1; - } - - char* B2 = strdup(aStrB); - if (!B2) - { - free(A2); - return 1; - } - - int32_t result; - char* a = A2; - char* b = B2; - - do - { - VersionPart va, vb; - - a = ParseVP(a, va); - b = ParseVP(b, vb); - - result = CompareVP(va, vb); - if (result) - { - break; - } - - } while (a || b); - - free(A2); - free(B2); - - return result; -} - -} // namespace mozilla diff --git a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h b/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h deleted file mode 100644 index d793e345eb86..000000000000 --- a/onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsVersionComparator_h__ -#define nsVersionComparator_h__ - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#if defined(_WIN32) && !defined(UPDATER_NO_STRING_GLUE_STL) -#include <wchar.h> -#include <stdint.h> - -#endif - -/** - * In order to compare version numbers in Mozilla, you need to use the - * mozilla::Version class. You can construct an object of this type by passing - * in a string version number to the constructor. Objects of this type can be - * compared using the standard comparison operators. - * - * For example, let's say that you want to make sure that a given version - * number is not older than 15.a2. Here's how you would write a function to - * do that. - * - * bool IsVersionValid(const char* version) { - * return mozilla::Version("15.a2") <= mozilla::Version(version); - * } - * - * Or, since Version's constructor is implicit, you can simplify this code: - * - * bool IsVersionValid(const char* version) { - * return mozilla::Version("15.a2") <= version; - * } - * - * On Windows, if your version strings are wide characters, you should use the - * mozilla::VersionW variant instead. The semantics of that class is the same - * as Version. - */ - -namespace mozilla { - -int32_t CompareVersions(const char* aStrA, const char* aStrB); - -#ifdef _WIN32 -int32_t CompareVersions(const wchar_t* aStrA, const wchar_t* aStrB); -#endif - -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; - } - -private: - 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; - } - -private: - wchar_t* versionContentW; -}; -#endif - -} // namespace mozilla - -#endif // nsVersionComparator_h__ - diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 7b189e4af414..981877ea114d 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -5302,16 +5302,6 @@ include/span include/o3tl/strong_int.hxx include/o3tl/typed_flags_set.hxx include/o3tl/vector_pool.hxx -include/onlineupdate/mar.h -include/onlineupdate/mar_cmdline.h -include/onlineupdate/mar_private.h -include/onlineupdate/mozilla/Assertions.h -include/onlineupdate/mozilla/Attributes.h -include/onlineupdate/mozilla/Compiler.h -include/onlineupdate/mozilla/MacroArgs.h -include/onlineupdate/mozilla/TypeTraits.h -include/onlineupdate/mozilla/Types.h -include/onlineupdate/mozilla/nsTraceRefcnt.h include/oox/core/binarycodec.hxx include/oox/core/contexthandler.hxx include/oox/core/contexthandler2.hxx @@ -6892,55 +6882,6 @@ odk/examples/cpp/remoteclient/remoteclient.cxx odk/source/unoapploader/unx/unoapploader.c odk/source/unoapploader/win/unoapploader.c officecfg/qa/cppheader.cxx -onlineupdate/inc/Char16.h -onlineupdate/source/libmar/sign/mar_sign.c -onlineupdate/source/libmar/sign/nss_secutil.c -onlineupdate/source/libmar/sign/nss_secutil.h -onlineupdate/source/libmar/src/mar_create.c -onlineupdate/source/libmar/src/mar_extract.c -onlineupdate/source/libmar/src/mar_read.c -onlineupdate/source/libmar/tool/mar.c -onlineupdate/source/libmar/verify/MacVerifyCrypto.cpp -onlineupdate/source/libmar/verify/cryptox.c -onlineupdate/source/libmar/verify/cryptox.h -onlineupdate/source/libmar/verify/mar_verify.c -onlineupdate/source/mbsdiff/bsdiff.cxx -onlineupdate/source/service/certificatecheck.cxx -onlineupdate/source/service/certificatecheck.hxx -onlineupdate/source/service/maintenanceservice.cxx -onlineupdate/source/service/maintenanceservice.hxx -onlineupdate/source/service/registrycertificates.cxx -onlineupdate/source/service/registrycertificates.hxx -onlineupdate/source/service/resource.hxx -onlineupdate/source/service/servicebase.cxx -onlineupdate/source/service/serviceinstall.cxx -onlineupdate/source/service/serviceinstall.hxx -onlineupdate/source/service/windowsHelper.hxx -onlineupdate/source/service/workmonitor.cxx -onlineupdate/source/update/common/pathhash.cxx -onlineupdate/source/update/common/pathhash.h -onlineupdate/source/update/common/readstrings.cxx -onlineupdate/source/update/common/readstrings.h -onlineupdate/source/update/common/uachelper.cxx -onlineupdate/source/update/common/uachelper.h -onlineupdate/source/update/common/updatedefines.h -onlineupdate/source/update/common/updatehelper.cxx -onlineupdate/source/update/common/updatehelper.h -onlineupdate/source/update/common/updatelogging.cxx -onlineupdate/source/update/common/updatelogging.h -onlineupdate/source/update/updater/archivereader.cxx -onlineupdate/source/update/updater/archivereader.h -onlineupdate/source/update/updater/bspatch.cxx -onlineupdate/source/update/updater/loaddlls.cxx -onlineupdate/source/update/updater/progressui-unused/progressui_gonk.cxx -onlineupdate/source/update/updater/progressui_gtk.cxx -onlineupdate/source/update/updater/progressui_gtk_icon.h -onlineupdate/source/update/updater/progressui_null.cxx -onlineupdate/source/update/updater/progressui_win.cxx -onlineupdate/source/update/updater/resource.h -onlineupdate/source/update/updater/updater.cxx -onlineupdate/source/update/updater/win_dirent.cxx -onlineupdate/source/update/updater/xpcom/glue/nsVersionComparator.h oox/inc/drawingml/ThemeOverrideFragmentHandler.hxx oox/inc/drawingml/chart/axiscontext.hxx oox/inc/drawingml/chart/axisconverter.hxx diff --git a/solenv/qa/python/gbuildtojson.py b/solenv/qa/python/gbuildtojson.py index e693f75f5947..a6ba733d06b6 100644 --- a/solenv/qa/python/gbuildtojson.py +++ b/solenv/qa/python/gbuildtojson.py @@ -124,7 +124,7 @@ class CheckGbuildToJsonModules(unittest.TestCase): shutil.rmtree(self.tempwork) def test_gbuildtojson(self): - modules = ['accessibility', 'android', 'animations', 'apple_remote', 'avmedia', 'basctl', 'basegfx', 'basic', 'bean', 'canvas', 'chart2', 'codemaker', 'comphelper', 'cppcanvas', 'cui', 'dbaccess', 'desktop', 'docmodel', 'drawinglayer', 'editeng', 'embeddedobj', 'embedserv', 'eventattacher', 'extras', 'filter', 'forms', 'formula', 'fpicker', 'framework', 'hwpfilter', 'i18nlangtag', 'i18nutil', 'idl', 'instsetoo_native', 'io', 'ios', 'jvmaccess', 'jvmfwk', 'l10ntools', 'librelogo', 'libreofficekit', 'linguistic', 'lotuswordpro', 'nlpsolver', 'o3tl', 'offapi', 'officecfg', 'onlineupdate', 'oovbaapi', 'oox', 'opencl', 'package', 'postprocess', 'pyuno', 'registry', 'remotebridges', 'reportbuilder', 'reportdesign', 'ridljar', 'salhelper', 'sax', 'sc', 'sccomp', 'scp2', 'scripting', 'sd', 'sdext', 'setup_native', 'sfx2', 'slideshow', 'smoketest', 'soltools', 'sot', 'starmath', 'store', 'svgio', 'emfio', 'svl', 'svtools', 'svx', 'sw', 'swext', 'sysui', 'test', 'testtools', 'toolkit', 'ucb', 'ucbhelper', 'udkapi', 'uitest', 'UnoControls', 'unodevtools', 'unoidl', 'unoil', 'unotest', 'unotools', 'unoxml', 'ure', 'uui', 'vbahelper', 'vcl', 'winaccessibility', 'wizards', 'writerperfect', 'xmerge', 'xmlhelp', 'xmloff', 'xmlreader', 'xmlscript', 'xmlsecurity'] + modules = ['accessibility', 'android', 'animations', 'apple_remote', 'avmedia', 'basctl', 'basegfx', 'basic', 'bean', 'canvas', 'chart2', 'codemaker', 'comphelper', 'cppcanvas', 'cui', 'dbaccess', 'desktop', 'docmodel', 'drawinglayer', 'editeng', 'embeddedobj', 'embedserv', 'eventattacher', 'extras', 'filter', 'forms', 'formula', 'fpicker', 'framework', 'hwpfilter', 'i18nlangtag', 'i18nutil', 'idl', 'instsetoo_native', 'io', 'ios', 'jvmaccess', 'jvmfwk', 'l10ntools', 'librelogo', 'libreofficekit', 'linguistic', 'lotuswordpro', 'nlpsolver', 'o3tl', 'offapi', 'officecfg', 'oovbaapi', 'oox', 'opencl', 'package', 'postprocess', 'pyuno', 'registry', 'remotebridges', 'reportbuilder', 'reportdesign', 'ridljar', 'salhelper', 'sax', 'sc', 'sccomp', 'scp2', 'scripting', 'sd', 'sdext', 'setup_native', 'sfx2', 'slideshow', 'smoketest', 'soltools', 'sot', 'starmath', 'store', 'svgio', 'emfio', 'svl', 'svtools', 'svx', 'sw', 'swext', 'sysui', 'test', 'testtools', 'toolkit', 'ucb', 'ucbhelper', 'udkapi', 'uitest', 'UnoControls', 'unodevtools', 'unoidl', 'unoil', 'unotest', 'unotools', 'unoxml', 'ure', 'uui', 'vbahelper', 'vcl', 'winaccessibility', 'wizards', 'writerperfect', 'xmerge', 'xmlhelp', 'xmloff', 'xmlreader', 'xmlscript', 'xmlsecurity'] if os.environ['OS'] == 'WNT': # for now, use a limited subset for testing on windows as it is so annoyingly slow on this modules = ['chart2', 'cui', 'dbaccess', 'framework', 'oox', 'sfx2', 'svl', 'svtools', 'svx', 'toolkit', 'vcl', 'xmloff'] |