Merge mozilla-central to autoland. r=merge

This commit is contained in:
Dorel Luca 2018-02-07 17:07:56 +02:00
Родитель 54c4111311 a539f8f7fe
Коммит 6b75e4235c
26 изменённых файлов: 175 добавлений и 741 удалений

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/mscom/StructStream.h" #include "mozilla/mscom/StructStream.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "HandlerData.h"
struct NEWEST_IA2_INTERFACE; struct NEWEST_IA2_INTERFACE;

Просмотреть файл

@ -28,7 +28,6 @@
#ifdef MOZ_SANDBOX #ifdef MOZ_SANDBOX
#include "mozilla/sandboxing/SandboxInitialization.h" #include "mozilla/sandboxing/SandboxInitialization.h"
#endif #endif
#include "mozilla/WindowsDllBlocklist.h"
#endif #endif
#include "BinaryPath.h" #include "BinaryPath.h"
@ -36,6 +35,7 @@
#include "mozilla/Sprintf.h" #include "mozilla/Sprintf.h"
#include "mozilla/StartupTimeline.h" #include "mozilla/StartupTimeline.h"
#include "mozilla/WindowsDllBlocklist.h"
#ifdef LIBFUZZER #ifdef LIBFUZZER
#include "FuzzerDefs.h" #include "FuzzerDefs.h"

Просмотреть файл

@ -402,7 +402,6 @@
} }
.ruleview-newproperty { .ruleview-newproperty {
/* (enable checkbox width: 12px) + (expander width: 15px) */
margin-inline-start: -10px; margin-inline-start: -10px;
} }

Просмотреть файл

@ -2385,6 +2385,17 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
} }
} }
#if defined(XP_WIN)
// Send the info needed to join the browser process's audio session.
nsID id;
nsString sessionName;
nsString iconPath;
if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
iconPath))) {
Unused << SendSetAudioSessionData(id, sessionName, iconPath);
}
#endif
#ifdef MOZ_CONTENT_SANDBOX #ifdef MOZ_CONTENT_SANDBOX
bool shouldSandbox = true; bool shouldSandbox = true;
MaybeFileDesc brokerFd = void_t(); MaybeFileDesc brokerFd = void_t();
@ -2416,16 +2427,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
KillHard("SandboxInitFailed"); KillHard("SandboxInitFailed");
} }
#endif #endif
#if defined(XP_WIN)
// Send the info needed to join the browser process's audio session.
nsID id;
nsString sessionName;
nsString iconPath;
if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
iconPath))) {
Unused << SendSetAudioSessionData(id, sessionName, iconPath);
}
#endif
{ {
RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get(); RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();

Просмотреть файл

@ -7,10 +7,7 @@
#include "../contentproc/plugin-container.cpp" #include "../contentproc/plugin-container.cpp"
#include "mozilla/Bootstrap.h" #include "mozilla/Bootstrap.h"
#if defined(XP_WIN)
#include "mozilla/WindowsDllBlocklist.h" #include "mozilla/WindowsDllBlocklist.h"
#endif // defined(XP_WIN)
using namespace mozilla; using namespace mozilla;

Просмотреть файл

@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include "mozilla/WindowsDllBlocklist.h"
#include "mozilla/Bootstrap.h" #include "mozilla/Bootstrap.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@ -25,7 +26,6 @@
#ifdef MOZ_SANDBOX #ifdef MOZ_SANDBOX
#include "mozilla/sandboxing/SandboxInitialization.h" #include "mozilla/sandboxing/SandboxInitialization.h"
#endif #endif
#include "mozilla/WindowsDllBlocklist.h"
#endif #endif
#ifdef MOZ_WIDGET_GTK #ifdef MOZ_WIDGET_GTK

Просмотреть файл

@ -1,210 +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/. */
#ifdef MOZ_MEMORY
#define MOZ_MEMORY_IMPL
#include "mozmemory_wrap.h"
#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
// See mozmemory_wrap.h for more details. This file is part of libmozglue, so
// it needs to use _impl suffixes.
#define MALLOC_DECL(name, return_type, ...) \
extern "C" MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__);
#include "malloc_decls.h"
#endif
#include "Authenticode.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/UniquePtr.h"
#include <windows.h>
#include <softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
namespace {
struct CertStoreDeleter
{
typedef HCERTSTORE pointer;
void operator()(pointer aStore)
{
::CertCloseStore(aStore, 0);
}
};
struct CryptMsgDeleter
{
typedef HCRYPTMSG pointer;
void operator()(pointer aMsg)
{
::CryptMsgClose(aMsg);
}
};
struct CertContextDeleter
{
void operator()(PCCERT_CONTEXT aCertContext)
{
::CertFreeCertificateContext(aCertContext);
}
};
typedef mozilla::UniquePtr<HCERTSTORE, CertStoreDeleter> CertStoreUniquePtr;
typedef mozilla::UniquePtr<HCRYPTMSG, CryptMsgDeleter> CryptMsgUniquePtr;
typedef mozilla::UniquePtr<const CERT_CONTEXT, CertContextDeleter> CertContextUniquePtr;
static const DWORD kEncodingTypes = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
class SignedBinary
{
public:
explicit SignedBinary(const wchar_t* aFilePath);
explicit operator bool() const
{
return mCertStore && mCryptMsg && mCertCtx;
}
mozilla::UniquePtr<wchar_t[]> GetOrgName();
SignedBinary(const SignedBinary&) = delete;
SignedBinary(SignedBinary&&) = delete;
SignedBinary& operator=(const SignedBinary&) = delete;
SignedBinary& operator=(SignedBinary&&) = delete;
private:
bool VerifySignature(const wchar_t* aFilePath);
private:
CertStoreUniquePtr mCertStore;
CryptMsgUniquePtr mCryptMsg;
CertContextUniquePtr mCertCtx;
};
SignedBinary::SignedBinary(const wchar_t* aFilePath)
{
if (!VerifySignature(aFilePath)) {
return;
}
DWORD encodingType, contentType, formatType;
HCERTSTORE rawCertStore;
HCRYPTMSG rawCryptMsg;
BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, aFilePath,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY, 0,
&encodingType, &contentType, &formatType,
&rawCertStore, &rawCryptMsg, nullptr);
if (!result) {
return;
}
mCertStore.reset(rawCertStore);
mCryptMsg.reset(rawCryptMsg);
DWORD certInfoLen = 0;
BOOL ok = CryptMsgGetParam(mCryptMsg.get(), CMSG_SIGNER_CERT_INFO_PARAM, 0,
nullptr, &certInfoLen);
if (!ok) {
return;
}
auto certInfoBuf = mozilla::MakeUnique<char[]>(certInfoLen);
ok = CryptMsgGetParam(mCryptMsg.get(), CMSG_SIGNER_CERT_INFO_PARAM, 0,
certInfoBuf.get(), &certInfoLen);
if (!ok) {
return;
}
auto certInfo = reinterpret_cast<CERT_INFO*>(certInfoBuf.get());
PCCERT_CONTEXT certCtx = CertFindCertificateInStore(mCertStore.get(),
kEncodingTypes, 0,
CERT_FIND_SUBJECT_CERT,
certInfo, nullptr);
if (!certCtx) {
return;
}
mCertCtx.reset(certCtx);
}
bool
SignedBinary::VerifySignature(const wchar_t* aFilePath)
{
WINTRUST_FILE_INFO fileInfo = {sizeof(fileInfo)};
fileInfo.pcwszFilePath = aFilePath;
WINTRUST_DATA trustData = {sizeof(trustData)};
trustData.dwUIChoice = WTD_UI_NONE;
trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
trustData.dwUnionChoice = WTD_CHOICE_FILE;
trustData.pFile = &fileInfo;
trustData.dwStateAction = WTD_STATEACTION_VERIFY;
const HWND hwnd = (HWND) INVALID_HANDLE_VALUE;
GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
LONG result = WinVerifyTrust(hwnd, &policyGUID, &trustData);
trustData.dwStateAction = WTD_STATEACTION_CLOSE;
WinVerifyTrust(hwnd, &policyGUID, &trustData);
return result == ERROR_SUCCESS;
}
mozilla::UniquePtr<wchar_t[]>
SignedBinary::GetOrgName()
{
DWORD charCount = CertGetNameStringW(mCertCtx.get(),
CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
nullptr, nullptr, 0);
if (charCount <= 1) {
// Not found
return nullptr;
}
auto result = mozilla::MakeUnique<wchar_t[]>(charCount);
charCount = CertGetNameStringW(mCertCtx.get(), CERT_NAME_SIMPLE_DISPLAY_TYPE,
0, nullptr, result.get(), charCount);
MOZ_ASSERT(charCount > 1);
return result;
}
} // anonymous namespace
namespace mozilla {
class AuthenticodeImpl : public Authenticode
{
public:
virtual UniquePtr<wchar_t[]> GetBinaryOrgName(const wchar_t* aFilePath) override;
};
UniquePtr<wchar_t[]>
AuthenticodeImpl::GetBinaryOrgName(const wchar_t* aFilePath)
{
SignedBinary bin(aFilePath);
if (!bin) {
return nullptr;
}
return bin.GetOrgName();
}
static AuthenticodeImpl sAuthenticodeImpl;
Authenticode*
GetAuthenticode()
{
return &sAuthenticodeImpl;
}
} // namespace mozilla

Просмотреть файл

@ -1,24 +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 mozilla_Authenticode_h
#define mozilla_Authenticode_h
#include "mozilla/Maybe.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
class Authenticode
{
public:
virtual UniquePtr<wchar_t[]> GetBinaryOrgName(const wchar_t* aFilePath) = 0;
};
} // namespace mozilla
#endif // mozilla_Authenticode_h

Просмотреть файл

@ -23,8 +23,8 @@
#include <map> #include <map>
#pragma warning( pop ) #pragma warning( pop )
#include "Authenticode.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsWindowsDllInterceptor.h" #include "nsWindowsDllInterceptor.h"
#include "mozilla/Sprintf.h" #include "mozilla/Sprintf.h"
#include "mozilla/StackWalk_windows.h" #include "mozilla/StackWalk_windows.h"
@ -33,7 +33,7 @@
#include "nsWindowsHelpers.h" #include "nsWindowsHelpers.h"
#include "WindowsDllBlocklist.h" #include "WindowsDllBlocklist.h"
#include "mozilla/AutoProfilerLabel.h" #include "mozilla/AutoProfilerLabel.h"
#include "mozilla/glue/WindowsDllServices.h" #include "mozilla/WindowsDllServices.h"
using namespace mozilla; using namespace mozilla;
@ -938,7 +938,7 @@ DllBlocklist_CheckStatus()
static SRWLOCK gDllServicesLock = SRWLOCK_INIT; static SRWLOCK gDllServicesLock = SRWLOCK_INIT;
static mozilla::glue::detail::DllServicesBase* gDllServices; static mozilla::detail::DllServicesBase* gDllServices;
class MOZ_RAII AutoSharedLock final class MOZ_RAII AutoSharedLock final
{ {
@ -1047,30 +1047,22 @@ DllLoadNotification(ULONG aReason, PCLDR_DLL_NOTIFICATION_DATA aNotificationData
gDllServices->DispatchDllLoadNotification(fullDllName); gDllServices->DispatchDllLoadNotification(fullDllName);
} }
namespace mozilla {
Authenticode* GetAuthenticode();
} // namespace mozilla
MFBT_API void MFBT_API void
DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc) DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc)
{ {
AutoExclusiveLock lock(gDllServicesLock); AutoExclusiveLock lock(gDllServicesLock);
if (aSvc) { if (aSvc && !gNotificationCookie) {
aSvc->SetAuthenticodeImpl(GetAuthenticode()); auto pLdrRegisterDllNotification =
reinterpret_cast<decltype(&::LdrRegisterDllNotification)>(
::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"),
"LdrRegisterDllNotification"));
if (!gNotificationCookie) { MOZ_DIAGNOSTIC_ASSERT(pLdrRegisterDllNotification);
auto pLdrRegisterDllNotification =
reinterpret_cast<decltype(&::LdrRegisterDllNotification)>(
::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"),
"LdrRegisterDllNotification"));
MOZ_DIAGNOSTIC_ASSERT(pLdrRegisterDllNotification); NTSTATUS ntStatus = pLdrRegisterDllNotification(0, &DllLoadNotification,
nullptr, &gNotificationCookie);
NTSTATUS ntStatus = pLdrRegisterDllNotification(0, &DllLoadNotification, MOZ_DIAGNOSTIC_ASSERT(NT_SUCCESS(ntStatus));
nullptr, &gNotificationCookie);
MOZ_DIAGNOSTIC_ASSERT(NT_SUCCESS(ntStatus));
}
} }
gDllServices = aSvc; gDllServices = aSvc;

Просмотреть файл

@ -26,14 +26,12 @@ MFBT_API bool DllBlocklist_CheckStatus();
// Forward declaration // Forward declaration
namespace mozilla { namespace mozilla {
namespace glue {
namespace detail { namespace detail {
class DllServicesBase; class DllServicesBase;
} // namespace detail } // namespace detail
} // namespace glue
} // namespace mozilla } // namespace mozilla
MFBT_API void DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc); MFBT_API void DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc);
#endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#endif // mozilla_windowsdllblocklist_h #endif // mozilla_windowsdllblocklist_h

Просмотреть файл

@ -4,10 +4,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_glue_WindowsDllServices_h #ifndef mozilla_WindowsDllServices_h
#define mozilla_glue_WindowsDllServices_h #define mozilla_WindowsDllServices_h
#include "mozilla/Authenticode.h"
#include "mozilla/WindowsDllBlocklist.h" #include "mozilla/WindowsDllBlocklist.h"
#if defined(MOZILLA_INTERNAL_API) #if defined(MOZILLA_INTERNAL_API)
@ -23,10 +22,9 @@
#include <winternl.h> #include <winternl.h>
namespace mozilla { namespace mozilla {
namespace glue {
namespace detail { namespace detail {
class DllServicesBase : public Authenticode class DllServicesBase
{ {
public: public:
/** /**
@ -37,20 +35,6 @@ public:
*/ */
virtual void DispatchDllLoadNotification(PCUNICODE_STRING aDllName) = 0; virtual void DispatchDllLoadNotification(PCUNICODE_STRING aDllName) = 0;
void SetAuthenticodeImpl(Authenticode* aAuthenticode)
{
mAuthenticode = aAuthenticode;
}
virtual UniquePtr<wchar_t[]> GetBinaryOrgName(const wchar_t* aFilePath) override final
{
if (!mAuthenticode) {
return nullptr;
}
return mAuthenticode->GetBinaryOrgName(aFilePath);
}
void Disable() void Disable()
{ {
DllBlocklist_SetDllServices(nullptr); DllBlocklist_SetDllServices(nullptr);
@ -62,20 +46,13 @@ public:
DllServicesBase& operator=(DllServicesBase&&) = delete; DllServicesBase& operator=(DllServicesBase&&) = delete;
protected: protected:
DllServicesBase() DllServicesBase() = default;
: mAuthenticode(nullptr)
{
}
virtual ~DllServicesBase() = default; virtual ~DllServicesBase() = default;
void Enable() void Enable()
{ {
DllBlocklist_SetDllServices(this); DllBlocklist_SetDllServices(this);
} }
private:
Authenticode* mAuthenticode;
}; };
} // namespace detail } // namespace detail
@ -109,7 +86,6 @@ protected:
#endif // defined(MOZILLA_INTERNAL_API) #endif // defined(MOZILLA_INTERNAL_API)
} // namespace glue
} // namespace mozilla } // namespace mozilla
#endif // mozilla_glue_WindowsDllServices_h #endif // mozilla_WindowsDllServices_h

Просмотреть файл

@ -56,22 +56,12 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
if CONFIG['CC_TYPE'] == "msvc": if CONFIG['CC_TYPE'] == "msvc":
SOURCES += ['WindowsCFGStatus.cpp'] SOURCES += ['WindowsCFGStatus.cpp']
SOURCES += [ SOURCES += [
'Authenticode.cpp',
'WindowsDllBlocklist.cpp', 'WindowsDllBlocklist.cpp',
] ]
DisableStlWrapping() DisableStlWrapping()
OS_LIBS += [ OS_LIBS += [
'crypt32',
'version', 'version',
'wintrust',
]
EXPORTS.mozilla += [
'Authenticode.h',
'WindowsDllBlocklist.h',
]
EXPORTS.mozilla.glue += [
'WindowsDllServices.h',
] ]
EXPORTS.mozilla += [ EXPORTS.mozilla += [
@ -79,6 +69,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
'mips.h', 'mips.h',
'SSE.h', 'SSE.h',
'WindowsCFGStatus.h', 'WindowsCFGStatus.h',
'WindowsDllBlocklist.h',
'WindowsDllServices.h',
] ]
if CONFIG['CPU_ARCH'].startswith('x86'): if CONFIG['CPU_ARCH'].startswith('x86'):

Просмотреть файл

@ -8,9 +8,12 @@ Unreleased
### Added ### Added
- New `--jsdebugger` flag to open the Browser Toolbox when Firefox
launches. This is useful for debugging Marionette internals.
- Introduced the temporary, boolean capability - Introduced the temporary, boolean capability
`moz:useNonSpecCompliantPointerOrigin` to `moz:useNonSpecCompliantPointerOrigin` to disable the WebDriver
disable the WebDriver conforming behavior of calculating the Pointer Origin. conforming behavior of calculating the Pointer Origin.
### Changed ### Changed

Просмотреть файл

@ -570,6 +570,13 @@ A helpful trick is that it is possible to bind to 0 to get the system
to atomically assign a free port. to atomically assign a free port.
#### <code>--jsdebugger</code>
Attach [browser toolbox] debugger when Firefox starts. This is
useful for debugging [Marionette] internals.
[browser toolbox]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox
#### <code>-v<var>[v]</var></code> #### <code>-v<var>[v]</var></code>
Increases the logging verbosity by to debug level when passing a single Increases the logging verbosity by to debug level when passing a single

Просмотреть файл

@ -123,6 +123,10 @@ fn app<'a, 'b>() -> App<'a, 'b> {
.long("connect-existing") .long("connect-existing")
.requires("marionette_port") .requires("marionette_port")
.help("Connect to an existing Firefox instance")) .help("Connect to an existing Firefox instance"))
.arg(Arg::with_name("jsdebugger")
.long("jsdebugger")
.takes_value(false)
.help("Attach browser toolbox debugger for Firefox"))
.arg(Arg::with_name("verbosity") .arg(Arg::with_name("verbosity")
.short("v") .short("v")
.multiple(true) .multiple(true)
@ -190,9 +194,10 @@ fn run() -> ProgramResult {
let settings = MarionetteSettings { let settings = MarionetteSettings {
port: marionette_port, port: marionette_port,
binary: binary, binary,
log_level,
connect_existing: matches.is_present("connect_existing"), connect_existing: matches.is_present("connect_existing"),
log_level: log_level, jsdebugger: matches.is_present("jsdebugger"),
}; };
let handler = MarionetteHandler::new(settings); let handler = MarionetteHandler::new(settings);
let listening = webdriver::server::start(addr, handler, &extension_routes()[..]) let listening = webdriver::server::start(addr, handler, &extension_routes()[..])

Просмотреть файл

@ -382,6 +382,10 @@ pub struct MarionetteSettings {
pub binary: Option<PathBuf>, pub binary: Option<PathBuf>,
pub connect_existing: bool, pub connect_existing: bool,
/// Brings up the Browser Toolbox when starting Firefox,
/// letting you debug internals.
pub jsdebugger: bool,
/// Optionally increase Marionette's verbosity by providing a log /// Optionally increase Marionette's verbosity by providing a log
/// level. The Gecko default is LogLevel::Info for optimised /// level. The Gecko default is LogLevel::Info for optimised
/// builds and LogLevel::Debug for debug builds. /// builds and LogLevel::Debug for debug builds.
@ -462,17 +466,20 @@ impl MarionetteHandler {
let mut runner = FirefoxRunner::new(&binary, profile); let mut runner = FirefoxRunner::new(&binary, profile);
// https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting
runner runner
// double-dashed flags are not accepted on Windows systems
.arg("-marionette")
// https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting
.env("MOZ_CRASHREPORTER", "1") .env("MOZ_CRASHREPORTER", "1")
.env("MOZ_CRASHREPORTER_NO_REPORT", "1") .env("MOZ_CRASHREPORTER_NO_REPORT", "1")
.env("MOZ_CRASHREPORTER_SHUTDOWN", "1"); .env("MOZ_CRASHREPORTER_SHUTDOWN", "1");
// double-dashed flags are not accepted on Windows systems
runner.arg("-marionette");
if self.settings.jsdebugger {
runner.arg("-jsdebugger");
}
if let Some(args) = options.args.as_ref() { if let Some(args) = options.args.as_ref() {
runner.args(args); runner.args(args);
}; }
let browser_proc = runner.start() let browser_proc = runner.start()
.map_err(|e| { .map_err(|e| {
@ -500,6 +507,14 @@ impl MarionetteHandler {
prefs.insert_slice(&extra_prefs[..]); prefs.insert_slice(&extra_prefs[..]);
if self.settings.jsdebugger {
prefs.insert("devtools.browsertoolbox.panel", Pref::new("jsdebugger".to_owned()));
prefs.insert("devtools.debugger.remote-enabled", Pref::new(true));
prefs.insert("devtools.chrome.enabled", Pref::new(true));
prefs.insert("devtools.debugger.prompt-connection", Pref::new(false));
prefs.insert("marionette.debugging.clicktostart", Pref::new(true));
}
if let Some(ref level) = self.current_log_level { if let Some(ref level) = self.current_log_level {
prefs.insert("marionette.log.level", Pref::new(level.to_string())); prefs.insert("marionette.log.level", Pref::new(level.to_string()));
}; };

Просмотреть файл

@ -1,240 +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 https://mozilla.org/MPL/2.0/. */
#include "CertAnnotator.h"
#include "mozilla/JSONWriter.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Services.h"
#include "mozilla/WinDllServices.h"
#include "nsExceptionHandler.h"
#include "nsIFile.h"
#include "nsIObserverService.h"
#include "nsReadableUtils.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXPCOM.h"
#include "nsXULAppAPI.h"
#include "nsWindowsHelpers.h"
#include <tlhelp32.h>
namespace mozilla {
NS_IMPL_ISUPPORTS(CertAnnotator, nsIObserver)
CertAnnotator::~CertAnnotator()
{
if (mAnnotatorThread) {
mAnnotatorThread->Shutdown();
}
}
bool
CertAnnotator::Init()
{
if (mAnnotatorThread) {
return true;
}
nsCOMPtr<nsIRunnable> initialEvent =
NewRunnableMethod("mozilla::CertAnnotator::RecordInitialCertInfo", this,
&CertAnnotator::RecordInitialCertInfo);
nsresult rv = NS_NewNamedThread("Cert Annotator",
getter_AddRefs(mAnnotatorThread),
initialEvent);
return NS_SUCCEEDED(rv);
}
NS_IMETHODIMP
CertAnnotator::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(!strcmp(aTopic, DllServices::kTopicDllLoadedMainThread) ||
!strcmp(aTopic, DllServices::kTopicDllLoadedNonMainThread));
MOZ_ASSERT(mAnnotatorThread);
if (!mAnnotatorThread) {
return NS_OK;
}
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod<nsString, bool>("mozilla::CertAnnotator::RecordCertInfo",
this, &CertAnnotator::RecordCertInfo,
aData, true);
mAnnotatorThread->Dispatch(event, NS_DISPATCH_NORMAL);
return NS_OK;
}
void
CertAnnotator::RecordInitialCertInfo()
{
MOZ_ASSERT(!NS_IsMainThread());
nsAutoHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0));
MOZ_ASSERT(snapshot != INVALID_HANDLE_VALUE);
if (snapshot == INVALID_HANDLE_VALUE) {
return;
}
MODULEENTRY32W moduleEntry = { sizeof(moduleEntry) };
if (!::Module32FirstW(snapshot, &moduleEntry)) {
return;
}
do {
RecordCertInfo(nsDependentString(moduleEntry.szExePath), false);
} while(::Module32NextW(snapshot, &moduleEntry));
Serialize();
}
void
CertAnnotator::RecordCertInfo(const nsAString& aLibPath, const bool aDoSerialize)
{
MOZ_ASSERT(!NS_IsMainThread());
// (1) Get Lowercase Module Name
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aLibPath, false, getter_AddRefs(file));
if (NS_FAILED(rv)) {
return;
}
nsAutoString key;
rv = file->GetLeafName(key);
if (NS_FAILED(rv)) {
return;
}
ToLowerCase(key);
// (2) Get cert subject info
auto flatLibPath = PromiseFlatString(aLibPath);
RefPtr<mozilla::DllServices> dllSvc(mozilla::DllServices::Get());
auto orgName = dllSvc->GetBinaryOrgName(flatLibPath.get());
if (!orgName) {
return;
}
// (3) Insert into hash table
auto& modulesForThisSubject = mCertTable.GetOrInsert(nsString(orgName.get()));
if (modulesForThisSubject.ContainsSorted(key)) {
return;
}
modulesForThisSubject.InsertElementSorted(Move(key));
if (!aDoSerialize) {
return;
}
// (4) Serialize and annotate
Serialize();
}
} // namespace mozilla
namespace {
class Writer final : public mozilla::JSONWriteFunc
{
public:
virtual void Write(const char* aStr) override
{
mStr += aStr;
}
const nsCString& Get() const
{
return mStr;
}
private:
nsCString mStr;
};
} // anonymous namespace
namespace mozilla {
void
CertAnnotator::Serialize()
{
MOZ_ASSERT(!NS_IsMainThread());
JSONWriter json(MakeUnique<Writer>());
#if defined(DEBUG)
const JSONWriter::CollectionStyle style = JSONWriter::MultiLineStyle;
#else
const JSONWriter::CollectionStyle style = JSONWriter::SingleLineStyle;
#endif
json.Start(style);
for (auto subjectItr = mCertTable.Iter(); !subjectItr.Done(); subjectItr.Next()) {
json.StartArrayProperty(NS_ConvertUTF16toUTF8(subjectItr.Key()).get());
auto& modules = subjectItr.Data();
for (auto&& module : modules) {
json.StringElement(NS_ConvertUTF16toUTF8(module).get());
}
json.EndArray();
}
json.End();
const nsCString& serialized = static_cast<Writer*>(json.WriteFunc())->Get();
if (XRE_IsParentProcess()) {
// Safe to do off main thread in the parent process
Annotate(serialized);
return;
}
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod<nsCString>("mozilla::CertAnnotator::Annotate", this,
&CertAnnotator::Annotate, serialized);
NS_DispatchToMainThread(event);
}
void
CertAnnotator::Annotate(const nsCString& aAnnotation)
{
nsAutoCString annotationKey;
annotationKey.AppendLiteral("ModuleSignatureInfo");
if (XRE_IsParentProcess()) {
annotationKey.AppendLiteral("Parent");
} else {
MOZ_ASSERT(NS_IsMainThread());
annotationKey.AppendLiteral("Child");
}
CrashReporter::AnnotateCrashReport(annotationKey, aAnnotation);
}
void
CertAnnotator::Register()
{
RefPtr<CertAnnotator> annotator(new CertAnnotator());
if (!annotator->Init()) {
return;
}
nsCOMPtr<nsIObserverService> obsServ(services::GetObserverService());
obsServ->AddObserver(annotator, DllServices::kTopicDllLoadedMainThread,
false);
obsServ->AddObserver(annotator, DllServices::kTopicDllLoadedNonMainThread,
false);
}
} // namespace mozilla

Просмотреть файл

@ -1,47 +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 https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_CertAnnotator_h
#define mozilla_CertAnnotator_h
#include "mozilla/Move.h"
#include "mozilla/Mutex.h"
#include "nsDataHashtable.h"
#include "nsIObserver.h"
#include "nsIThread.h"
#include "nsString.h"
#include "nsTArray.h"
namespace mozilla {
class CertAnnotator final : public nsIObserver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
static void Register();
private:
CertAnnotator() = default;
virtual ~CertAnnotator();
bool Init();
void RecordInitialCertInfo();
void RecordCertInfo(const nsAString& aLibPath, const bool aDoSerialize);
void Serialize();
void Annotate(const nsCString& aAnnotation);
nsDataHashtable<nsStringHashKey, nsTArray<nsString>> mCertTable;
nsCOMPtr<nsIThread> mAnnotatorThread;
};
} // namespace mozilla
#endif // mozilla_CertAnnotator_h

Просмотреть файл

@ -35,13 +35,6 @@ if CONFIG['MOZ_CRASHREPORTER']:
if CONFIG['MOZ_CRASHREPORTER_INJECTOR']: if CONFIG['MOZ_CRASHREPORTER_INJECTOR']:
DIRS += ['breakpad-windows-standalone'] DIRS += ['breakpad-windows-standalone']
UNIFIED_SOURCES += [
'CertAnnotator.cpp',
]
EXPORTS.mozilla += [
'CertAnnotator.h',
]
elif CONFIG['OS_ARCH'] == 'Darwin': elif CONFIG['OS_ARCH'] == 'Darwin':
DIRS += [ DIRS += [
'breakpad-client', 'breakpad-client',

Просмотреть файл

@ -42,7 +42,6 @@
#include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceUtils.h"
#include "nsWindowsDllInterceptor.h" #include "nsWindowsDllInterceptor.h"
#include "mozilla/WindowsDllBlocklist.h"
#include "mozilla/WindowsVersion.h" #include "mozilla/WindowsVersion.h"
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
#include "breakpad-client/mac/crash_generation/client_info.h" #include "breakpad-client/mac/crash_generation/client_info.h"
@ -92,6 +91,7 @@ using mozilla::InjectCrashRunnable;
#include "mozilla/IOInterposer.h" #include "mozilla/IOInterposer.h"
#include "mozilla/mozalloc_oom.h" #include "mozilla/mozalloc_oom.h"
#include "mozilla/WindowsDllBlocklist.h"
#if defined(XP_MACOSX) #if defined(XP_MACOSX)
CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter"); CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter");

Просмотреть файл

@ -1,54 +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 https://mozilla.org/MPL/2.0/. */
#include "mozilla/WinDllServices.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "nsString.h"
namespace mozilla {
const char* DllServices::kTopicDllLoadedMainThread = "dll-loaded-main-thread";
const char* DllServices::kTopicDllLoadedNonMainThread = "dll-loaded-non-main-thread";
static StaticRefPtr<DllServices> sInstance;
DllServices*
DllServices::Get()
{
if (sInstance) {
return sInstance;
}
sInstance = new DllServices();
ClearOnShutdown(&sInstance);
return sInstance;
}
DllServices::DllServices()
{
Enable();
}
void
DllServices::NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName)
{
const char* topic;
if (aIsMainThread) {
topic = kTopicDllLoadedMainThread;
} else {
topic = kTopicDllLoadedNonMainThread;
}
nsCOMPtr<nsIObserverService> obsServ(mozilla::services::GetObserverService());
obsServ->NotifyObservers(nullptr, topic, aDllName.get());
}
} // namespace mozilla

Просмотреть файл

@ -1,31 +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 https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_WinDllServices_h
#define mozilla_WinDllServices_h
#include "mozilla/glue/WindowsDllServices.h"
namespace mozilla {
class DllServices : public mozilla::glue::DllServices
{
public:
static DllServices* Get();
static const char* kTopicDllLoadedMainThread;
static const char* kTopicDllLoadedNonMainThread;
private:
DllServices();
~DllServices() = default;
void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override;
};
} // namespace mozilla
#endif // mozilla_WinDllServices_h

Просмотреть файл

@ -36,15 +36,11 @@ if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
EXPORTS += ['EventTracer.h'] EXPORTS += ['EventTracer.h']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS.mozilla += [
'WinDllServices.h',
]
SOURCES += [ SOURCES += [
'../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp', '../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp',
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nsNativeAppSupportWin.cpp', 'nsNativeAppSupportWin.cpp',
'WinDllServices.cpp',
] ]
DEFINES['PROXY_PRINTING'] = 1 DEFINES['PROXY_PRINTING'] = 1
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [

Просмотреть файл

@ -160,8 +160,7 @@
#ifdef XP_WIN #ifdef XP_WIN
#include <process.h> #include <process.h>
#include <shlobj.h> #include <shlobj.h>
#include "mozilla/CertAnnotator.h" #include "mozilla/WindowsDllServices.h"
#include "mozilla/WinDllServices.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include <comdef.h> #include <comdef.h>
#include <wbemidl.h> #include <wbemidl.h>
@ -1666,6 +1665,40 @@ ScopedXPCOMStartup::CreateAppSupport(nsISupports* aOuter, REFNSIID aIID, void**
nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport; nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport;
#if defined(XP_WIN)
class DllNotifications : public mozilla::DllServices
{
public:
DllNotifications()
{
Enable();
}
private:
~DllNotifications() = default;
void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override;
};
void
DllNotifications::NotifyDllLoad(const bool aIsMainThread,
const nsString& aDllName)
{
const char* topic;
if (aIsMainThread) {
topic = "dll-loaded-main-thread";
} else {
topic = "dll-loaded-non-main-thread";
}
nsCOMPtr<nsIObserverService> obsServ(mozilla::services::GetObserverService());
obsServ->NotifyObservers(nullptr, topic, aDllName.get());
}
#endif // defined(XP_WIN)
static void DumpArbitraryHelp() static void DumpArbitraryHelp()
{ {
nsresult rv; nsresult rv;
@ -4311,12 +4344,10 @@ XREMain::XRE_mainRun()
NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized."); NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized.");
#if defined(XP_WIN) #if defined(XP_WIN)
RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get()); RefPtr<DllNotifications> dllNotifications(new DllNotifications());
auto dllServicesDisable = MakeScopeExit([&dllServices]() { auto dllNotificationsDisable = MakeScopeExit([&dllNotifications]() {
dllServices->Disable(); dllNotifications->Disable();
}); });
mozilla::CertAnnotator::Register();
#endif // defined(XP_WIN) #endif // defined(XP_WIN)
#ifdef NS_FUNCTION_TIMER #ifdef NS_FUNCTION_TIMER

Просмотреть файл

@ -26,7 +26,6 @@
#include <process.h> #include <process.h>
#include <shobjidl.h> #include <shobjidl.h>
#include "mozilla/ipc/WindowsMessageLoop.h" #include "mozilla/ipc/WindowsMessageLoop.h"
#include "mozilla/WindowsDllBlocklist.h"
#endif #endif
#include "nsAppDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h"
@ -74,6 +73,7 @@
#include "mozilla/ipc/TestShellParent.h" #include "mozilla/ipc/TestShellParent.h"
#include "mozilla/ipc/XPCShellEnvironment.h" #include "mozilla/ipc/XPCShellEnvironment.h"
#include "mozilla/Scheduler.h" #include "mozilla/Scheduler.h"
#include "mozilla/WindowsDllBlocklist.h"
#include "GMPProcessChild.h" #include "GMPProcessChild.h"
#include "mozilla/gfx/GPUProcessImpl.h" #include "mozilla/gfx/GPUProcessImpl.h"

Просмотреть файл

@ -20,6 +20,7 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Mutex.h"
#include <objbase.h> #include <objbase.h>
@ -54,6 +55,8 @@ public:
STDMETHODIMP OnSessionDisconnected(AudioSessionDisconnectReason aReason); STDMETHODIMP OnSessionDisconnected(AudioSessionDisconnectReason aReason);
private: private:
nsresult OnSessionDisconnectedInternal(); nsresult OnSessionDisconnectedInternal();
nsresult CommitAudioSessionData();
public: public:
STDMETHODIMP OnSimpleVolumeChanged(float aVolume, STDMETHODIMP OnSimpleVolumeChanged(float aVolume,
BOOL aMute, BOOL aMute,
@ -86,6 +89,8 @@ protected:
nsString mIconPath; nsString mIconPath;
nsID mSessionGroupingParameter; nsID mSessionGroupingParameter;
SessionState mState; SessionState mState;
// Guards the IAudioSessionControl
mozilla::Mutex mMutex;
ThreadSafeAutoRefCnt mRefCnt; ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD NS_DECL_OWNINGTHREAD
@ -127,7 +132,8 @@ RecvAudioSessionData(const nsID& aID,
AudioSession* AudioSession::sService = nullptr; AudioSession* AudioSession::sService = nullptr;
AudioSession::AudioSession() AudioSession::AudioSession() :
mMutex("AudioSessionControl")
{ {
mState = UNINITIALIZED; mState = UNINITIALIZED;
} }
@ -254,6 +260,7 @@ AudioSession::Start()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
MutexAutoLock lock(mMutex);
hr = manager->GetAudioSessionControl(&GUID_NULL, hr = manager->GetAudioSessionControl(&GUID_NULL,
0, 0,
getter_AddRefs(mAudioSessionControl)); getter_AddRefs(mAudioSessionControl));
@ -262,25 +269,6 @@ AudioSession::Start()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
hr = mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter,
nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
// Increments refcount of 'this'. // Increments refcount of 'this'.
hr = mAudioSessionControl->RegisterAudioSessionNotification(this); hr = mAudioSessionControl->RegisterAudioSessionNotification(this);
if (FAILED(hr)) { if (FAILED(hr)) {
@ -288,6 +276,11 @@ AudioSession::Start()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsCOMPtr<nsIRunnable> runnable =
NewRunnableMethod("AudioSession::CommitAudioSessionData",
this, &AudioSession::CommitAudioSessionData);
NS_DispatchToMainThread(runnable);
mState = STARTED; mState = STARTED;
return NS_OK; return NS_OK;
@ -296,6 +289,8 @@ AudioSession::Start()
void void
AudioSession::StopInternal() AudioSession::StopInternal()
{ {
mMutex.AssertCurrentThreadOwns();
if (mAudioSessionControl && if (mAudioSessionControl &&
(mState == STARTED || mState == STOPPED)) { (mState == STARTED || mState == STOPPED)) {
// Decrement refcount of 'this' // Decrement refcount of 'this'
@ -318,6 +313,7 @@ AudioSession::Stop()
RefPtr<AudioSession> kungFuDeathGrip; RefPtr<AudioSession> kungFuDeathGrip;
kungFuDeathGrip.swap(sService); kungFuDeathGrip.swap(sService);
MutexAutoLock lock(mMutex);
StopInternal(); StopInternal();
} }
@ -374,6 +370,39 @@ AudioSession::SetSessionData(const nsID& aID,
return NS_OK; return NS_OK;
} }
nsresult
AudioSession::CommitAudioSessionData()
{
MutexAutoLock lock(mMutex);
if (!mAudioSessionControl) {
// Stop() was called before we had a chance to do this.
return NS_OK;
}
HRESULT hr =
mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter,
nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr);
if (FAILED(hr)) {
StopInternal();
return NS_ERROR_FAILURE;
}
return NS_OK;
}
STDMETHODIMP STDMETHODIMP
AudioSession::OnChannelVolumeChanged(DWORD aChannelCount, AudioSession::OnChannelVolumeChanged(DWORD aChannelCount,
float aChannelVolumeArray[], float aChannelVolumeArray[],
@ -419,15 +448,20 @@ AudioSession::OnSessionDisconnected(AudioSessionDisconnectReason aReason)
nsresult nsresult
AudioSession::OnSessionDisconnectedInternal() AudioSession::OnSessionDisconnectedInternal()
{ {
if (!mAudioSessionControl) {
return NS_OK; // We need to release the mutex before we call Start().
MutexAutoLock lock(mMutex);
// When successful, UnregisterAudioSessionNotification will decrement the if (!mAudioSessionControl)
// refcount of 'this'. Start will re-increment it. In the interim, return NS_OK;
// we'll need to reference ourselves.
RefPtr<AudioSession> kungFuDeathGrip(this); // When successful, UnregisterAudioSessionNotification will decrement the
mAudioSessionControl->UnregisterAudioSessionNotification(this); // refcount of 'this'. Start will re-increment it. In the interim,
mAudioSessionControl = nullptr; // we'll need to reference ourselves.
RefPtr<AudioSession> kungFuDeathGrip(this);
mAudioSessionControl->UnregisterAudioSessionNotification(this);
mAudioSessionControl = nullptr;
}
mState = AUDIO_SESSION_DISCONNECTED; mState = AUDIO_SESSION_DISCONNECTED;
CoUninitialize(); CoUninitialize();