/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Util.h" #include "nsClipboardPrivacyHandler.h" #include "nsITransferable.h" #include "nsISupportsPrimitives.h" #include "nsIObserverService.h" #include "nsIClipboard.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" #include "nsLiteralString.h" #include "nsNetCID.h" #include "nsXPCOM.h" #include "mozilla/Services.h" #if defined(XP_WIN) #include #endif using namespace mozilla; #define NS_MOZ_DATA_FROM_PRIVATEBROWSING "application/x-moz-private-browsing" NS_IMPL_ISUPPORTS2(nsClipboardPrivacyHandler, nsIObserver, nsISupportsWeakReference) nsresult nsClipboardPrivacyHandler::Init() { nsCOMPtr observerService = mozilla::services::GetObserverService(); if (!observerService) return NS_ERROR_FAILURE; return observerService->AddObserver(this, "last-pb-context-exited", true); } /** * Prepare the transferable object to be inserted into the clipboard * */ nsresult nsClipboardPrivacyHandler::PrepareDataForClipboard(nsITransferable * aTransferable) { NS_ASSERTION(aTransferable, "clipboard given a null transferable"); bool isPrivateData = false; aTransferable->GetIsPrivateData(&isPrivateData); nsresult rv = NS_OK; if (isPrivateData) { nsCOMPtr data = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); if (data) { rv = data->SetData(true); NS_ENSURE_SUCCESS(rv, rv); rv = aTransferable->AddDataFlavor(NS_MOZ_DATA_FROM_PRIVATEBROWSING); NS_ENSURE_SUCCESS(rv, rv); rv = aTransferable->SetTransferData(NS_MOZ_DATA_FROM_PRIVATEBROWSING, data, sizeof(bool)); NS_ENSURE_SUCCESS(rv, rv); } } return rv; } NS_IMETHODIMP nsClipboardPrivacyHandler::Observe(nsISupports *aSubject, char const *aTopic, PRUnichar const *aData) { nsresult rv; nsCOMPtr clipboard = do_GetService("@mozilla.org/widget/clipboard;1", &rv); NS_ENSURE_SUCCESS(rv, rv); const char * flavors[] = { NS_MOZ_DATA_FROM_PRIVATEBROWSING }; bool haveFlavors; rv = clipboard->HasDataMatchingFlavors(flavors, ArrayLength(flavors), nsIClipboard::kGlobalClipboard, &haveFlavors); if (NS_SUCCEEDED(rv) && haveFlavors) { #if defined(XP_WIN) // Workaround for bug 518412. On Windows 7 x64, there is a bug // in handling clipboard data without any formats between // 32-bit/64-bit boundaries, which could lead Explorer to crash. // We work around the problem by clearing the clipboard using // the usual Win32 API. NS_ENSURE_TRUE(SUCCEEDED(::OleSetClipboard(NULL)), NS_ERROR_FAILURE); #else // Empty the native clipboard by copying an empty transferable nsCOMPtr nullData = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv); NS_ENSURE_SUCCESS(rv, rv); nullData->Init(nsnull); rv = clipboard->SetData(nullData, nsnull, nsIClipboard::kGlobalClipboard); NS_ENSURE_SUCCESS(rv, rv); #endif } return NS_OK; } nsresult NS_NewClipboardPrivacyHandler(nsClipboardPrivacyHandler ** aHandler) { NS_PRECONDITION(aHandler != nsnull, "null ptr"); if (!aHandler) return NS_ERROR_NULL_POINTER; *aHandler = new nsClipboardPrivacyHandler(); NS_ADDREF(*aHandler); nsresult rv = (*aHandler)->Init(); if (NS_FAILED(rv)) NS_RELEASE(*aHandler); return rv; }