From a5e825cc69f9c29d450607d9033682ec3a68b57e Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Thu, 7 Dec 2023 02:18:49 +0000 Subject: More fixup Windows buiuld Change-Id: Ic5ffedbf57fa0f686b9ede193f61e47e7efe90ac --- onlineupdate/StaticLibrary_updatehelper.mk | 8 + onlineupdate/inc/nsAutoRef.h | 489 +++++++++++++++++++++++++ onlineupdate/inc/nsCharTraits.h | 486 ++++++++++++++++++++++++ onlineupdate/inc/nsUTF8Utils.h | 247 +++++++++++++ onlineupdate/inc/nsWindowsHelpers.h | 339 +++++++++++++++++ onlineupdate/source/service/nsAutoRef.h | 489 ------------------------- onlineupdate/source/service/nsCharTraits.h | 486 ------------------------ onlineupdate/source/service/nsUTF8Utils.h | 247 ------------- onlineupdate/source/service/nsWindowsHelpers.h | 339 ----------------- 9 files changed, 1569 insertions(+), 1561 deletions(-) create mode 100644 onlineupdate/inc/nsAutoRef.h create mode 100644 onlineupdate/inc/nsCharTraits.h create mode 100644 onlineupdate/inc/nsUTF8Utils.h create mode 100644 onlineupdate/inc/nsWindowsHelpers.h delete mode 100644 onlineupdate/source/service/nsAutoRef.h delete mode 100644 onlineupdate/source/service/nsCharTraits.h delete mode 100644 onlineupdate/source/service/nsUTF8Utils.h delete mode 100644 onlineupdate/source/service/nsWindowsHelpers.h diff --git a/onlineupdate/StaticLibrary_updatehelper.mk b/onlineupdate/StaticLibrary_updatehelper.mk index cbb0130759e9..cce26a8dcbac 100644 --- a/onlineupdate/StaticLibrary_updatehelper.mk +++ b/onlineupdate/StaticLibrary_updatehelper.mk @@ -19,8 +19,11 @@ $(eval $(call gb_StaticLibrary_set_include,updatehelper,\ $(eval $(call gb_StaticLibrary_add_defs,updatehelper,\ -DNSS3 \ + -DUNICODE \ -DVERIFY_MAR_SIGNATURE \ -DXP_WIN=1 \ + -DNTDDI_VERSION=NTDDI_WIN8 \ + -DMOZ_MAINTENANCE_SERVICE \ )) $(eval $(call gb_StaticLibrary_add_exception_objects,updatehelper,\ @@ -28,6 +31,11 @@ $(eval $(call gb_StaticLibrary_add_exception_objects,updatehelper,\ onlineupdate/source/update/common/readstrings \ onlineupdate/source/update/common/uachelper \ onlineupdate/source/update/common/updatehelper \ + onlineupdate/source/update/common/updatecommon \ +)) + +$(eval $(call gb_StaticLibrary_add_exception_objects,updatehelper,\ + onlineupdate/source/update/common/updateutils_win \ )) # vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/onlineupdate/inc/nsAutoRef.h b/onlineupdate/inc/nsAutoRef.h new file mode 100644 index 000000000000..9a1f3ddd93e9 --- /dev/null +++ b/onlineupdate/inc/nsAutoRef.h @@ -0,0 +1,489 @@ +/* -*- 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/. */ + +// NB: This code may be used from non-XPCOM code, in particular, the +// Windows Default Browser Agent. + +#ifndef nsAutoRef_h_ +#define nsAutoRef_h_ + +#include "mozilla/Attributes.h" + +template +class nsSimpleRef; +template +class nsAutoRefBase; +template +class nsReturnRef; +template +class nsReturningRef; + +/** + * template class nsAutoRef + * + * A class that holds a handle to a resource that must be released. + * No reference is added on construction. + * + * No copy constructor nor copy assignment operators are available, so the + * resource will be held until released on destruction or explicitly + * |reset()| or transferred through provided methods. + * + * The publicly available methods are the public methods on this class and its + * public base classes |nsAutoRefBase| and |nsSimpleRef|. + * + * For function return values see |nsReturnRef|. + * + * For each class |T|, |nsAutoRefTraits| or |nsSimpleRef| must be + * specialized to use |nsAutoRef|. + * + * @param T A class identifying the type of reference held by the + * |nsAutoRef| and the unique set methods for managing references + * to the resource (defined by |nsAutoRefTraits| or + * |nsSimpleRef|). + * + * Often this is the class representing the resource. Sometimes a + * new possibly-incomplete class may need to be declared. + * + * + * Example: An Automatically closing file descriptor + * + * // References that are simple integral types (as file-descriptors are) + * // usually need a new class to represent the resource and how to handle its + * // references. + * class nsRawFD; + * + * // Specializing nsAutoRefTraits describes how to manage file + * // descriptors, so that nsAutoRef provides automatic closing of + * // its file descriptor on destruction. + * template <> + * class nsAutoRefTraits { + * public: + * // The file descriptor is held in an int. + * typedef int RawRef; + * // -1 means that there is no file associated with the handle. + * static int Void() { return -1; } + * // The file associated with a file descriptor is released with close(). + * static void Release(RawRef aFD) { close(aFD); } + * }; + * + * // A function returning a file descriptor that must be closed. + * nsReturnRef get_file(const char *filename) { + * // Constructing from a raw file descriptor assumes ownership. + * nsAutoRef fd(open(filename, O_RDONLY)); + * fcntl(fd, F_SETFD, FD_CLOEXEC); + * return fd.out(); + * } + * + * void f() { + * unsigned char buf[1024]; + * + * // Hold a file descriptor for /etc/hosts in fd1. + * nsAutoRef fd1(get_file("/etc/hosts")); + * + * nsAutoRef fd2; + * fd2.steal(fd1); // fd2 takes the file descriptor from fd1 + * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file + * count = read(fd2, buf, 1024); // reads from /etc/hosts + * + * // If the file descriptor is not stored then it is closed. + * get_file("/etc/login.defs"); // login.defs is closed + * + * // Now use fd1 to hold a file descriptor for /etc/passwd. + * fd1 = get_file("/etc/passwd"); + * + * // The nsAutoRef can give up the file descriptor if explicitly + * // instructed, but the caller must then ensure that the file is closed. + * int rawfd = fd1.disown(); + * + * // Assume ownership of another file descriptor. + * fd1.own(open("/proc/1/maps"); + * + * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts, + * // but /etc/passwd is not closed. + * } + * + */ + +template +class nsAutoRef : public nsAutoRefBase { + protected: + typedef nsAutoRef ThisClass; + typedef nsAutoRefBase BaseClass; + typedef nsSimpleRef SimpleRef; + typedef typename BaseClass::RawRefOnly RawRefOnly; + typedef typename BaseClass::LocalSimpleRef LocalSimpleRef; + + public: + nsAutoRef() = default; + + // Explicit construction is required so as not to risk unintentionally + // releasing the resource associated with a raw ref. + explicit nsAutoRef(RawRefOnly aRefToRelease) : BaseClass(aRefToRelease) {} + + // Construction from a nsReturnRef function return value, which expects + // to give up ownership, transfers ownership. + // (nsReturnRef is converted to const nsReturningRef.) + explicit nsAutoRef(const nsReturningRef& aReturning) + : BaseClass(aReturning) {} + + // The only assignment operator provided is for transferring from an + // nsReturnRef smart reference, which expects to pass its ownership to + // another object. + // + // With raw references and other smart references, the type of the lhs and + // its taking and releasing nature is often not obvious from an assignment + // statement. Assignment from a raw ptr especially is not normally + // expected to release the reference. + // + // Use |steal| for taking ownership from other smart refs. + // + // For raw references, use |own| to indicate intention to have the + // resource released. + + ThisClass& operator=(const nsReturningRef& aReturning) { + BaseClass::steal(aReturning.mReturnRef); + return *this; + } + + // Conversion to a raw reference allow the nsAutoRef to often be used + // like a raw reference. + operator typename SimpleRef::RawRef() const { return this->get(); } + + explicit operator bool() const { return this->HaveResource(); } + + // Transfer ownership from another smart reference. + void steal(ThisClass& aOtherRef) { BaseClass::steal(aOtherRef); } + + // Assume ownership of a raw ref. + // + // |own| has similar function to |steal|, and is useful for receiving + // ownership from a return value of a function. It is named differently + // because |own| requires more care to ensure that the function intends to + // give away ownership, and so that |steal| can be safely used, knowing + // that it won't steal ownership from any methods returning raw ptrs to + // data owned by a foreign object. + void own(RawRefOnly aRefToRelease) { BaseClass::own(aRefToRelease); } + + // Exchange ownership with |aOther| + void swap(ThisClass& aOther) { + LocalSimpleRef temp; + temp.SimpleRef::operator=(*this); + SimpleRef::operator=(aOther); + aOther.SimpleRef::operator=(temp); + } + + // Release the reference now. + void reset() { + this->SafeRelease(); + LocalSimpleRef empty; + SimpleRef::operator=(empty); + } + + // Pass out the reference for a function return values. + nsReturnRef out() { return nsReturnRef(this->disown()); } + + // operator->() and disown() are provided by nsAutoRefBase. + // The default nsSimpleRef provides get(). + + // No copy constructor + explicit nsAutoRef(const ThisClass& aRefToSteal) = delete; +}; + +/** + * template class nsReturnRef + * + * A type for function return values that hold a reference to a resource that + * must be released. See also |nsAutoRef::out()|. + */ + +template +class nsReturnRef : public nsAutoRefBase { + protected: + typedef nsAutoRefBase BaseClass; + typedef typename BaseClass::RawRefOnly RawRefOnly; + + public: + // For constructing a return value with no resource + nsReturnRef() = default; + + // For returning a smart reference from a raw reference that must be + // released. Explicit construction is required so as not to risk + // unintentionally releasing the resource associated with a raw ref. + MOZ_IMPLICIT nsReturnRef(RawRefOnly aRefToRelease) + : BaseClass(aRefToRelease) {} + + // Move construction transfers ownership + nsReturnRef(nsReturnRef&& aRefToSteal) = default; + + MOZ_IMPLICIT nsReturnRef(const nsReturningRef& aReturning) + : BaseClass(aReturning) {} + + // Conversion to a temporary (const) object referring to this object so + // that the reference may be passed from a function return value + // (temporary) to another smart reference. There is no need to use this + // explicitly. Simply assign a nsReturnRef function return value to a + // smart reference. + operator nsReturningRef() { return nsReturningRef(*this); } + + // No conversion to RawRef operator is provided on nsReturnRef, to ensure + // that the return value is not carelessly assigned to a raw ptr (and the + // resource then released). If passing to a function that takes a raw + // ptr, use get or disown as appropriate. +}; + +/** + * template class nsReturningRef + * + * A class to allow ownership to be transferred from nsReturnRef function + * return values. + * + * It should not be necessary for clients to reference this + * class directly. Simply pass an nsReturnRef to a parameter taking an + * |nsReturningRef|. + * + * The conversion operator on nsReturnRef constructs a temporary wrapper of + * class nsReturningRef around a non-const reference to the nsReturnRef. + * The wrapper can then be passed as an rvalue parameter. + */ + +template +class nsReturningRef { + private: + friend class nsReturnRef; + + explicit nsReturningRef(nsReturnRef& aReturnRef) + : mReturnRef(aReturnRef) {} + + public: + nsReturnRef& mReturnRef; +}; + +/** + * template class nsAutoRefTraits + * + * A class describing traits of references managed by the default + * |nsSimpleRef| implementation and thus |nsAutoRef|. + * The default |nsSimpleRef is suitable for resources with handles that + * have a void value. (If there is no such void value for a handle, + * specialize |nsSimpleRef|.) + * + * Specializations must be provided for each class |T| according to the + * following pattern: + * + * // The template parameter |T| should be a class such that the set of fields + * // in class nsAutoRefTraits is unique for class |T|. Usually the + * // resource object class is sufficient. For handles that are simple + * // integral typedefs, a new unique possibly-incomplete class may need to be + * // declared. + * + * template <> + * class nsAutoRefTraits + * { + * // Specializations must provide a typedef for RawRef, describing the + * // type of the handle to the resource. + * typedef RawRef; + * + * // Specializations should define Void(), a function returning a value + * // suitable for a handle that does not have an associated resource. + * // + * // The return type must be a suitable as the parameter to a RawRef + * // constructor and operator==. + * // + * // If this method is not accessible then some limited nsAutoRef + * // functionality will still be available, but the default constructor, + * // |reset|, and most transfer of ownership methods will not be available. + * static Void(); + * + * // Specializations must define Release() to properly finalize the + * // handle to a non-void custom-deleted or reference-counted resource. + * static void Release(RawRef aRawRef); + * }; + * + * See nsPointerRefTraits for example specializations for simple pointer + * references. See nsAutoRef for an example specialization for a non-pointer + * reference. + */ + +template +class nsAutoRefTraits; + +/** + * template class nsPointerRefTraits + * + * A convenience class useful as a base class for specializations of + * |nsAutoRefTraits| where the handle to the resource is a pointer to |T|. + * By inheriting from this class, definitions of only Release(RawRef) and + * possibly AddRef(RawRef) need to be added. + * + * Examples of use: + * + * template <> + * class nsAutoRefTraits : public nsPointerRefTraits + * { + * public: + * static void Release(PRFileDesc *ptr) { PR_Close(ptr); } + * }; + * + * template <> + * class nsAutoRefTraits : public nsPointerRefTraits + * { + * public: + * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } + * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } + * }; + */ + +template +class nsPointerRefTraits { + public: + // The handle is a pointer to T. + typedef T* RawRef; + // A nullptr does not have a resource. + static RawRef Void() { return nullptr; } +}; + +/** + * template class nsSimpleRef + * + * Constructs a non-smart reference, and provides methods to test whether + * there is an associated resource and (if so) get its raw handle. + * + * A default implementation is suitable for resources with handles that have a + * void value. This is not intended for direct use but used by |nsAutoRef|. + * + * Specialize this class if there is no particular void value for the resource + * handle. A specialized implementation must also provide Release(RawRef), + */ + +template +class nsSimpleRef : protected nsAutoRefTraits { + protected: + // The default implementation uses nsAutoRefTrait. + // Specializations need not define this typedef. + typedef nsAutoRefTraits Traits; + // The type of the handle to the resource. + // A specialization must provide a typedef for RawRef. + typedef typename Traits::RawRef RawRef; + + // Construct with no resource. + // + // If this constructor is not accessible then some limited nsAutoRef + // functionality will still be available, but the default constructor, + // |reset|, and most transfer of ownership methods will not be available. + nsSimpleRef() : mRawRef(Traits::Void()) {} + // Construct with a handle to a resource. + // A specialization must provide this. + explicit nsSimpleRef(RawRef aRawRef) : mRawRef(aRawRef) {} + + // Test whether there is an associated resource. A specialization must + // provide this. The function is permitted to always return true if the + // default constructor is not accessible, or if Release (and AddRef) can + // deal with void handles. + bool HaveResource() const { return mRawRef != Traits::Void(); } + + public: + // A specialization must provide get() or loose some functionality. This + // is inherited by derived classes and the specialization may choose + // whether it is public or protected. + RawRef get() const { return mRawRef; } + + private: + RawRef mRawRef; +}; + +/** + * template class nsAutoRefBase + * + * Internal base class for |nsAutoRef| and |nsReturnRef|. + * Adds release on destruction to a |nsSimpleRef|. + */ + +template +class nsAutoRefBase : public nsSimpleRef { + protected: + typedef nsAutoRefBase ThisClass; + typedef nsSimpleRef SimpleRef; + typedef typename SimpleRef::RawRef RawRef; + + nsAutoRefBase() = default; + + // A type for parameters that should be passed a raw ref but should not + // accept implicit conversions (from another smart ref). (The only + // conversion to this type is from a raw ref so only raw refs will be + // accepted.) + class RawRefOnly { + public: + MOZ_IMPLICIT RawRefOnly(RawRef aRawRef) : mRawRef(aRawRef) {} + operator RawRef() const { return mRawRef; } + + private: + RawRef mRawRef; + }; + + // Construction from a raw ref assumes ownership + explicit nsAutoRefBase(RawRefOnly aRefToRelease) : SimpleRef(aRefToRelease) {} + + // Constructors that steal ownership + nsAutoRefBase(ThisClass&& aRefToSteal) : SimpleRef(aRefToSteal.disown()) {} + explicit nsAutoRefBase(const nsReturningRef& aReturning) + : SimpleRef(aReturning.mReturnRef.disown()) {} + + ~nsAutoRefBase() { SafeRelease(); } + + // An internal class providing access to protected nsSimpleRef + // constructors for construction of temporary simple references (that are + // not ThisClass). + class LocalSimpleRef : public SimpleRef { + public: + LocalSimpleRef() = default; + explicit LocalSimpleRef(RawRef aRawRef) : SimpleRef(aRawRef) {} + }; + + public: + ThisClass& operator=(const ThisClass& aSmartRef) = delete; + + RawRef operator->() const { return this->get(); } + + // Transfer ownership to a raw reference. + // + // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED. + // + // Is this really what you want to use? Using this removes any guarantee + // of release. Use nsAutoRef::out() for return values, or an + // nsAutoRef modifiable lvalue for an out parameter. Use disown() when + // the reference must be stored in a POD type object, such as may be + // preferred for a namespace-scope object with static storage duration, + // for example. + RawRef disown() { + RawRef temp = this->get(); + LocalSimpleRef empty; + SimpleRef::operator=(empty); + return temp; + } + + protected: + // steal and own are protected because they make no sense on nsReturnRef, + // but steal is implemented on this class for access to aOtherRef.disown() + // when aOtherRef is an nsReturnRef; + + // Transfer ownership from another smart reference. + void steal(ThisClass& aOtherRef) { own(aOtherRef.disown()); } + // Assume ownership of a raw ref. + void own(RawRefOnly aRefToRelease) { + SafeRelease(); + LocalSimpleRef ref(aRefToRelease); + SimpleRef::operator=(ref); + } + + // Release a resource if there is one. + void SafeRelease() { + if (this->HaveResource()) { + this->Release(this->get()); + } + } +}; + +#endif // !defined(nsAutoRef_h_) diff --git a/onlineupdate/inc/nsCharTraits.h b/onlineupdate/inc/nsCharTraits.h new file mode 100644 index 000000000000..c81c2f5b2d3b --- /dev/null +++ b/onlineupdate/inc/nsCharTraits.h @@ -0,0 +1,486 @@ +/* -*- 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 nsCharTraits_h___ +#define nsCharTraits_h___ + +#include // for |EOF|, |WEOF| +#include // for |uint32_t| +#include // for |memcpy|, et al +#include "mozilla/MemoryChecking.h" + +// This file may be used (through nsUTF8Utils.h) from non-XPCOM code, in +// particular the standalone software updater. In that case stub out +// the macros provided by nsDebug.h which are only usable when linking XPCOM + +#ifdef NS_NO_XPCOM +# define NS_WARNING(msg) +# define NS_ASSERTION(cond, msg) +# define NS_ERROR(msg) +#else +# include "nsDebug.h" // for NS_ASSERTION +#endif + +/* + * Some macros for converting char16_t (UTF-16) to and from Unicode scalar + * values. + * + * Note that UTF-16 represents all Unicode scalar values up to U+10FFFF by + * using "surrogate pairs". These consist of a high surrogate, i.e. a code + * point in the range U+D800 - U+DBFF, and a low surrogate, i.e. a code point + * in the range U+DC00 - U+DFFF, like this: + * + * U+D800 U+DC00 = U+10000 + * U+D800 U+DC01 = U+10001 + * ... + * U+DBFF U+DFFE = U+10FFFE + * U+DBFF U+DFFF = U+10FFFF + * + * These surrogate code points U+D800 - U+DFFF are not themselves valid Unicode + * scalar values and are not well-formed UTF-16 except as high-surrogate / + * low-surrogate pairs. + */ + +#define PLANE1_BASE uint32_t(0x00010000) +// High surrogates are in the range 0xD800 -- OxDBFF +#define NS_IS_HIGH_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xD800) +// Low surrogates are in the range 0xDC00 -- 0xDFFF +#define NS_IS_LOW_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xDC00) +// Easier to type than NS_IS_HIGH_SURROGATE && NS_IS_LOW_SURROGATE +#define NS_IS_SURROGATE_PAIR(h, l) \ + (NS_IS_HIGH_SURROGATE(h) && NS_IS_LOW_SURROGATE(l)) +// Faster than testing NS_IS_HIGH_SURROGATE || NS_IS_LOW_SURROGATE +#define IS_SURROGATE(u) ((uint32_t(u) & 0xFFFFF800) == 0xD800) + +// Everything else is not a surrogate: 0x000 -- 0xD7FF, 0xE000 -- 0xFFFF + +// N = (H - 0xD800) * 0x400 + 0x10000 + (L - 0xDC00) +// I wonder whether we could somehow assert that H is a high surrogate +// and L is a low surrogate +#define SURROGATE_TO_UCS4(h, l) \ + (((uint32_t(h) & 0x03FF) << 10) + (uint32_t(l) & 0x03FF) + PLANE1_BASE) + +// Extract surrogates from a UCS4 char +// Reference: the Unicode standard 4.0, section 3.9 +// Since (c - 0x10000) >> 10 == (c >> 10) - 0x0080 and +// 0xD7C0 == 0xD800 - 0x0080, +// ((c - 0x10000) >> 10) + 0xD800 can be simplified to +#define H_SURROGATE(c) char16_t(char16_t(uint32_t(c) >> 10) + char16_t(0xD7C0)) +// where it's to be noted that 0xD7C0 is not bitwise-OR'd +// but added. + +// Since 0x10000 & 0x03FF == 0, +// (c - 0x10000) & 0x03FF == c & 0x03FF so that +// ((c - 0x10000) & 0x03FF) | 0xDC00 is equivalent to +#define L_SURROGATE(c) \ + char16_t(char16_t(uint32_t(c) & uint32_t(0x03FF)) | char16_t(0xDC00)) + +#define IS_IN_BMP(ucs) (uint32_t(ucs) < PLANE1_BASE) +#define UCS2_REPLACEMENT_CHAR char16_t(0xFFFD) + +#define UCS_END uint32_t(0x00110000) +#define IS_VALID_CHAR(c) ((uint32_t(c) < UCS_END) && !IS_SURROGATE(c)) +#define ENSURE_VALID_CHAR(c) (IS_VALID_CHAR(c) ? (c) : UCS2_REPLACEMENT_CHAR) + +template +struct nsCharTraits {}; + +template <> +struct nsCharTraits { + typedef char16_t char_type; + typedef uint16_t unsigned_char_type; + typedef char incompatible_char_type; + + static char_type* const sEmptyBuffer; + + // integer representation of characters: + typedef int int_type; + + static char_type to_char_type(int_type aChar) { return char_type(aChar); } + + static int_type to_int_type(char_type aChar) { + return int_type(static_cast(aChar)); + } + + static bool eq_int_type(int_type aLhs, int_type aRhs) { return aLhs == aRhs; } + + // |char_type| comparisons: + + static bool eq(char_type aLhs, char_type aRhs) { return aLhs == aRhs; } + + static bool lt(char_type aLhs, char_type aRhs) { return aLhs < aRhs; } + + // operations on s[n] arrays: + + static char_type* move(char_type* aStr1, const char_type* aStr2, size_t aN) { + return static_cast( + memmove(aStr1, aStr2, aN * sizeof(char_type))); + } + + static char_type* copy(char_type* aStr1, const char_type* aStr2, size_t aN) { + return static_cast( + memcpy(aStr1, aStr2, aN * sizeof(char_type))); + } + + static void uninitialize(char_type* aStr, size_t aN) { +#ifdef DEBUG + memset(aStr, 0xE4, aN * sizeof(char_type)); +#endif + MOZ_MAKE_MEM_UNDEFINED(aStr, aN * sizeof(char_type)); + } + + static char_type* copyASCII(char_type* aStr1, const char* aStr2, size_t aN) { + for (char_type* s = aStr1; aN--; ++s, ++aStr2) { + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + *s = static_cast(*aStr2); + } + return aStr1; + } + + static int compare(const char_type* aStr1, const char_type* aStr2, + size_t aN) { + for (; aN--; ++aStr1, ++aStr2) { + if (!eq(*aStr1, *aStr2)) { + return to_int_type(*aStr1) - to_int_type(*aStr2); + } + } + + return 0; + } + + static int compareASCII(const char_type* aStr1, const char* aStr2, + size_t aN) { + for (; aN--; ++aStr1, ++aStr2) { + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + if (!eq_int_type(to_int_type(*aStr1), + to_int_type(static_cast(*aStr2)))) { + return to_int_type(*aStr1) - + to_int_type(static_cast(*aStr2)); + } + } + + return 0; + } + + static bool equalsLatin1(const char_type* aStr1, const char* aStr2, + const size_t aN) { + for (size_t i = aN; i > 0; --i, ++aStr1, ++aStr2) { + if (*aStr1 != static_cast(*aStr2)) { + return false; + } + } + + return true; + } + + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static int compareASCIINullTerminated(const char_type* aStr1, size_t aN, + const char* aStr2) { + for (; aN--; ++aStr1, ++aStr2) { + if (!*aStr2) { + return 1; + } + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + if (!eq_int_type(to_int_type(*aStr1), + to_int_type(static_cast(*aStr2)))) { + return to_int_type(*aStr1) - + to_int_type(static_cast(*aStr2)); + } + } + + if (*aStr2) { + return -1; + } + + return 0; + } + + /** + * Convert c to its lower-case form, but only if c is in the ASCII + * range. Otherwise leave it alone. + */ + static char_type ASCIIToLower(char_type aChar) { + if (aChar >= 'A' && aChar <= 'Z') { + return char_type(aChar + ('a' - 'A')); + } + + return aChar; + } + + static int compareLowerCaseToASCII(const char_type* aStr1, const char* aStr2, + size_t aN) { + for (; aN--; ++aStr1, ++aStr2) { + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), + "Unexpected uppercase character"); + char_type lower_s1 = ASCIIToLower(*aStr1); + if (lower_s1 != static_cast(*aStr2)) { + return to_int_type(lower_s1) - + to_int_type(static_cast(*aStr2)); + } + } + + return 0; + } + + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static int compareLowerCaseToASCIINullTerminated(const char_type* aStr1, + size_t aN, + const char* aStr2) { + for (; aN--; ++aStr1, ++aStr2) { + if (!*aStr2) { + return 1; + } + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), + "Unexpected uppercase character"); + char_type lower_s1 = ASCIIToLower(*aStr1); + if (lower_s1 != static_cast(*aStr2)) { + return to_int_type(lower_s1) - + to_int_type(static_cast(*aStr2)); + } + } + + if (*aStr2) { + return -1; + } + + return 0; + } + + static size_t length(const char_type* aStr) { + size_t result = 0; + while (!eq(*aStr++, char_type(0))) { + ++result; + } + return result; + } + + static const char_type* find(const char_type* aStr, size_t aN, + char_type aChar) { + while (aN--) { + if (eq(*aStr, aChar)) { + return aStr; + } + ++aStr; + } + + return 0; + } +}; + +template <> +struct nsCharTraits { + typedef char char_type; + typedef unsigned char unsigned_char_type; + typedef char16_t incompatible_char_type; + + static char_type* const sEmptyBuffer; + + // integer representation of characters: + + typedef int int_type; + + static char_type to_char_type(int_type aChar) { return char_type(aChar); } + + static int_type to_int_type(char_type aChar) { + return int_type(static_cast(aChar)); + } + + static bool eq_int_type(int_type aLhs, int_type aRhs) { return aLhs == aRhs; } + + // |char_type| comparisons: + + static bool eq(char_type aLhs, char_type aRhs) { return aLhs == aRhs; } + + static bool lt(char_type aLhs, char_type aRhs) { return aLhs < aRhs; } + + // operations on s[n] arrays: + + static char_type* move(char_type* aStr1, const char_type* aStr2, size_t aN) { + return static_cast( + memmove(aStr1, aStr2, aN * sizeof(char_type))); + } + + static char_type* copy(char_type* aStr1, const char_type* aStr2, size_t aN) { + return static_cast( + memcpy(aStr1, aStr2, aN * sizeof(char_type))); + } + + static void uninitialize(char_type* aStr, size_t aN) { +#ifdef DEBUG + memset(aStr, 0xE4, aN * sizeof(char_type)); +#endif + MOZ_MAKE_MEM_UNDEFINED(aStr, aN * sizeof(char_type)); + } + + static char_type* copyASCII(char_type* aStr1, const char* aStr2, size_t aN) { + return copy(aStr1, aStr2, aN); + } + + static int compare(const char_type* aStr1, const char_type* aStr2, + size_t aN) { + return memcmp(aStr1, aStr2, aN); + } + + static int compareASCII(const char_type* aStr1, const char* aStr2, + size_t aN) { +#ifdef DEBUG + for (size_t i = 0; i < aN; ++i) { + NS_ASSERTION(!(aStr2[i] & ~0x7F), "Unexpected non-ASCII character"); + } +#endif + return compare(aStr1, aStr2, aN); + } + + static bool equalsLatin1(const char_type* aStr1, const char* aStr2, + size_t aN) { + return memcmp(aStr1, aStr2, aN) == 0; + } + + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static int compareASCIINullTerminated(const char_type* aStr1, size_t aN, + const char* aStr2) { + // can't use strcmp here because we don't want to stop when aStr1 + // contains a null + for (; aN--; ++aStr1, ++aStr2) { + if (!*aStr2) { + return 1; + } + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + if (*aStr1 != *aStr2) { + return to_int_type(*aStr1) - to_int_type(*aStr2); + } + } + + if (*aStr2) { + return -1; + } + + return 0; + } + + /** + * Convert c to its lower-case form, but only if c is ASCII. + */ + static char_type ASCIIToLower(char_type aChar) { + if (aChar >= 'A' && aChar <= 'Z') { + return char_type(aChar + ('a' - 'A')); + } + + return aChar; + } + + static int compareLowerCaseToASCII(const char_type* aStr1, const char* aStr2, + size_t aN) { + for (; aN--; ++aStr1, ++aStr2) { + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), + "Unexpected uppercase character"); + char_type lower_s1 = ASCIIToLower(*aStr1); + if (lower_s1 != *aStr2) { + return to_int_type(lower_s1) - to_int_type(*aStr2); + } + } + return 0; + } + + // this version assumes that s2 is null-terminated and s1 has length n. + // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, + // we return 1. + static int compareLowerCaseToASCIINullTerminated(const char_type* aStr1, + size_t aN, + const char* aStr2) { + for (; aN--; ++aStr1, ++aStr2) { + if (!*aStr2) { + return 1; + } + NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); + NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), + "Unexpected uppercase character"); + char_type lower_s1 = ASCIIToLower(*aStr1); + if (lower_s1 != *aStr2) { + return to_int_type(lower_s1) - to_int_type(*aStr2); + } + } + + if (*aStr2) { + return -1; + } + + return 0; + } + + static size_t length(const char_type* aStr) { return strlen(aStr); } + + static const char_type* find(const char_type* aStr, size_t aN, + char_type aChar) { + return reinterpret_cast( + memchr(aStr, to_int_type(aChar), aN)); + } +}; + +template +struct nsCharSourceTraits { + typedef typename InputIterator::difference_type difference_type; + + static difference_type readable_distance(const InputIterator& aFirst, + const InputIterator& aLast) { + // assumes single fragment + return aLast.get() - aFirst.get(); + } + + static const typename InputIterator::value_type* read( + const InputIterator& aIter) { + return aIter.get(); + } + + static void advance(InputIterator& aStr, difference_type aN) { + aStr.advance(aN); + } +}; + +template +struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + + static difference_type readable_distance(CharT* aStr) { + return nsCharTraits::length(aStr); + } + + static difference_type readable_distance(CharT* aFirst, CharT* aLast) { + return aLast - aFirst; + } + + static const CharT* read(CharT* aStr) { return aStr; } + + static void advance(CharT*& aStr, difference_type aN) { aStr += aN; } +}; + +template +struct nsCharSinkTraits { + static void write(OutputIterator& aIter, + const typename OutputIterator::value_type* aStr, + size_t aN) { + aIter.write(aStr, aN); + } +}; + +template +struct nsCharSinkTraits { + static void write(CharT*& aIter, const CharT* aStr, size_t aN) { + nsCharTraits::move(aIter, aStr, aN); + aIter += aN; + } +}; + +#endif // !defined(nsCharTraits_h___) diff --git a/onlineupdate/inc/nsUTF8Utils.h b/onlineupdate/inc/nsUTF8Utils.h new file mode 100644 index 000000000000..0145011ec152 --- /dev/null +++ b/onlineupdate/inc/nsUTF8Utils.h @@ -0,0 +1,247 @@ +/* -*- 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 nsUTF8Utils_h_ +#define nsUTF8Utils_h_ + +// NB: This code may be used from non-XPCOM code, in particular, the +// standalone updater executable. That is, this file may be used in +// two ways: if MOZILLA_INTERNAL_API is defined, this file will +// provide signatures for the Mozilla abstract string types. It will +// use XPCOM assertion/debugging macros, etc. + +#include + +#include "mozilla/Assertions.h" +#include "mozilla/EndianUtils.h" + +#include "nsCharTraits.h" + +#ifdef MOZILLA_INTERNAL_API +# define UTF8UTILS_WARNING(msg) NS_WARNING(msg) +#else +# define UTF8UTILS_WARNING(msg) +#endif + +class UTF8traits { + public: + static bool isASCII(char aChar) { return (aChar & 0x80) == 0x00; } + static bool isInSeq(char aChar) { return (aChar & 0xC0) == 0x80; } + static bool is2byte(char aChar) { return (aChar & 0xE0) == 0xC0; } + static bool is3byte(char aChar) { return (aChar & 0xF0) == 0xE0; } + static bool is4byte(char aChar) { return (aChar & 0xF8) == 0xF0; } + static bool is5byte(char aChar) { return (aChar & 0xFC) == 0xF8; } + static bool is6byte(char aChar) { return (aChar & 0xFE) == 0xFC; } + // return the number of bytes in a sequence beginning with aChar + static int bytes(char aChar) { + if (isASCII(aChar)) { + return 1; + } + if (is2byte(aChar)) { + return 2; + } + if (is3byte(aChar)) { + return 3; + } + if (is4byte(aChar)) { + return 4; + } + MOZ_ASSERT_UNREACHABLE("should not be used for in-sequence characters"); + return 1; + } +}; + +/** + * Extract the next Unicode scalar value from the buffer and return it. The + * pointer passed in is advanced to the start of the next character in the + * buffer. Upon error, the return value is 0xFFFD, *aBuffer is advanced + * over the maximal valid prefix and *aErr is set to true (if aErr is not + * null). + * + * Note: This method never sets *aErr to false to allow error accumulation + * across multiple calls. + * + * Precondition: *aBuffer < aEnd + */ +class UTF8CharEnumerator { + public: + static inline char32_t NextChar(const char** aBuffer, const char* aEnd, + bool* aErr = nullptr) { + MOZ_ASSERT(aBuffer, "null buffer pointer pointer"); + MOZ_ASSERT(aEnd, "null end pointer"); + + const unsigned char* p = reinterpret_cast(*aBuffer); + const unsigned char* end = reinterpret_cast(aEnd); + + MOZ_ASSERT(p, "null buffer"); + MOZ_ASSERT(p < end, "Bogus range"); + + unsigned char first = *p; + ++p; + + if (MOZ_LIKELY(first < 0x80U)) { + *aBuffer = reinterpret_cast(p); + return first; + } + + // Unsigned underflow is defined behavior + if (MOZ_UNLIKELY((p == end) || ((first - 0xC2U) >= (0xF5U - 0xC2U)))) { + *aBuffer = reinterpret_cast(p); + if (aErr) { + *aErr = true; + } + return 0xFFFDU; + } + + unsigned char second = *p; + + if (first < 0xE0U) { + // Two-byte + if (MOZ_LIKELY((second & 0xC0U) == 0x80U)) { + ++p; + *aBuffer = reinterpret_cast(p); + return ((uint32_t(first) & 0x1FU) << 6) | (uint32_t(second) & 0x3FU); + } + *aBuffer = reinterpret_cast(p); + if (aErr) { + *aErr = true; + } + return 0xFFFDU; + } + + if (MOZ_LIKELY(first < 0xF0U)) { + // Three-byte + unsigned char lower = 0x80U; + unsigned char upper = 0xBFU; + if (first == 0xE0U) { + lower = 0xA0U; + } else if (first == 0xEDU) { + upper = 0x9FU; + } + if (MOZ_LIKELY(second >= lower && second <= upper)) { + ++p; + if (MOZ_LIKELY(p != end)) { + unsigned char third = *p; + if (MOZ_LIKELY((third & 0xC0U) == 0x80U)) { + ++p; + *aBuffer = reinterpret_cast(p); + return ((uint32_t(first) & 0xFU) << 12) | + ((uint32_t(second) & 0x3FU) << 6) | + (uint32_t(third) & 0x3FU); + } + } + } + *aBuffer = reinterpret_cast(p); + if (aErr) { + *aErr = true; + } + return 0xFFFDU; + } + + // Four-byte + unsigned char lower = 0x80U; + unsigned char upper = 0xBFU; + if (first == 0xF0U) { + lower = 0x90U; + } else if (first == 0xF4U) { + upper = 0x8FU; + } + if (MOZ_LIKELY(second >= lower && second <= upper)) { + ++p; + if (MOZ_LIKELY(p != end)) { + unsigned char third = *p; + if (MOZ_LIKELY((third & 0xC0U) == 0x80U)) { + ++p; + if (MOZ_LIKELY(p != end)) { + unsigned char fourth = *p; + if (MOZ_LIKELY((fourth & 0xC0U) == 0x80U)) { + ++p; + *aBuffer = reinterpret_cast(p); + return ((uint32_t(first) & 0x7U) << 18) | + ((uint32_t(second) & 0x3FU) << 12) | + ((uint32_t(third) & 0x3FU) << 6) | + (uint32_t(fourth) & 0x3FU); + } + } + } + } + } + *aBuffer = reinterpret_cast(p); + if (aErr) { + *aErr = true; + } + return 0xFFFDU; + } +}; + +/** + * Extract the next Unicode scalar value from the buffer and return it. The + * pointer passed in is advanced to the start of the next character in the + * buffer. Upon error, the return value is 0xFFFD, *aBuffer is advanced over + * the unpaired surrogate and *aErr is set to true (if aErr is not null). + * + * Note: This method never sets *aErr to false to allow error accumulation + * across multiple calls. + * + * Precondition: *aBuffer < aEnd + */ +class UTF16CharEnumerator { + public: + static inline char32_t NextChar(const char16_t** aBuffer, + const char16_t* aEnd, bool* aErr = nullptr) { + MOZ_ASSERT(aBuffer, "null buffer pointer pointer"); + MOZ_ASSERT(aEnd, "null end pointer"); + + const char16_t* p = *aBuffer; + + MOZ_ASSERT(p, "null buffer"); + MOZ_ASSERT(p < aEnd, "Bogus range"); + + char16_t c = *p++; + + // Let's use encoding_rs-style code golf here. + // Unsigned underflow is defined behavior + char16_t cMinusSurrogateStart = c - 0xD800U; + if (MOZ_LIKELY(cMinusSurrogateStart > (0xDFFFU - 0xD800U))) { + *aBuffer = p; + return c; + } + if (MOZ_LIKELY(cMinusSurrogateStart <= (0xDBFFU - 0xD800U))) { + // High surrogate + if (MOZ_LIKELY(p != aEnd)) { + char16_t second = *p; + // Unsigned underflow is defined behavior + if (MOZ_LIKELY((second - 0xDC00U) <= (0xDFFFU - 0xDC00U))) { + *aBuffer = ++p; + return (uint32_t(c) << 10) + uint32_t(second) - + (((0xD800U << 10) - 0x10000U) + 0xDC00U); + } + } + } + // Unpaired surrogate + *aBuffer = p; + if (aErr) { + *aErr = true; + } + return 0xFFFDU; + } +}; + +template +inline UnsignedT RewindToPriorUTF8Codepoint(const Char* utf8Chars, + UnsignedT index) { + static_assert(std::is_same_v || + std::is_same_v || + std::is_same_v, + "UTF-8 data must be in 8-bit units"); + static_assert(std::is_unsigned_v, "index type must be unsigned"); + while (index > 0 && (utf8Chars[index] & 0xC0) == 0x80) --index; + + return index; +} + +#undef UTF8UTILS_WARNING + +#endif /* !defined(nsUTF8Utils_h_) */ diff --git a/onlineupdate/inc/nsWindowsHelpers.h b/onlineupdate/inc/nsWindowsHelpers.h new file mode 100644 index 000000000000..7c9127580371 --- /dev/null +++ b/onlineupdate/inc/nsWindowsHelpers.h @@ -0,0 +1,339 @@ +/* -*- 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/. */ + +// NB: This code may be used from non-XPCOM code, in particular, the +// Windows Default Browser Agent. + +#ifndef nsWindowsHelpers_h +#define nsWindowsHelpers_h + +#include +#include +#include "nsAutoRef.h" +#include "mozilla/Assertions.h" +#include "mozilla/UniquePtr.h" + +// ---------------------------------------------------------------------------- +// Critical Section helper class +// ---------------------------------------------------------------------------- + +class AutoCriticalSection { + public: + explicit AutoCriticalSection(LPCRITICAL_SECTION aSection) + : mSection(aSection) { + ::EnterCriticalSection(mSection); + } + ~AutoCriticalSection() { ::LeaveCriticalSection(mSection); } + + private: + LPCRITICAL_SECTION mSection; +}; + +template <> +class nsAutoRefTraits { + public: + typedef HKEY RawRef; + static HKEY Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + RegCloseKey(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef HDC RawRef; + static HDC Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + ::DeleteDC(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef HFONT RawRef; + static HFONT Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + ::DeleteObject(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef HBRUSH RawRef; + static HBRUSH Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + ::DeleteObject(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef HRGN RawRef; + static HRGN Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + ::DeleteObject(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef HBITMAP RawRef; + static HBITMAP Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + ::DeleteObject(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef SC_HANDLE RawRef; + static SC_HANDLE Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + CloseServiceHandle(aFD); + } + } +}; + +template <> +class nsSimpleRef { + protected: + typedef HANDLE RawRef; + + nsSimpleRef() : mRawRef(nullptr) {} + + explicit nsSimpleRef(RawRef aRawRef) : mRawRef(aRawRef) {} + + bool HaveResource() const { + return mRawRef && mRawRef != INVALID_HANDLE_VALUE; + } + + public: + RawRef get() const { return mRawRef; } + + static void Release(RawRef aRawRef) { + if (aRawRef && aRawRef != INVALID_HANDLE_VALUE) { + CloseHandle(aRawRef); + } + } + RawRef mRawRef; +}; + +template <> +class nsAutoRefTraits { + public: + typedef HMODULE RawRef; + static RawRef Void() { return nullptr; } + + static void Release(RawRef aFD) { + if (aFD != Void()) { + FreeLibrary(aFD); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef DEVMODEW* RawRef; + static RawRef Void() { return nullptr; } + + static void Release(RawRef aDevMode) { + if (aDevMode != Void()) { + ::HeapFree(::GetProcessHeap(), 0, aDevMode); + } + } +}; + +template <> +class nsAutoRefTraits { + public: + typedef MSIHANDLE RawRef; + static RawRef Void() { return 0; } + + static void Release(RawRef aHandle) { + if (aHandle != Void()) { + ::MsiCloseHandle(aHandle); + } + } +}; + +// HGLOBAL is just a typedef of HANDLE which nsSimpleRef has a specialization +// of, that means having a nsAutoRefTraits specialization for HGLOBAL is +// useless. Therefore we create a wrapper class for HGLOBAL to make +// nsAutoRefTraits and nsAutoRef work as intention. +class nsHGLOBAL { + public: + MOZ_IMPLICIT nsHGLOBAL(HGLOBAL hGlobal) : m_hGlobal(hGlobal) {} + + operator HGLOBAL() const { return m_hGlobal; } + + private: + HGLOBAL m_hGlobal; +}; + +template <> +class nsAutoRefTraits { + public: + typedef nsHGLOBAL RawRef; + static RawRef Void() { return nullptr; } + + static void Release(RawRef hGlobal) { ::GlobalFree(hGlobal); } +}; + +// Because Printer's HANDLE uses ClosePrinter and we already have +// nsAutoRef which uses CloseHandle so we need to create a wrapper class +// for HANDLE to have another specialization for nsAutoRefTraits. +class nsHPRINTER { + public: + MOZ_IMPLICIT nsHPRINTER(HANDLE hPrinter) : m_hPrinter(hPrinter) {} + + operator HANDLE() const { return m_hPrinter; } + + HANDLE* operator&() { return &m_hPrinter; } + + private: + HANDLE m_hPrinter; +}; + +// winspool.h header has AddMonitor macro, it conflicts with AddMonitor member +// function in TaskbarPreview.cpp and TaskbarTabPreview.cpp. Beside, we only +// need ClosePrinter here for Release function, so having its prototype is +// enough. +extern "C" BOOL WINAPI ClosePrinter(HANDLE hPrinter); + +template <> +class nsAutoRefTraits { + public: + typedef nsHPRINTER RawRef; + static RawRef Void() { return nullptr; } + + static void Release(RawRef hPrinter) { ::ClosePrinter(hPrinter); } +}; + +typedef nsAutoRef nsAutoRegKey; +typedef nsAutoRef nsAutoHDC; +typedef nsAutoRef nsAutoFont; +typedef nsAutoRef nsAutoBrush; +typedef nsAutoRef nsAutoRegion; +typedef nsAutoRef nsAutoBitmap; +typedef nsAutoRef nsAutoServiceHandle; +typedef nsAutoRef nsAutoHandle; +typedef nsAutoRef nsModuleHandle; +typedef nsAutoRef nsAutoDevMode; +typedef nsAutoRef nsAutoGlobalMem; +typedef nsAutoRef nsAutoPrinter; +typedef nsAutoRef nsAutoMsiHandle; + +// Construct a path "\". return false if the output buffer +// is too small. +// Note: If the system path cannot be found, or doesn't fit in the output buffer +// with the module name, we will just ignore the system path and output the +// module name alone; +// this may mean using a normal search path wherever the output is used. +bool inline ConstructSystem32Path(LPCWSTR aModule, WCHAR* aSystemPath, + UINT aSize) { + MOZ_ASSERT(aSystemPath); + + size_t fileLen = wcslen(aModule); + if (fileLen >= aSize) { + // The module name alone cannot even fit! + return false; + } + + size_t systemDirLen = GetSystemDirectoryW(aSystemPath, aSize); + + if (systemDirLen) { + if (systemDirLen < aSize - fileLen) { + // Make the system directory path terminate with a slash. + if (aSystemPath[systemDirLen - 1] != L'\\') { + if (systemDirLen + 1 < aSize - fileLen) { + aSystemPath[systemDirLen] = L'\\'; + ++systemDirLen; + // No need to re-nullptr terminate. + } else { + // Couldn't fit the system path with added slash. + systemDirLen = 0; + } + } + } else { + // Couldn't fit the system path. + systemDirLen = 0; + } + } + + MOZ_ASSERT(systemDirLen + fileLen < aSize); + + wcsncpy(aSystemPath + systemDirLen, aModule, fileLen); + aSystemPath[systemDirLen + fileLen] = L'\0'; + return true; +} + +HMODULE inline LoadLibrarySystem32(LPCWSTR aModule) { + return LoadLibraryExW(aModule, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); +} + +// for UniquePtr +struct LocalFreeDeleter { + void operator()(void* aPtr) { ::LocalFree(aPtr); } +}; + +struct VirtualFreeDeleter { + void operator()(void* aPtr) { ::VirtualFree(aPtr, 0, MEM_RELEASE); } +}; + +// for UniquePtr to store a PSID +struct FreeSidDeleter { + void operator()(void* aPtr) { ::FreeSid(aPtr); } +}; +// Unfortunately, although SID is a struct, PSID is a void* +// This typedef will work for storing a PSID in a UniquePtr and should make +// things a bit more readable. +typedef mozilla::UniquePtr UniqueSidPtr; + +struct CloseHandleDeleter { + typedef HANDLE pointer; + void operator()(pointer aHandle) { + if (aHandle != INVALID_HANDLE_VALUE) { + ::CloseHandle(aHandle); + } + } +}; + +// One caller of this function is early in startup and several others are not, +// so they have different ways of determining the two parameters. This function +// exists just so any future code that needs to determine whether the dynamic +// blocklist is disabled remembers to check whether safe mode is active. +inline bool IsDynamicBlocklistDisabled(bool isSafeMode, + bool hasCommandLineDisableArgument) { + return isSafeMode || hasCommandLineDisableArgument; +} +#endif diff --git a/onlineupdate/source/service/nsAutoRef.h b/onlineupdate/source/service/nsAutoRef.h deleted file mode 100644 index 9a1f3ddd93e9..000000000000 --- a/onlineupdate/source/service/nsAutoRef.h +++ /dev/null @@ -1,489 +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/. */ - -// NB: This code may be used from non-XPCOM code, in particular, the -// Windows Default Browser Agent. - -#ifndef nsAutoRef_h_ -#define nsAutoRef_h_ - -#include "mozilla/Attributes.h" - -template -class nsSimpleRef; -template -class nsAutoRefBase; -template -class nsReturnRef; -template -class nsReturningRef; - -/** - * template class nsAutoRef - * - * A class that holds a handle to a resource that must be released. - * No reference is added on construction. - * - * No copy constructor nor copy assignment operators are available, so the - * resource will be held until released on destruction or explicitly - * |reset()| or transferred through provided methods. - * - * The publicly available methods are the public methods on this class and its - * public base classes |nsAutoRefBase| and |nsSimpleRef|. - * - * For function return values see |nsReturnRef|. - * - * For each class |T|, |nsAutoRefTraits| or |nsSimpleRef| must be - * specialized to use |nsAutoRef|. - * - * @param T A class identifying the type of reference held by the - * |nsAutoRef| and the unique set methods for managing references - * to the resource (defined by |nsAutoRefTraits| or - * |nsSimpleRef|). - * - * Often this is the class representing the resource. Sometimes a - * new possibly-incomplete class may need to be declared. - * - * - * Example: An Automatically closing file descriptor - * - * // References that are simple integral types (as file-descriptors are) - * // usually need a new class to represent the resource and how to handle its - * // references. - * class nsRawFD; - * - * // Specializing nsAutoRefTraits describes how to manage file - * // descriptors, so that nsAutoRef provides automatic closing of - * // its file descriptor on destruction. - * template <> - * class nsAutoRefTraits { - * public: - * // The file descriptor is held in an int. - * typedef int RawRef; - * // -1 means that there is no file associated with the handle. - * static int Void() { return -1; } - * // The file associated with a file descriptor is released with close(). - * static void Release(RawRef aFD) { close(aFD); } - * }; - * - * // A function returning a file descriptor that must be closed. - * nsReturnRef get_file(const char *filename) { - * // Constructing from a raw file descriptor assumes ownership. - * nsAutoRef fd(open(filename, O_RDONLY)); - * fcntl(fd, F_SETFD, FD_CLOEXEC); - * return fd.out(); - * } - * - * void f() { - * unsigned char buf[1024]; - * - * // Hold a file descriptor for /etc/hosts in fd1. - * nsAutoRef fd1(get_file("/etc/hosts")); - * - * nsAutoRef fd2; - * fd2.steal(fd1); // fd2 takes the file descriptor from fd1 - * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file - * count = read(fd2, buf, 1024); // reads from /etc/hosts - * - * // If the file descriptor is not stored then it is closed. - * get_file("/etc/login.defs"); // login.defs is closed - * - * // Now use fd1 to hold a file descriptor for /etc/passwd. - * fd1 = get_file("/etc/passwd"); - * - * // The nsAutoRef can give up the file descriptor if explicitly - * // instructed, but the caller must then ensure that the file is closed. - * int rawfd = fd1.disown(); - * - * // Assume ownership of another file descriptor. - * fd1.own(open("/proc/1/maps"); - * - * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts, - * // but /etc/passwd is not closed. - * } - * - */ - -template -class nsAutoRef : public nsAutoRefBase { - protected: - typedef nsAutoRef ThisClass; - typedef nsAutoRefBase BaseClass; - typedef nsSimpleRef SimpleRef; - typedef typename BaseClass::RawRefOnly RawRefOnly; - typedef typename BaseClass::LocalSimpleRef LocalSimpleRef; - - public: - nsAutoRef() = default; - - // Explicit construction is required so as not to risk unintentionally - // releasing the resource associated with a raw ref. - explicit nsAutoRef(RawRefOnly aRefToRelease) : BaseClass(aRefToRelease) {} - - // Construction from a nsReturnRef function return value, which expects - // to give up ownership, transfers ownership. - // (nsReturnRef is converted to const nsReturningRef.) - explicit nsAutoRef(const nsReturningRef& aReturning) - : BaseClass(aReturning) {} - - // The only assignment operator provided is for transferring from an - // nsReturnRef smart reference, which expects to pass its ownership to - // another object. - // - // With raw references and other smart references, the type of the lhs and - // its taking and releasing nature is often not obvious from an assignment - // statement. Assignment from a raw ptr especially is not normally - // expected to release the reference. - // - // Use |steal| for taking ownership from other smart refs. - // - // For raw references, use |own| to indicate intention to have the - // resource released. - - ThisClass& operator=(const nsReturningRef& aReturning) { - BaseClass::steal(aReturning.mReturnRef); - return *this; - } - - // Conversion to a raw reference allow the nsAutoRef to often be used - // like a raw reference. - operator typename SimpleRef::RawRef() const { return this->get(); } - - explicit operator bool() const { return this->HaveResource(); } - - // Transfer ownership from another smart reference. - void steal(ThisClass& aOtherRef) { BaseClass::steal(aOtherRef); } - - // Assume ownership of a raw ref. - // - // |own| has similar function to |steal|, and is useful for receiving - // ownership from a return value of a function. It is named differently - // because |own| requires more care to ensure that the function intends to - // give away ownership, and so that |steal| can be safely used, knowing - // that it won't steal ownership from any methods returning raw ptrs to - // data owned by a foreign object. - void own(RawRefOnly aRefToRelease) { BaseClass::own(aRefToRelease); } - - // Exchange ownership with |aOther| - void swap(ThisClass& aOther) { - LocalSimpleRef temp; - temp.SimpleRef::operator=(*this); - SimpleRef::operator=(aOther); - aOther.SimpleRef::operator=(temp); - } - - // Release the reference now. - void reset() { - this->SafeRelease(); - LocalSimpleRef empty; - SimpleRef::operator=(empty); - } - - // Pass out the reference for a function return values. - nsReturnRef out() { return nsReturnRef(this->disown()); } - - // operator->() and disown() are provided by nsAutoRefBase. - // The default nsSimpleRef provides get(). - - // No copy constructor - explicit nsAutoRef(const ThisClass& aRefToSteal) = delete; -}; - -/** - * template class nsReturnRef - * - * A type for function return values that hold a reference to a resource that - * must be released. See also |nsAutoRef::out()|. - */ - -template -class nsReturnRef : public nsAutoRefBase { - protected: - typedef nsAutoRefBase BaseClass; - typedef typename BaseClass::RawRefOnly RawRefOnly; - - public: - // For constructing a return value with no resource - nsReturnRef() = default; - - // For returning a smart reference from a raw reference that must be - // released. Explicit construction is required so as not to risk - // unintentionally releasing the resource associated with a raw ref. - MOZ_IMPLICIT nsReturnRef(RawRefOnly aRefToRelease) - : BaseClass(aRefToRelease) {} - - // Move construction transfers ownership - nsReturnRef(nsReturnRef&& aRefToSteal) = default; - - MOZ_IMPLICIT nsReturnRef(const nsReturningRef& aReturning) - : BaseClass(aReturning) {} - - // Conversion to a temporary (const) object referring to this object so - // that the reference may be passed from a function return value - // (temporary) to another smart reference. There is no need to use this - // explicitly. Simply assign a nsReturnRef function return value to a - // smart reference. - operator nsReturningRef() { return nsReturningRef(*this); } - - // No conversion to RawRef operator is provided on nsReturnRef, to ensure - // that the return value is not carelessly assigned to a raw ptr (and the - // resource then released). If passing to a function that takes a raw - // ptr, use get or disown as appropriate. -}; - -/** - * template class nsReturningRef - * - * A class to allow ownership to be transferred from nsReturnRef function - * return values. - * - * It should not be necessary for clients to reference this - * class directly. Simply pass an nsReturnRef to a parameter taking an - * |nsReturningRef|. - * - * The conversion operator on nsReturnRef constructs a temporary wrapper of - * class nsReturningRef around a non-const reference to the nsReturnRef. - * The wrapper can then be passed as an rvalue parameter. - */ - -template -class nsReturningRef { - private: - friend class nsReturnRef; - - explicit nsReturningRef(nsReturnRef& aReturnRef) - : mReturnRef(aReturnRef) {} - - public: - nsReturnRef& mReturnRef; -}; - -/** - * template class nsAutoRefTraits - * - * A class describing traits of references managed by the default - * |nsSimpleRef| implementation and thus |nsAutoRef|. - * The default |nsSimpleRef is suitable for resources with handles that - * have a void value. (If there is no such void value for a handle, - * specialize |nsSimpleRef|.) - * - * Specializations must be provided for each class |T| according to the - * following pattern: - * - * // The template parameter |T| should be a class such that the set of fields - * // in class nsAutoRefTraits is unique for class |T|. Usually the - * // resource object class is sufficient. For handles that are simple - * // integral typedefs, a new unique possibly-incomplete class may need to be - * // declared. - * - * template <> - * class nsAutoRefTraits - * { - * // Specializations must provide a typedef for RawRef, describing the - * // type of the handle to the resource. - * typedef RawRef; - * - * // Specializations should define Void(), a function returning a value - * // suitable for a handle that does not have an associated resource. - * // - * // The return type must be a suitable as the parameter to a RawRef - * // constructor and operator==. - * // - * // If this method is not accessible then some limited nsAutoRef - * // functionality will still be available, but the default constructor, - * // |reset|, and most transfer of ownership methods will not be available. - * static Void(); - * - * // Specializations must define Release() to properly finalize the - * // handle to a non-void custom-deleted or reference-counted resource. - * static void Release(RawRef aRawRef); - * }; - * - * See nsPointerRefTraits for example specializations for simple pointer - * references. See nsAutoRef for an example specialization for a non-pointer - * reference. - */ - -template -class nsAutoRefTraits; - -/** - * template class nsPointerRefTraits - * - * A convenience class useful as a base class for specializations of - * |nsAutoRefTraits| where the handle to the resource is a pointer to |T|. - * By inheriting from this class, definitions of only Release(RawRef) and - * possibly AddRef(RawRef) need to be added. - * - * Examples of use: - * - * template <> - * class nsAutoRefTraits : public nsPointerRefTraits - * { - * public: - * static void Release(PRFileDesc *ptr) { PR_Close(ptr); } - * }; - * - * template <> - * class nsAutoRefTraits : public nsPointerRefTraits - * { - * public: - * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } - * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } - * }; - */ - -template -class nsPointerRefTraits { - public: - // The handle is a pointer to T. - typedef T* RawRef; - // A nullptr does not have a resource. - static RawRef Void() { return nullptr; } -}; - -/** - * template class nsSimpleRef - * - * Constructs a non-smart reference, and provides methods to test whether - * there is an associated resource and (if so) get its raw handle. - * - * A default implementation is suitable for resources with handles that have a - * void value. This is not intended for direct use but used by |nsAutoRef|. - * - * Specialize this class if there is no particular void value for the resource - * handle. A specialized implementation must also provide Release(RawRef), - */ - -template -class nsSimpleRef : protected nsAutoRefTraits { - protected: - // The default implementation uses nsAutoRefTrait. - // Specializations need not define this typedef. - typedef nsAutoRefTraits Traits; - // The type of the handle to the resource. - // A specialization must provide a typedef for RawRef. - typedef typename Traits::RawRef RawRef; - - // Construct with no resource. - // - // If this constructor is not accessible then some limited nsAutoRef - // functionality will still be available, but the default constructor, - // |reset|, and most transfer of ownership methods will not be available. - nsSimpleRef() : mRawRef(Traits::Void()) {} - // Construct with a handle to a resource. - // A specialization must provide this. - explicit nsSimpleRef(RawRef aRawRef) : mRawRef(aRawRef) {} - - // Test whether there is an associated resource. A specialization must - // provide this. The function is permitted to always return true if the - // default constructor is not accessible, or if Release (and AddRef) can - // deal with void handles. - bool HaveResource() const { return mRawRef != Traits::Void(); } - - public: - // A specialization must provide get() or loose some functionality. This - // is inherited by derived classes and the specialization may choose - // whether it is public or protected. - RawRef get() const { return mRawRef; } - - private: - RawRef mRawRef; -}; - -/** - * template class nsAutoRefBase - * - * Internal base class for |nsAutoRef| and |nsReturnRef|. - * Adds release on destruction to a |nsSimpleRef|. - */ - -template -class nsAutoRefBase : public nsSimpleRef { - protected: - typedef nsAutoRefBase ThisClass; - typedef nsSimpleRef SimpleRef; - typedef typename SimpleRef::RawRef RawRef; - - nsAutoRefBase() = default; - - // A type for parameters that should be passed a raw ref but should not - // accept implicit conversions (from another smart ref). (The only - // conversion to this type is from a raw ref so only raw refs will be - // accepted.) - class RawRefOnly { - public: - MOZ_IMPLICIT RawRefOnly(RawRef aRawRef) : mRawRef(aRawRef) {} - operator RawRef() const { return mRawRef; } - - private: - RawRef mRawRef; - }; - - // Construction from a raw ref assumes ownership - explicit nsAutoRefBase(RawRefOnly aRefToRelease) : SimpleRef(aRefToRelease) {} - - // Constructors that steal ownership - nsAutoRefBase(ThisClass&& aRefToSteal) : SimpleRef(aRefToSteal.disown()) {} - explicit nsAutoRefBase(const nsReturningRef& aReturning) - : SimpleRef(aReturning.mReturnRef.disown()) {} - - ~nsAutoRefBase() { SafeRelease(); } - - // An internal class providing access to protected nsSimpleRef - // constructors for construction of temporary simple references (that are - // not ThisClass). - class LocalSimpleRef : public SimpleRef { - public: - LocalSimpleRef() = default; - explicit LocalSimpleRef(RawRef aRawRef) : SimpleRef(aRawRef) {} - }; - - public: - ThisClass& operator=(const ThisClass& aSmartRef) = delete; - - RawRef operator->() const { return this->get(); } - - // Transfer ownership to a raw reference. - // - // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED. - // - // Is this really what you want to use? Using this removes any guarantee - // of release. Use nsAutoRef::out() for return values, or an - // nsAutoRef modifiable lvalue for an out parameter. Use disown() when - // the reference must be stored in a POD type object, such as may be - // preferred for a namespace-scope object with static storage duration, - // for example. - RawRef disown() { - RawRef temp = this->get(); - LocalSimpleRef empty; - SimpleRef::operator=(empty); - return temp; - } - - protected: - // steal and own are protected because they make no sense on nsReturnRef, - // but steal is implemented on this class for access to aOtherRef.disown() - // when aOtherRef is an nsReturnRef; - - // Transfer ownership from another smart reference. - void steal(ThisClass& aOtherRef) { own(aOtherRef.disown()); } - // Assume ownership of a raw ref. - void own(RawRefOnly aRefToRelease) { - SafeRelease(); - LocalSimpleRef ref(aRefToRelease); - SimpleRef::operator=(ref); - } - - // Release a resource if there is one. - void SafeRelease() { - if (this->HaveResource()) { - this->Release(this->get()); - } - } -}; - -#endif // !defined(nsAutoRef_h_) diff --git a/onlineupdate/source/service/nsCharTraits.h b/onlineupdate/source/service/nsCharTraits.h deleted file mode 100644 index c81c2f5b2d3b..000000000000 --- a/onlineupdate/source/service/nsCharTraits.h +++ /dev/null @@ -1,486 +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 nsCharTraits_h___ -#define nsCharTraits_h___ - -#include // for |EOF|, |WEOF| -#include // for |uint32_t| -#include // for |memcpy|, et al -#include "mozilla/MemoryChecking.h" - -// This file may be used (through nsUTF8Utils.h) from non-XPCOM code, in -// particular the standalone software updater. In that case stub out -// the macros provided by nsDebug.h which are only usable when linking XPCOM - -#ifdef NS_NO_XPCOM -# define NS_WARNING(msg) -# define NS_ASSERTION(cond, msg) -# define NS_ERROR(msg) -#else -# include "nsDebug.h" // for NS_ASSERTION -#endif - -/* - * Some macros for converting char16_t (UTF-16) to and from Unicode scalar - * values. - * - * Note that UTF-16 represents all Unicode scalar values up to U+10FFFF by - * using "surrogate pairs". These consist of a high surrogate, i.e. a code - * point in the range U+D800 - U+DBFF, and a low surrogate, i.e. a code point - * in the range U+DC00 - U+DFFF, like this: - * - * U+D800 U+DC00 = U+10000 - * U+D800 U+DC01 = U+10001 - * ... - * U+DBFF U+DFFE = U+10FFFE - * U+DBFF U+DFFF = U+10FFFF - * - * These surrogate code points U+D800 - U+DFFF are not themselves valid Unicode - * scalar values and are not well-formed UTF-16 except as high-surrogate / - * low-surrogate pairs. - */ - -#define PLANE1_BASE uint32_t(0x00010000) -// High surrogates are in the range 0xD800 -- OxDBFF -#define NS_IS_HIGH_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xD800) -// Low surrogates are in the range 0xDC00 -- 0xDFFF -#define NS_IS_LOW_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xDC00) -// Easier to type than NS_IS_HIGH_SURROGATE && NS_IS_LOW_SURROGATE -#define NS_IS_SURROGATE_PAIR(h, l) \ - (NS_IS_HIGH_SURROGATE(h) && NS_IS_LOW_SURROGATE(l)) -// Faster than testing NS_IS_HIGH_SURROGATE || NS_IS_LOW_SURROGATE -#define IS_SURROGATE(u) ((uint32_t(u) & 0xFFFFF800) == 0xD800) - -// Everything else is not a surrogate: 0x000 -- 0xD7FF, 0xE000 -- 0xFFFF - -// N = (H - 0xD800) * 0x400 + 0x10000 + (L - 0xDC00) -// I wonder whether we could somehow assert that H is a high surrogate -// and L is a low surrogate -#define SURROGATE_TO_UCS4(h, l) \ - (((uint32_t(h) & 0x03FF) << 10) + (uint32_t(l) & 0x03FF) + PLANE1_BASE) - -// Extract surrogates from a UCS4 char -// Reference: the Unicode standard 4.0, section 3.9 -// Since (c - 0x10000) >> 10 == (c >> 10) - 0x0080 and -// 0xD7C0 == 0xD800 - 0x0080, -// ((c - 0x10000) >> 10) + 0xD800 can be simplified to -#define H_SURROGATE(c) char16_t(char16_t(uint32_t(c) >> 10) + char16_t(0xD7C0)) -// where it's to be noted that 0xD7C0 is not bitwise-OR'd -// but added. - -// Since 0x10000 & 0x03FF == 0, -// (c - 0x10000) & 0x03FF == c & 0x03FF so that -// ((c - 0x10000) & 0x03FF) | 0xDC00 is equivalent to -#define L_SURROGATE(c) \ - char16_t(char16_t(uint32_t(c) & uint32_t(0x03FF)) | char16_t(0xDC00)) - -#define IS_IN_BMP(ucs) (uint32_t(ucs) < PLANE1_BASE) -#define UCS2_REPLACEMENT_CHAR char16_t(0xFFFD) - -#define UCS_END uint32_t(0x00110000) -#define IS_VALID_CHAR(c) ((uint32_t(c) < UCS_END) && !IS_SURROGATE(c)) -#define ENSURE_VALID_CHAR(c) (IS_VALID_CHAR(c) ? (c) : UCS2_REPLACEMENT_CHAR) - -template -struct nsCharTraits {}; - -template <> -struct nsCharTraits { - typedef char16_t char_type; - typedef uint16_t unsigned_char_type; - typedef char incompatible_char_type; - - static char_type* const sEmptyBuffer; - - // integer representation of characters: - typedef int int_type; - - static char_type to_char_type(int_type aChar) { return char_type(aChar); } - - static int_type to_int_type(char_type aChar) { - return int_type(static_cast(aChar)); - } - - static bool eq_int_type(int_type aLhs, int_type aRhs) { return aLhs == aRhs; } - - // |char_type| comparisons: - - static bool eq(char_type aLhs, char_type aRhs) { return aLhs == aRhs; } - - static bool lt(char_type aLhs, char_type aRhs) { return aLhs < aRhs; } - - // operations on s[n] arrays: - - static char_type* move(char_type* aStr1, const char_type* aStr2, size_t aN) { - return static_cast( - memmove(aStr1, aStr2, aN * sizeof(char_type))); - } - - static char_type* copy(char_type* aStr1, const char_type* aStr2, size_t aN) { - return static_cast( - memcpy(aStr1, aStr2, aN * sizeof(char_type))); - } - - static void uninitialize(char_type* aStr, size_t aN) { -#ifdef DEBUG - memset(aStr, 0xE4, aN * sizeof(char_type)); -#endif - MOZ_MAKE_MEM_UNDEFINED(aStr, aN * sizeof(char_type)); - } - - static char_type* copyASCII(char_type* aStr1, const char* aStr2, size_t aN) { - for (char_type* s = aStr1; aN--; ++s, ++aStr2) { - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - *s = static_cast(*aStr2); - } - return aStr1; - } - - static int compare(const char_type* aStr1, const char_type* aStr2, - size_t aN) { - for (; aN--; ++aStr1, ++aStr2) { - if (!eq(*aStr1, *aStr2)) { - return to_int_type(*aStr1) - to_int_type(*aStr2); - } - } - - return 0; - } - - static int compareASCII(const char_type* aStr1, const char* aStr2, - size_t aN) { - for (; aN--; ++aStr1, ++aStr2) { - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - if (!eq_int_type(to_int_type(*aStr1), - to_int_type(static_cast(*aStr2)))) { - return to_int_type(*aStr1) - - to_int_type(static_cast(*aStr2)); - } - } - - return 0; - } - - static bool equalsLatin1(const char_type* aStr1, const char* aStr2, - const size_t aN) { - for (size_t i = aN; i > 0; --i, ++aStr1, ++aStr2) { - if (*aStr1 != static_cast(*aStr2)) { - return false; - } - } - - return true; - } - - // this version assumes that s2 is null-terminated and s1 has length n. - // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, - // we return 1. - static int compareASCIINullTerminated(const char_type* aStr1, size_t aN, - const char* aStr2) { - for (; aN--; ++aStr1, ++aStr2) { - if (!*aStr2) { - return 1; - } - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - if (!eq_int_type(to_int_type(*aStr1), - to_int_type(static_cast(*aStr2)))) { - return to_int_type(*aStr1) - - to_int_type(static_cast(*aStr2)); - } - } - - if (*aStr2) { - return -1; - } - - return 0; - } - - /** - * Convert c to its lower-case form, but only if c is in the ASCII - * range. Otherwise leave it alone. - */ - static char_type ASCIIToLower(char_type aChar) { - if (aChar >= 'A' && aChar <= 'Z') { - return char_type(aChar + ('a' - 'A')); - } - - return aChar; - } - - static int compareLowerCaseToASCII(const char_type* aStr1, const char* aStr2, - size_t aN) { - for (; aN--; ++aStr1, ++aStr2) { - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), - "Unexpected uppercase character"); - char_type lower_s1 = ASCIIToLower(*aStr1); - if (lower_s1 != static_cast(*aStr2)) { - return to_int_type(lower_s1) - - to_int_type(static_cast(*aStr2)); - } - } - - return 0; - } - - // this version assumes that s2 is null-terminated and s1 has length n. - // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, - // we return 1. - static int compareLowerCaseToASCIINullTerminated(const char_type* aStr1, - size_t aN, - const char* aStr2) { - for (; aN--; ++aStr1, ++aStr2) { - if (!*aStr2) { - return 1; - } - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), - "Unexpected uppercase character"); - char_type lower_s1 = ASCIIToLower(*aStr1); - if (lower_s1 != static_cast(*aStr2)) { - return to_int_type(lower_s1) - - to_int_type(static_cast(*aStr2)); - } - } - - if (*aStr2) { - return -1; - } - - return 0; - } - - static size_t length(const char_type* aStr) { - size_t result = 0; - while (!eq(*aStr++, char_type(0))) { - ++result; - } - return result; - } - - static const char_type* find(const char_type* aStr, size_t aN, - char_type aChar) { - while (aN--) { - if (eq(*aStr, aChar)) { - return aStr; - } - ++aStr; - } - - return 0; - } -}; - -template <> -struct nsCharTraits { - typedef char char_type; - typedef unsigned char unsigned_char_type; - typedef char16_t incompatible_char_type; - - static char_type* const sEmptyBuffer; - - // integer representation of characters: - - typedef int int_type; - - static char_type to_char_type(int_type aChar) { return char_type(aChar); } - - static int_type to_int_type(char_type aChar) { - return int_type(static_cast(aChar)); - } - - static bool eq_int_type(int_type aLhs, int_type aRhs) { return aLhs == aRhs; } - - // |char_type| comparisons: - - static bool eq(char_type aLhs, char_type aRhs) { return aLhs == aRhs; } - - static bool lt(char_type aLhs, char_type aRhs) { return aLhs < aRhs; } - - // operations on s[n] arrays: - - static char_type* move(char_type* aStr1, const char_type* aStr2, size_t aN) { - return static_cast( - memmove(aStr1, aStr2, aN * sizeof(char_type))); - } - - static char_type* copy(char_type* aStr1, const char_type* aStr2, size_t aN) { - return static_cast( - memcpy(aStr1, aStr2, aN * sizeof(char_type))); - } - - static void uninitialize(char_type* aStr, size_t aN) { -#ifdef DEBUG - memset(aStr, 0xE4, aN * sizeof(char_type)); -#endif - MOZ_MAKE_MEM_UNDEFINED(aStr, aN * sizeof(char_type)); - } - - static char_type* copyASCII(char_type* aStr1, const char* aStr2, size_t aN) { - return copy(aStr1, aStr2, aN); - } - - static int compare(const char_type* aStr1, const char_type* aStr2, - size_t aN) { - return memcmp(aStr1, aStr2, aN); - } - - static int compareASCII(const char_type* aStr1, const char* aStr2, - size_t aN) { -#ifdef DEBUG - for (size_t i = 0; i < aN; ++i) { - NS_ASSERTION(!(aStr2[i] & ~0x7F), "Unexpected non-ASCII character"); - } -#endif - return compare(aStr1, aStr2, aN); - } - - static bool equalsLatin1(const char_type* aStr1, const char* aStr2, - size_t aN) { - return memcmp(aStr1, aStr2, aN) == 0; - } - - // this version assumes that s2 is null-terminated and s1 has length n. - // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, - // we return 1. - static int compareASCIINullTerminated(const char_type* aStr1, size_t aN, - const char* aStr2) { - // can't use strcmp here because we don't want to stop when aStr1 - // contains a null - for (; aN--; ++aStr1, ++aStr2) { - if (!*aStr2) { - return 1; - } - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - if (*aStr1 != *aStr2) { - return to_int_type(*aStr1) - to_int_type(*aStr2); - } - } - - if (*aStr2) { - return -1; - } - - return 0; - } - - /** - * Convert c to its lower-case form, but only if c is ASCII. - */ - static char_type ASCIIToLower(char_type aChar) { - if (aChar >= 'A' && aChar <= 'Z') { - return char_type(aChar + ('a' - 'A')); - } - - return aChar; - } - - static int compareLowerCaseToASCII(const char_type* aStr1, const char* aStr2, - size_t aN) { - for (; aN--; ++aStr1, ++aStr2) { - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), - "Unexpected uppercase character"); - char_type lower_s1 = ASCIIToLower(*aStr1); - if (lower_s1 != *aStr2) { - return to_int_type(lower_s1) - to_int_type(*aStr2); - } - } - return 0; - } - - // this version assumes that s2 is null-terminated and s1 has length n. - // if s1 is shorter than s2 then we return -1; if s1 is longer than s2, - // we return 1. - static int compareLowerCaseToASCIINullTerminated(const char_type* aStr1, - size_t aN, - const char* aStr2) { - for (; aN--; ++aStr1, ++aStr2) { - if (!*aStr2) { - return 1; - } - NS_ASSERTION(!(*aStr2 & ~0x7F), "Unexpected non-ASCII character"); - NS_ASSERTION(!(*aStr2 >= 'A' && *aStr2 <= 'Z'), - "Unexpected uppercase character"); - char_type lower_s1 = ASCIIToLower(*aStr1); - if (lower_s1 != *aStr2) { - return to_int_type(lower_s1) - to_int_type(*aStr2); - } - } - - if (*aStr2) { - return -1; - } - - return 0; - } - - static size_t length(const char_type* aStr) { return strlen(aStr); } - - static const char_type* find(const char_type* aStr, size_t aN, - char_type aChar) { - return reinterpret_cast( - memchr(aStr, to_int_type(aChar), aN)); - } -}; - -template -struct nsCharSourceTraits { - typedef typename InputIterator::difference_type difference_type; - - static difference_type readable_distance(const InputIterator& aFirst, - const InputIterator& aLast) { - // assumes single fragment - return aLast.get() - aFirst.get(); - } - - static const typename InputIterator::value_type* read( - const InputIterator& aIter) { - return aIter.get(); - } - - static void advance(InputIterator& aStr, difference_type aN) { - aStr.advance(aN); - } -}; - -template -struct nsCharSourceTraits { - typedef ptrdiff_t difference_type; - - static difference_type readable_distance(CharT* aStr) { - return nsCharTraits::length(aStr); - } - - static difference_type readable_distance(CharT* aFirst, CharT* aLast) { - return aLast - aFirst; - } - - static const CharT* read(CharT* aStr) { return aStr; } - - static void advance(CharT*& aStr, difference_type aN) { aStr += aN; } -}; - -template -struct nsCharSinkTraits { - static void write(OutputIterator& aIter, - const typename OutputIterator::value_type* aStr, - size_t aN) { - aIter.write(aStr, aN); - } -}; - -template -struct nsCharSinkTraits { - static void write(CharT*& aIter, const CharT* aStr, size_t aN) { - nsCharTraits::move(aIter, aStr, aN); - aIter += aN; - } -}; - -#endif // !defined(nsCharTraits_h___) diff --git a/onlineupdate/source/service/nsUTF8Utils.h b/onlineupdate/source/service/nsUTF8Utils.h deleted file mode 100644 index 0145011ec152..000000000000 --- a/onlineupdate/source/service/nsUTF8Utils.h +++ /dev/null @@ -1,247 +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 nsUTF8Utils_h_ -#define nsUTF8Utils_h_ - -// NB: This code may be used from non-XPCOM code, in particular, the -// standalone updater executable. That is, this file may be used in -// two ways: if MOZILLA_INTERNAL_API is defined, this file will -// provide signatures for the Mozilla abstract string types. It will -// use XPCOM assertion/debugging macros, etc. - -#include - -#include "mozilla/Assertions.h" -#include "mozilla/EndianUtils.h" - -#include "nsCharTraits.h" - -#ifdef MOZILLA_INTERNAL_API -# define UTF8UTILS_WARNING(msg) NS_WARNING(msg) -#else -# define UTF8UTILS_WARNING(msg) -#endif - -class UTF8traits { - public: - static bool isASCII(char aChar) { return (aChar & 0x80) == 0x00; } - static bool isInSeq(char aChar) { return (aChar & 0xC0) == 0x80; } - static bool is2byte(char aChar) { return (aChar & 0xE0) == 0xC0; } - static bool is3byte(char aChar) { return (aChar & 0xF0) == 0xE0; } - static bool is4byte(char aChar) { return (aChar & 0xF8) == 0xF0; } - static bool is5byte(char aChar) { return (aChar & 0xFC) == 0xF8; } - static bool is6byte(char aChar) { return (aChar & 0xFE) == 0xFC; } - // return the number of bytes in a sequence beginning with aChar - static int bytes(char aChar) { - if (isASCII(aChar)) { - return 1; - } - if (is2byte(aChar)) { - return 2; - } - if (is3byte(aChar)) { - return 3; - } - if (is4byte(aChar)) { - return 4; - } - MOZ_ASSERT_UNREACHABLE("should not be used for in-sequence characters"); - return 1; - } -}; - -/** - * Extract the next Unicode scalar value from the buffer and return it. The - * pointer passed in is advanced to the start of the next character in the - * buffer. Upon error, the return value is 0xFFFD, *aBuffer is advanced - * over the maximal valid prefix and *aErr is set to true (if aErr is not - * null). - * - * Note: This method never sets *aErr to false to allow error accumulation - * across multiple calls. - * - * Precondition: *aBuffer < aEnd - */ -class UTF8CharEnumerator { - public: - static inline char32_t NextChar(const char** aBuffer, const char* aEnd, - bool* aErr = nullptr) { - MOZ_ASSERT(aBuffer, "null buffer pointer pointer"); - MOZ_ASSERT(aEnd, "null end pointer"); - - const unsigned char* p = reinterpret_cast(*aBuffer); - const unsigned char* end = reinterpret_cast(aEnd); - - MOZ_ASSERT(p, "null buffer"); - MOZ_ASSERT(p < end, "Bogus range"); - - unsigned char first = *p; - ++p; - - if (MOZ_LIKELY(first < 0x80U)) { - *aBuffer = reinterpret_cast(p); - return first; - } - - // Unsigned underflow is defined behavior - if (MOZ_UNLIKELY((p == end) || ((first - 0xC2U) >= (0xF5U - 0xC2U)))) { - *aBuffer = reinterpret_cast(p); - if (aErr) { - *aErr = true; - } - return 0xFFFDU; - } - - unsigned char second = *p; - - if (first < 0xE0U) { - // Two-byte - if (MOZ_LIKELY((second & 0xC0U) == 0x80U)) { - ++p; - *aBuffer = reinterpret_cast(p); - return ((uint32_t(first) & 0x1FU) << 6) | (uint32_t(second) & 0x3FU); - } - *aBuffer = reinterpret_cast(p); - if (aErr) { - *aErr = true; - } - return 0xFFFDU; - } - - if (MOZ_LIKELY(first < 0xF0U)) { - // Three-byte - unsigned char lower = 0x80U; - unsigned char upper = 0xBFU; - if (first == 0xE0U) { - lower = 0xA0U; - } else if (first == 0xEDU) { - upper = 0x9FU; - } - if (MOZ_LIKELY(second >= lower && second <= upper)) { - ++p; - if (MOZ_LIKELY(p != end)) { - unsigned char third = *p; - if (MOZ_LIKELY((third & 0xC0U) == 0x80U)) { - ++p; - *aBuffer = reinterpret_cast(p); - return ((uint32_t(first) & 0xFU) << 12) | - ((uint32_t(second) & 0x3FU) << 6) | - (uint32_t(third) & 0x3FU); - } - } - } - *aBuffer = reinterpret_cast(p); - if (aErr) { - *aErr = true; - } - return 0xFFFDU; - } - - // Four-byte - unsigned char lower = 0x80U; - unsigned char upper = 0xBFU; - if (first == 0xF0U) { - lower = 0x90U; - } else if (first == 0xF4U) { - upper = 0x8FU; - } - if (MOZ_LIKELY(second >= lower && second <= upper)) { - ++p; - if (MOZ_LIKELY(p != end)) { - unsigned char third = *p; - if (MOZ_LIKELY((third & 0xC0U) == 0x80U)) { - ++p; - if (MOZ_LIKELY(p != end)) { - unsigned char fourth = *p; - if (MOZ_LIKELY((fourth & 0xC0U) == 0x80U)) { - ++p; - *aBuffer = reinterpret_cast(p); - return ((uint32_t(first) & 0x7U) << 18) | - ((uint32_t(second) & 0x3FU) << 12) | - ((uint32_t(third) & 0x3FU) << 6) | - (uint32_t(fourth) & 0x3FU); - } - } - } - } - } - *aBuffer = reinterpret_cast(p); - if (aErr) { - *aErr = true; - } - return 0xFFFDU; - } -}; - -/** - * Extract the next Unicode scalar value from the buffer and return it. The - * pointer passed in is advanced to the start of the next character in the - * buffer. Upon error, the return value is 0xFFFD, *aBuffer is advanced over - * the unpaired surrogate and *aErr is set to true (if aErr is not null). - * - * Note: This method never sets *aErr to false to allow error accumulation - * across multiple calls. - * - * Precondition: *aBuffer < aEnd - */ -class UTF16CharEnumerator { - public: - static inline char32_t NextChar(const char16_t** aBuffer, - const char16_t* aEnd, bool* aErr = nullptr) { - MOZ_ASSERT(aBuffer, "null buffer pointer pointer"); - MOZ_ASSERT(aEnd, "null end pointer"); - - const char16_t* p = *aBuffer; - - MOZ_ASSERT(p, "null buffer"); - MOZ_ASSERT(p < aEnd, "Bogus range"); - - char16_t c = *p++; - - // Let's use encoding_rs-style code golf here. - // Unsigned underflow is defined behavior - char16_t cMinusSurrogateStart = c - 0xD800U; - if (MOZ_LIKELY(cMinusSurrogateStart > (0xDFFFU - 0xD800U))) { - *aBuffer = p; - return c; - } - if (MOZ_LIKELY(cMinusSurrogateStart <= (0xDBFFU - 0xD800U))) { - // High surrogate - if (MOZ_LIKELY(p != aEnd)) { - char16_t second = *p; - // Unsigned underflow is defined behavior - if (MOZ_LIKELY((second - 0xDC00U) <= (0xDFFFU - 0xDC00U))) { - *aBuffer = ++p; - return (uint32_t(c) << 10) + uint32_t(second) - - (((0xD800U << 10) - 0x10000U) + 0xDC00U); - } - } - } - // Unpaired surrogate - *aBuffer = p; - if (aErr) { - *aErr = true; - } - return 0xFFFDU; - } -}; - -template -inline UnsignedT RewindToPriorUTF8Codepoint(const Char* utf8Chars, - UnsignedT index) { - static_assert(std::is_same_v || - std::is_same_v || - std::is_same_v, - "UTF-8 data must be in 8-bit units"); - static_assert(std::is_unsigned_v, "index type must be unsigned"); - while (index > 0 && (utf8Chars[index] & 0xC0) == 0x80) --index; - - return index; -} - -#undef UTF8UTILS_WARNING - -#endif /* !defined(nsUTF8Utils_h_) */ diff --git a/onlineupdate/source/service/nsWindowsHelpers.h b/onlineupdate/source/service/nsWindowsHelpers.h deleted file mode 100644 index 7c9127580371..000000000000 --- a/onlineupdate/source/service/nsWindowsHelpers.h +++ /dev/null @@ -1,339 +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/. */ - -// NB: This code may be used from non-XPCOM code, in particular, the -// Windows Default Browser Agent. - -#ifndef nsWindowsHelpers_h -#define nsWindowsHelpers_h - -#include -#include -#include "nsAutoRef.h" -#include "mozilla/Assertions.h" -#include "mozilla/UniquePtr.h" - -// ---------------------------------------------------------------------------- -// Critical Section helper class -// ---------------------------------------------------------------------------- - -class AutoCriticalSection { - public: - explicit AutoCriticalSection(LPCRITICAL_SECTION aSection) - : mSection(aSection) { - ::EnterCriticalSection(mSection); - } - ~AutoCriticalSection() { ::LeaveCriticalSection(mSection); } - - private: - LPCRITICAL_SECTION mSection; -}; - -template <> -class nsAutoRefTraits { - public: - typedef HKEY RawRef; - static HKEY Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - RegCloseKey(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef HDC RawRef; - static HDC Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - ::DeleteDC(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef HFONT RawRef; - static HFONT Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - ::DeleteObject(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef HBRUSH RawRef; - static HBRUSH Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - ::DeleteObject(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef HRGN RawRef; - static HRGN Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - ::DeleteObject(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef HBITMAP RawRef; - static HBITMAP Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - ::DeleteObject(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef SC_HANDLE RawRef; - static SC_HANDLE Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - CloseServiceHandle(aFD); - } - } -}; - -template <> -class nsSimpleRef { - protected: - typedef HANDLE RawRef; - - nsSimpleRef() : mRawRef(nullptr) {} - - explicit nsSimpleRef(RawRef aRawRef) : mRawRef(aRawRef) {} - - bool HaveResource() const { - return mRawRef && mRawRef != INVALID_HANDLE_VALUE; - } - - public: - RawRef get() const { return mRawRef; } - - static void Release(RawRef aRawRef) { - if (aRawRef && aRawRef != INVALID_HANDLE_VALUE) { - CloseHandle(aRawRef); - } - } - RawRef mRawRef; -}; - -template <> -class nsAutoRefTraits { - public: - typedef HMODULE RawRef; - static RawRef Void() { return nullptr; } - - static void Release(RawRef aFD) { - if (aFD != Void()) { - FreeLibrary(aFD); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef DEVMODEW* RawRef; - static RawRef Void() { return nullptr; } - - static void Release(RawRef aDevMode) { - if (aDevMode != Void()) { - ::HeapFree(::GetProcessHeap(), 0, aDevMode); - } - } -}; - -template <> -class nsAutoRefTraits { - public: - typedef MSIHANDLE RawRef; - static RawRef Void() { return 0; } - - static void Release(RawRef aHandle) { - if (aHandle != Void()) { - ::MsiCloseHandle(aHandle); - } - } -}; - -// HGLOBAL is just a typedef of HANDLE which nsSimpleRef has a specialization -// of, that means having a nsAutoRefTraits specialization for HGLOBAL is -// useless. Therefore we create a wrapper class for HGLOBAL to make -// nsAutoRefTraits and nsAutoRef work as intention. -class nsHGLOBAL { - public: - MOZ_IMPLICIT nsHGLOBAL(HGLOBAL hGlobal) : m_hGlobal(hGlobal) {} - - operator HGLOBAL() const { return m_hGlobal; } - - private: - HGLOBAL m_hGlobal; -}; - -template <> -class nsAutoRefTraits { - public: - typedef nsHGLOBAL RawRef; - static RawRef Void() { return nullptr; } - - static void Release(RawRef hGlobal) { ::GlobalFree(hGlobal); } -}; - -// Because Printer's HANDLE uses ClosePrinter and we already have -// nsAutoRef which uses CloseHandle so we need to create a wrapper class -// for HANDLE to have another specialization for nsAutoRefTraits. -class nsHPRINTER { - public: - MOZ_IMPLICIT nsHPRINTER(HANDLE hPrinter) : m_hPrinter(hPrinter) {} - - operator HANDLE() const { return m_hPrinter; } - - HANDLE* operator&() { return &m_hPrinter; } - - private: - HANDLE m_hPrinter; -}; - -// winspool.h header has AddMonitor macro, it conflicts with AddMonitor member -// function in TaskbarPreview.cpp and TaskbarTabPreview.cpp. Beside, we only -// need ClosePrinter here for Release function, so having its prototype is -// enough. -extern "C" BOOL WINAPI ClosePrinter(HANDLE hPrinter); - -template <> -class nsAutoRefTraits { - public: - typedef nsHPRINTER RawRef; - static RawRef Void() { return nullptr; } - - static void Release(RawRef hPrinter) { ::ClosePrinter(hPrinter); } -}; - -typedef nsAutoRef nsAutoRegKey; -typedef nsAutoRef nsAutoHDC; -typedef nsAutoRef nsAutoFont; -typedef nsAutoRef nsAutoBrush; -typedef nsAutoRef nsAutoRegion; -typedef nsAutoRef nsAutoBitmap; -typedef nsAutoRef nsAutoServiceHandle; -typedef nsAutoRef nsAutoHandle; -typedef nsAutoRef nsModuleHandle; -typedef nsAutoRef nsAutoDevMode; -typedef nsAutoRef nsAutoGlobalMem; -typedef nsAutoRef nsAutoPrinter; -typedef nsAutoRef nsAutoMsiHandle; - -// Construct a path "\". return false if the output buffer -// is too small. -// Note: If the system path cannot be found, or doesn't fit in the output buffer -// with the module name, we will just ignore the system path and output the -// module name alone; -// this may mean using a normal search path wherever the output is used. -bool inline ConstructSystem32Path(LPCWSTR aModule, WCHAR* aSystemPath, - UINT aSize) { - MOZ_ASSERT(aSystemPath); - - size_t fileLen = wcslen(aModule); - if (fileLen >= aSize) { - // The module name alone cannot even fit! - return false; - } - - size_t systemDirLen = GetSystemDirectoryW(aSystemPath, aSize); - - if (systemDirLen) { - if (systemDirLen < aSize - fileLen) { - // Make the system directory path terminate with a slash. - if (aSystemPath[systemDirLen - 1] != L'\\') { - if (systemDirLen + 1 < aSize - fileLen) { - aSystemPath[systemDirLen] = L'\\'; - ++systemDirLen; - // No need to re-nullptr terminate. - } else { - // Couldn't fit the system path with added slash. - systemDirLen = 0; - } - } - } else { - // Couldn't fit the system path. - systemDirLen = 0; - } - } - - MOZ_ASSERT(systemDirLen + fileLen < aSize); - - wcsncpy(aSystemPath + systemDirLen, aModule, fileLen); - aSystemPath[systemDirLen + fileLen] = L'\0'; - return true; -} - -HMODULE inline LoadLibrarySystem32(LPCWSTR aModule) { - return LoadLibraryExW(aModule, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); -} - -// for UniquePtr -struct LocalFreeDeleter { - void operator()(void* aPtr) { ::LocalFree(aPtr); } -}; - -struct VirtualFreeDeleter { - void operator()(void* aPtr) { ::VirtualFree(aPtr, 0, MEM_RELEASE); } -}; - -// for UniquePtr to store a PSID -struct FreeSidDeleter { - void operator()(void* aPtr) { ::FreeSid(aPtr); } -}; -// Unfortunately, although SID is a struct, PSID is a void* -// This typedef will work for storing a PSID in a UniquePtr and should make -// things a bit more readable. -typedef mozilla::UniquePtr UniqueSidPtr; - -struct CloseHandleDeleter { - typedef HANDLE pointer; - void operator()(pointer aHandle) { - if (aHandle != INVALID_HANDLE_VALUE) { - ::CloseHandle(aHandle); - } - } -}; - -// One caller of this function is early in startup and several others are not, -// so they have different ways of determining the two parameters. This function -// exists just so any future code that needs to determine whether the dynamic -// blocklist is disabled remembers to check whether safe mode is active. -inline bool IsDynamicBlocklistDisabled(bool isSafeMode, - bool hasCommandLineDisableArgument) { - return isSafeMode || hasCommandLineDisableArgument; -} -#endif -- cgit