Backed out 11 changesets (bug 1382251) for clipbloard failures, mingw32 bustage

Backed out changeset a5f447c3bde8 (bug 1382251)
Backed out changeset f9f8aba058c1 (bug 1382251)
Backed out changeset dc0ce4cae588 (bug 1382251)
Backed out changeset 7a304ff7873a (bug 1382251)
Backed out changeset 09cb062d95ee (bug 1382251)
Backed out changeset 95701ac611fa (bug 1382251)
Backed out changeset 37cad137215f (bug 1382251)
Backed out changeset 0d82d0b69c9e (bug 1382251)
Backed out changeset 24de376fb860 (bug 1382251)
Backed out changeset 5f33ad77c5b4 (bug 1382251)
Backed out changeset d2f531c6a6d8 (bug 1382251)
This commit is contained in:
Dorel Luca 2018-01-18 14:44:31 +02:00
Родитель 6f5458a90b
Коммит 52d6539c96
30 изменённых файлов: 1009 добавлений и 4754 удалений

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

@ -1,975 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBroker.h"
#include "FunctionBrokerParent.h"
#include "PluginQuirks.h"
#if defined(XP_WIN)
#include <commdlg.h>
#include <schannel.h>
#endif // defined(XP_WIN)
using namespace mozilla;
using namespace mozilla::ipc;
using namespace mozilla::plugins;
namespace mozilla {
namespace plugins {
template <int QuirkFlag>
static bool CheckQuirks(int aQuirks)
{
return static_cast<bool>(aQuirks & QuirkFlag);
}
void FreeDestructor(void* aObj) { free(aObj); }
#if defined(XP_WIN)
/* GetKeyState */
typedef FunctionBroker<ID_GetKeyState,
decltype(GetKeyState)> GetKeyStateFB;
template<>
ShouldHookFunc* const
GetKeyStateFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_GETKEYSTATE>;
/* SetCursorPos */
typedef FunctionBroker<ID_SetCursorPos,
decltype(SetCursorPos)> SetCursorPosFB;
/* GetSaveFileNameW */
typedef FunctionBroker<ID_GetSaveFileNameW,
decltype(GetSaveFileNameW)> GetSaveFileNameWFB;
// Remember files granted access in the chrome process
static void GrantFileAccess(base::ProcessId aClientId, LPOPENFILENAME& aLpofn,
bool isSave)
{
#if defined(MOZ_SANDBOX)
if (aLpofn->Flags & OFN_ALLOWMULTISELECT) {
// We only support multiselect with the OFN_EXPLORER flag.
// This guarantees that ofn.lpstrFile follows the pattern below.
MOZ_ASSERT(aLpofn->Flags & OFN_EXPLORER);
// lpstrFile is one of two things:
// 1. A null terminated full path to a file, or
// 2. A path to a folder, followed by a NULL, followed by a
// list of file names, each NULL terminated, followed by an
// additional NULL (so it is also double-NULL terminated).
std::wstring path = std::wstring(aLpofn->lpstrFile);
MOZ_ASSERT(aLpofn->nFileOffset > 0);
// For condition #1, nFileOffset points to the file name in the path.
// It will be preceeded by a non-NULL character from the path.
if (aLpofn->lpstrFile[aLpofn->nFileOffset-1] != L'\0') {
FunctionBrokerParent::GetSandboxPermissions()->GrantFileAccess(aClientId, path.c_str(), isSave);
}
else {
// This is condition #2
wchar_t* nextFile = aLpofn->lpstrFile + path.size() + 1;
while (*nextFile != L'\0') {
std::wstring nextFileStr(nextFile);
std::wstring fullPath =
path + std::wstring(L"\\") + nextFileStr;
FunctionBrokerParent::GetSandboxPermissions()->GrantFileAccess(aClientId, fullPath.c_str(), isSave);
nextFile += nextFileStr.size() + 1;
}
}
}
else {
FunctionBrokerParent::GetSandboxPermissions()->GrantFileAccess(aClientId, aLpofn->lpstrFile, isSave);
}
#else
MOZ_ASSERT_UNREACHABLE("GetFileName IPC message is only available on "
"Windows builds with sandbox.");
#endif
}
template<> template<>
BOOL GetSaveFileNameWFB::RunFunction(GetSaveFileNameWFB::FunctionType* aOrigFunction,
base::ProcessId aClientId,
LPOPENFILENAMEW& aLpofn) const
{
BOOL result = aOrigFunction(aLpofn);
if (result) {
// Record any file access permission that was just granted.
GrantFileAccess(aClientId, aLpofn, true);
}
return result;
}
template<> template<>
struct GetSaveFileNameWFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
/* GetOpenFileNameW */
typedef FunctionBroker<ID_GetOpenFileNameW,
decltype(GetOpenFileNameW)> GetOpenFileNameWFB;
template<> template<>
BOOL GetOpenFileNameWFB::RunFunction(GetOpenFileNameWFB::FunctionType* aOrigFunction,
base::ProcessId aClientId,
LPOPENFILENAMEW& aLpofn) const
{
BOOL result = aOrigFunction(aLpofn);
if (result) {
// Record any file access permission that was just granted.
GrantFileAccess(aClientId, aLpofn, false);
}
return result;
}
template<> template<>
struct GetOpenFileNameWFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
/* InternetOpenA */
typedef FunctionBroker<ID_InternetOpenA,
decltype(InternetOpenA)> InternetOpenAFB;
/* InternetConnectA */
typedef FunctionBroker<ID_InternetConnectA,
decltype(InternetConnectA)> InternetConnectAFB;
typedef InternetConnectAFB::Request ICAReqHandler;
template<>
bool ICAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const LPCSTR& srv, const INTERNET_PORT& port,
const LPCSTR& user, const LPCSTR& pass,
const DWORD& svc, const DWORD& flags,
const DWORD_PTR& cxt)
{
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* InternetCloseHandle */
typedef FunctionBroker<ID_InternetCloseHandle,
decltype(InternetCloseHandle)> InternetCloseHandleFB;
typedef InternetCloseHandleFB::Request ICHReqHandler;
template<>
bool ICHReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h)
{
// If we are server side then we were already validated since we had to be
// looked up in the "uint64_t <-> HINTERNET" hashtable.
// In the client, we check that this is a dummy handle.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* InternetQueryDataAvailable */
typedef FunctionBroker<ID_InternetQueryDataAvailable,
decltype(InternetQueryDataAvailable)> InternetQueryDataAvailableFB;
typedef InternetQueryDataAvailableFB::Request IQDAReq;
typedef struct RequestHandler<ID_InternetQueryDataAvailable,
BOOL HOOK_CALL (HINTERNET)> IQDADelegateReq;
template<>
void IQDAReq::Marshal(IpdlTuple& aTuple, const HINTERNET& file,
const LPDWORD& nBytes, const DWORD& flags,
const DWORD_PTR& cxt)
{
IQDADelegateReq::Marshal(aTuple, file);
}
template<>
bool IQDAReq::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& file,
LPDWORD& nBytes, DWORD& flags, DWORD_PTR& cxt)
{
bool success = IQDADelegateReq::Unmarshal(aScd, aTuple, file);
if (!success) {
return false;
}
flags = 0;
cxt = 0;
nBytes = aScd.Allocate<DWORD>();
return true;
}
template<>
bool IQDAReq::ShouldBroker(Endpoint endpoint, const HINTERNET& file,
const LPDWORD& nBytes, const DWORD& flags,
const DWORD_PTR& cxt)
{
// If we are server side then we were already validated since we had to be
// looked up in the "uint64_t <-> HINTERNET" hashtable.
// In the client, we check that this is a dummy handle.
return (endpoint == SERVER) ||
((flags == 0) && (cxt == 0) &&
IsOdd(reinterpret_cast<uint64_t>(file)));
}
template<> template<>
struct InternetQueryDataAvailableFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
/* InternetReadFile */
typedef FunctionBroker<ID_InternetReadFile,
decltype(InternetReadFile)> InternetReadFileFB;
typedef InternetReadFileFB::Request IRFRequestHandler;
typedef struct RequestHandler<ID_InternetReadFile,
BOOL HOOK_CALL (HINTERNET, DWORD)> IRFDelegateReq;
template<>
void IRFRequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
const LPVOID& buf, const DWORD& nBytesToRead,
const LPDWORD& nBytesRead)
{
IRFDelegateReq::Marshal(aTuple, h, nBytesToRead);
}
template<>
bool IRFRequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
LPVOID& buf, DWORD& nBytesToRead,
LPDWORD& nBytesRead)
{
bool ret = IRFDelegateReq::Unmarshal(aScd, aTuple, h, nBytesToRead);
if (!ret) {
return false;
}
nBytesRead = aScd.Allocate<DWORD>();
MOZ_ASSERT(nBytesToRead > 0);
aScd.AllocateMemory(nBytesToRead, buf);
return true;
}
template<>
bool IRFRequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const LPVOID& buf, const DWORD& nBytesToRead,
const LPDWORD& nBytesRead)
{
// For server-side validation, the HINTERNET deserialization will have
// required it to already be looked up in the IdToPtrMap. At that point,
// any call is valid.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
// Marshal the output parameter that we sent to the response delegate.
template<> template<>
struct InternetReadFileFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
typedef ResponseHandler<ID_InternetReadFile, decltype(InternetReadFile)> IRFResponseHandler;
typedef ResponseHandler<ID_InternetReadFile,
BOOL HOOK_CALL (nsDependentCSubstring)> IRFDelegateResponseHandler;
template<>
void IRFResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
const LPVOID& buf, const DWORD& nBytesToRead,
const LPDWORD& nBytesRead)
{
nsDependentCSubstring str;
if (*nBytesRead) {
str.Assign(static_cast<const char*>(buf), *nBytesRead);
}
IRFDelegateResponseHandler::Marshal(aTuple, ret, str);
}
template<>
bool IRFResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
LPVOID& buf, DWORD& nBytesToRead,
LPDWORD& nBytesRead)
{
nsDependentCSubstring str;
bool success =
IRFDelegateResponseHandler::Unmarshal(aTuple, ret, str);
if (!success) {
return false;
}
if (str.Length()) {
memcpy(buf, str.Data(), str.Length());
*nBytesRead = str.Length();
}
return true;
}
/* InternetWriteFile */
typedef FunctionBroker<ID_InternetWriteFile,
decltype(InternetWriteFile)> InternetWriteFileFB;
typedef InternetWriteFileFB::Request IWFReqHandler;
typedef RequestHandler<ID_InternetWriteFile,
int HOOK_CALL (HINTERNET, nsDependentCSubstring)> IWFDelegateReqHandler;
template<>
void IWFReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& file, const LPCVOID& buf,
const DWORD& nToWrite, const LPDWORD& nWritten)
{
MOZ_ASSERT(nWritten);
IWFDelegateReqHandler::Marshal(aTuple, file,
nsDependentCSubstring(static_cast<const char*>(buf), nToWrite));
}
template<>
bool IWFReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& file,
LPCVOID& buf, DWORD& nToWrite, LPDWORD& nWritten)
{
nsDependentCSubstring str;
if (!IWFDelegateReqHandler::Unmarshal(aScd, aTuple, file, str)) {
return false;
}
aScd.AllocateString(str, buf, false);
nToWrite = str.Length();
nWritten = aScd.Allocate<DWORD>();
return true;
}
template<>
bool IWFReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& file,
const LPCVOID& buf, const DWORD& nToWrite,
const LPDWORD& nWritten)
{
// For server-side validation, the HINTERNET deserialization will have
// required it to already be looked up in the IdToPtrMap. At that point,
// any call is valid.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(file));
}
template<> template<>
struct InternetWriteFileFB::Response::Info::ShouldMarshal<3> { static const bool value = true; };
/* InternetSetOptionA */
typedef FunctionBroker<ID_InternetSetOptionA,
decltype(InternetSetOptionA)> InternetSetOptionAFB;
typedef InternetSetOptionAFB::Request ISOAReqHandler;
typedef RequestHandler<ID_InternetSetOptionA,
BOOL HOOK_CALL (HINTERNET, DWORD, nsDependentCSubstring)> ISOADelegateReqHandler;
template<>
void ISOAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h, const DWORD& opt,
const LPVOID& buf, const DWORD& bufLen)
{
ISOADelegateReqHandler::Marshal(aTuple, h, opt,
nsDependentCSubstring(static_cast<const char*>(buf), bufLen));
}
template<>
bool ISOAReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
DWORD& opt, LPVOID& buf, DWORD& bufLen)
{
nsDependentCSubstring str;
if (!ISOADelegateReqHandler::Unmarshal(aScd, aTuple, h, opt, str)) {
return false;
}
aScd.AllocateString(str, buf, false);
bufLen = str.Length();
return true;
}
template<>
bool ISOAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h, const DWORD& opt,
const LPVOID& buf, const DWORD& bufLen)
{
// For server-side validation, the HINTERNET deserialization will have
// required it to already be looked up in the IdToPtrMap. At that point,
// any call is valid.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* HttpAddRequestHeadersA */
typedef FunctionBroker<ID_HttpAddRequestHeadersA,
decltype(HttpAddRequestHeadersA)> HttpAddRequestHeadersAFB;
typedef HttpAddRequestHeadersAFB::Request HARHAReqHandler;
template<>
bool HARHAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const LPCSTR& head, const DWORD& headLen,
const DWORD& mods)
{
// For server-side validation, the HINTERNET deserialization will have
// required it to already be looked up in the IdToPtrMap. At that point,
// any call is valid.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* HttpOpenRequestA */
typedef FunctionBroker<ID_HttpOpenRequestA,
decltype(HttpOpenRequestA)> HttpOpenRequestAFB;
typedef HttpOpenRequestAFB::Request HORAReqHandler;
typedef RequestHandler<ID_HttpOpenRequestA,
HINTERNET HOOK_CALL (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR,
nsTArray<nsCString>, DWORD, DWORD_PTR)> HORADelegateReqHandler;
template<>
void HORAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
const LPCSTR& verb, const LPCSTR& obj,
const LPCSTR& ver, const LPCSTR& ref,
LPCSTR * const & acceptTypes, const DWORD& flags,
const DWORD_PTR& cxt)
{
nsTArray<nsCString> arrayAcceptTypes;
LPCSTR * curAcceptType = acceptTypes;
if (curAcceptType) {
while (*curAcceptType) {
arrayAcceptTypes.AppendElement(nsCString(*curAcceptType));
++curAcceptType;
}
}
HORADelegateReqHandler::Marshal(aTuple, h, verb, obj, ver, ref,
arrayAcceptTypes, flags, cxt);
}
template<>
bool HORAReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
LPCSTR& verb, LPCSTR& obj, LPCSTR& ver,
LPCSTR& ref, LPCSTR *& acceptTypes,
DWORD& flags, DWORD_PTR& cxt)
{
nsTArray<nsCString> arrayAcceptTypes;
if (!HORADelegateReqHandler::Unmarshal(aScd, aTuple, h, verb, obj, ver, ref, arrayAcceptTypes, flags, cxt)) {
return false;
}
if (arrayAcceptTypes.Length() == 0) {
acceptTypes = nullptr;
} else {
aScd.AllocateMemory((arrayAcceptTypes.Length() + 1) * sizeof(LPCSTR), acceptTypes);
for (size_t i = 0; i < arrayAcceptTypes.Length(); ++i) {
aScd.AllocateString(arrayAcceptTypes[i], acceptTypes[i]);
}
acceptTypes[arrayAcceptTypes.Length()] = nullptr;
}
return true;
}
template<>
bool HORAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const LPCSTR& verb, const LPCSTR& obj,
const LPCSTR& ver, const LPCSTR& ref,
LPCSTR * const & acceptTypes,
const DWORD& flags, const DWORD_PTR& cxt)
{
// For the server-side test, the HINTERNET deserialization will have
// required it to already be looked up in the IdToPtrMap. At that point,
// any call is valid.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* HttpQueryInfoA */
typedef FunctionBroker<ID_HttpQueryInfoA,
decltype(HttpQueryInfoA)> HttpQueryInfoAFB;
typedef HttpQueryInfoAFB::Request HQIARequestHandler;
typedef RequestHandler<ID_HttpQueryInfoA,
BOOL HOOK_CALL (HINTERNET, DWORD, BOOL, DWORD, BOOL,
DWORD)> HQIADelegateRequestHandler;
template<>
void HQIARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
const DWORD& lvl, const LPVOID& buf, const LPDWORD& bufLen,
const LPDWORD& idx)
{
HQIADelegateRequestHandler::Marshal(aTuple, h, lvl,
bufLen != nullptr, bufLen ? *bufLen : 0,
idx != nullptr, idx ? *idx : 0);
}
template<>
bool HQIARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
DWORD& lvl, LPVOID& buf, LPDWORD& bufLen,
LPDWORD& idx)
{
BOOL hasBufLen, hasIdx;
DWORD tempBufLen, tempIdx;
bool success =
HQIADelegateRequestHandler::Unmarshal(aScd, aTuple, h, lvl, hasBufLen, tempBufLen, hasIdx, tempIdx);
if (!success) {
return false;
}
bufLen = nullptr;
if (hasBufLen) {
aScd.AllocateMemory(tempBufLen, buf, bufLen);
}
idx = nullptr;
if (hasIdx) {
idx = aScd.Allocate<DWORD>(tempIdx);
}
return true;
}
template<>
bool HQIARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const DWORD& lvl, const LPVOID& buf,
const LPDWORD& bufLen, const LPDWORD& idx)
{
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
// Marshal all of the output parameters that we sent to the response delegate.
template<> template<>
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
template<> template<>
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
template<> template<>
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<2> { static const bool value = true; };
typedef HttpQueryInfoAFB::Response HQIAResponseHandler;
typedef ResponseHandler<ID_HttpQueryInfoA,
BOOL HOOK_CALL (nsDependentCSubstring,
DWORD, DWORD)> HQIADelegateResponseHandler;
template<>
void HQIAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
const DWORD& lvl, const LPVOID& buf, const LPDWORD& bufLen,
const LPDWORD& idx)
{
nsDependentCSubstring str;
if (buf && ret) {
MOZ_ASSERT(bufLen);
str.Assign(static_cast<const char*>(buf), *bufLen);
}
// Note that we send the bufLen separately to handle the case where buf wasn't
// allocated or large enough to hold the entire return value. bufLen is then
// the required buffer size.
HQIADelegateResponseHandler::Marshal(aTuple, ret, str,
bufLen ? *bufLen : 0, idx ? *idx : 0);
}
template<>
bool HQIAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
DWORD& lvl, LPVOID& buf, LPDWORD& bufLen,
LPDWORD& idx)
{
DWORD totalBufLen = *bufLen;
nsDependentCSubstring str;
DWORD tempBufLen, tempIdx;
bool success =
HQIADelegateResponseHandler::Unmarshal(aTuple, ret, str, tempBufLen, tempIdx);
if (!success) {
return false;
}
if (bufLen) {
*bufLen = tempBufLen;
}
if (idx) {
*idx = tempIdx;
}
if (buf && ret) {
// When HttpQueryInfo returns strings, the buffer length will not include
// the null terminator. Rather than (brittle-y) trying to determine if the
// return buffer is a string, we always tack on a null terminator if the
// buffer has room for it.
MOZ_ASSERT(str.Length() == *bufLen);
memcpy(buf, str.Data(), str.Length());
if (str.Length() < totalBufLen) {
char* cbuf = static_cast<char*>(buf);
cbuf[str.Length()] = '\0';
}
}
return true;
}
/* HttpSendRequestA */
typedef FunctionBroker<ID_HttpSendRequestA,
decltype(HttpSendRequestA)> HttpSendRequestAFB;
typedef HttpSendRequestAFB::Request HSRARequestHandler;
typedef RequestHandler<ID_HttpSendRequestA,
BOOL HOOK_CALL (HINTERNET, nsDependentCSubstring,
nsDependentCSubstring)> HSRADelegateRequestHandler;
template<>
void HSRARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
const LPCSTR& head, const DWORD& headLen,
const LPVOID& opt, const DWORD& optLen)
{
nsDependentCSubstring headStr;
headStr.SetIsVoid(head == nullptr);
if (head) {
// HttpSendRequest allows headLen == -1L for length of a null terminated string.
DWORD ncHeadLen = headLen;
if (ncHeadLen == -1L) {
ncHeadLen = strlen(head);
}
headStr.Rebind(head, ncHeadLen);
}
nsDependentCSubstring optStr;
optStr.SetIsVoid(opt == nullptr);
if (opt) {
optStr.Rebind(static_cast<const char*>(opt), optLen);
}
HSRADelegateRequestHandler::Marshal(aTuple, h, headStr, optStr);
}
template<>
bool HSRARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
LPCSTR& head, DWORD& headLen, LPVOID& opt,
DWORD& optLen)
{
nsDependentCSubstring headStr;
nsDependentCSubstring optStr;
bool success = HSRADelegateRequestHandler::Unmarshal(aScd, aTuple, h, headStr, optStr);
if (!success) {
return false;
}
if (headStr.IsVoid()) {
head = nullptr;
MOZ_ASSERT(headLen == 0);
} else {
aScd.AllocateString(headStr, head, false);
headLen = headStr.Length();
}
if (optStr.IsVoid()) {
opt = nullptr;
MOZ_ASSERT(optLen == 0);
} else {
aScd.AllocateString(optStr, opt, false);
optLen = optStr.Length();
}
return true;
}
template<>
bool HSRARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const LPCSTR& head, const DWORD& headLen,
const LPVOID& opt, const DWORD& optLen)
{
// If we are server side then we were already validated since we had to be
// looked up in the "uint64_t <-> HINTERNET" hashtable.
// In the client, we check that this is a dummy handle.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
/* HttpSendRequestExA */
typedef FunctionBroker<ID_HttpSendRequestExA,
decltype(HttpSendRequestExA)> HttpSendRequestExAFB;
typedef RequestInfo<ID_HttpSendRequestExA> HSRExAReqInfo;
template<> template<>
struct HSRExAReqInfo::FixedValue<2> { static const LPINTERNET_BUFFERSA value; };
const LPINTERNET_BUFFERSA HSRExAReqInfo::FixedValue<2>::value = nullptr;
// Docs for HttpSendRequestExA say this parameter 'must' be zero but Flash
// passes other values.
// template<> template<>
// struct HSRExAReqInfo::FixedValue<3> { static const DWORD value = 0; };
template<> template<>
struct HSRExAReqInfo::FixedValue<4> { static const DWORD_PTR value = 0; };
/* InternetQueryOptionA */
typedef FunctionBroker<ID_InternetQueryOptionA,
decltype(InternetQueryOptionA)> InternetQueryOptionAFB;
typedef InternetQueryOptionAFB::Request IQOARequestHandler;
typedef RequestHandler<ID_InternetQueryOptionA,
BOOL HOOK_CALL (HINTERNET, DWORD, DWORD)> IQOADelegateRequestHandler;
template<>
void IQOARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
const DWORD& opt, const LPVOID& buf, const LPDWORD& bufLen)
{
MOZ_ASSERT(bufLen);
IQOADelegateRequestHandler::Marshal(aTuple, h, opt, buf ? *bufLen : 0);
}
template<>
bool IQOARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
DWORD& opt, LPVOID& buf, LPDWORD& bufLen)
{
DWORD tempBufLen;
bool success =
IQOADelegateRequestHandler::Unmarshal(aScd, aTuple, h, opt, tempBufLen);
if (!success) {
return false;
}
aScd.AllocateMemory(tempBufLen, buf, bufLen);
return true;
}
template<>
bool IQOARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
const DWORD& opt, const LPVOID& buf,
const LPDWORD& bufLen)
{
// If we are server side then we were already validated since we had to be
// looked up in the "uint64_t <-> HINTERNET" hashtable.
// In the client, we check that this is a dummy handle.
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
}
// Marshal all of the output parameters that we sent to the response delegate.
template<> template<>
struct InternetQueryOptionAFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
template<> template<>
struct InternetQueryOptionAFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
typedef InternetQueryOptionAFB::Response IQOAResponseHandler;
typedef ResponseHandler<ID_InternetQueryOptionA,
BOOL HOOK_CALL (nsDependentCSubstring, DWORD)> IQOADelegateResponseHandler;
template<>
void IQOAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
const DWORD& opt, const LPVOID& buf, const LPDWORD& bufLen)
{
nsDependentCSubstring str;
if (buf && ret) {
MOZ_ASSERT(*bufLen);
str.Assign(static_cast<const char*>(buf), *bufLen);
}
IQOADelegateResponseHandler::Marshal(aTuple, ret, str, *bufLen);
}
template<>
bool IQOAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
DWORD& opt, LPVOID& buf, LPDWORD& bufLen)
{
nsDependentCSubstring str;
bool success =
IQOADelegateResponseHandler::Unmarshal(aTuple, ret, str, *bufLen);
if (!success) {
return false;
}
if (buf && ret) {
MOZ_ASSERT(str.Length() == *bufLen);
memcpy(buf, str.Data(), str.Length());
}
return true;
}
/* InternetErrorDlg */
typedef FunctionBroker<ID_InternetErrorDlg,
decltype(InternetErrorDlg)> InternetErrorDlgFB;
typedef RequestInfo<ID_InternetErrorDlg> IEDReqInfo;
template<> template<>
struct IEDReqInfo::FixedValue<4> { static LPVOID* const value; };
LPVOID* const IEDReqInfo::FixedValue<4>::value = nullptr;
typedef InternetErrorDlgFB::Request IEDReqHandler;
template<>
bool IEDReqHandler::ShouldBroker(Endpoint endpoint, const HWND& hwnd,
const HINTERNET& h, const DWORD& err,
const DWORD& flags, LPVOID* const & data)
{
const DWORD SUPPORTED_FLAGS =
FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_NO_UI;
// We broker if (1) the handle h is brokered (odd in client),
// (2) we support the requested action flags and (3) there is no user
// data, which wouldn't make sense for our supported flags anyway.
return ((endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h))) &&
(!(flags & ~SUPPORTED_FLAGS)) && (data == nullptr);
}
/* AcquireCredentialsHandleA */
typedef FunctionBroker<ID_AcquireCredentialsHandleA,
decltype(AcquireCredentialsHandleA)> AcquireCredentialsHandleAFB;
typedef RequestInfo<ID_AcquireCredentialsHandleA> ACHAReqInfo;
template<> template<>
struct ACHAReqInfo::FixedValue<0> { static const LPSTR value; };
const LPSTR ACHAReqInfo::FixedValue<0>::value = nullptr;
template<> template<>
struct ACHAReqInfo::FixedValue<1> { static const LPSTR value; };
const LPSTR ACHAReqInfo::FixedValue<1>::value = UNISP_NAME_A;
template<> template<>
struct ACHAReqInfo::FixedValue<2> { static const unsigned long value; };
const unsigned long ACHAReqInfo::FixedValue<2>::value = SECPKG_CRED_OUTBOUND;
template<> template<>
struct ACHAReqInfo::FixedValue<3> { static void* const value; };
void* const ACHAReqInfo::FixedValue<3>::value = nullptr;
template<> template<>
struct ACHAReqInfo::FixedValue<5> { static const SEC_GET_KEY_FN value; };
const SEC_GET_KEY_FN ACHAReqInfo::FixedValue<5>::value = nullptr;
template<> template<>
struct ACHAReqInfo::FixedValue<6> { static void* const value; };
void* const ACHAReqInfo::FixedValue<6>::value = nullptr;
typedef AcquireCredentialsHandleAFB::Request ACHARequestHandler;
typedef RequestHandler<ID_AcquireCredentialsHandleA,
SECURITY_STATUS HOOK_CALL (LPSTR, LPSTR, unsigned long,
void*, PSCHANNEL_CRED, SEC_GET_KEY_FN,
void*)> ACHADelegateRequestHandler;
template<>
void ACHARequestHandler::Marshal(IpdlTuple& aTuple, const LPSTR& principal,
const LPSTR& pkg, const unsigned long& credUse,
const PVOID& logonId, const PVOID& auth,
const SEC_GET_KEY_FN& getKeyFn,
const PVOID& getKeyArg, const PCredHandle& cred,
const PTimeStamp& expiry)
{
const PSCHANNEL_CRED& scCred = reinterpret_cast<const PSCHANNEL_CRED&>(auth);
ACHADelegateRequestHandler::Marshal(aTuple, principal, pkg, credUse, logonId,
scCred, getKeyFn, getKeyArg);
}
template<>
bool ACHARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, LPSTR& principal,
LPSTR& pkg, unsigned long& credUse,
PVOID& logonId, PVOID& auth, SEC_GET_KEY_FN& getKeyFn,
PVOID& getKeyArg, PCredHandle& cred, PTimeStamp& expiry)
{
PSCHANNEL_CRED& scCred = reinterpret_cast<PSCHANNEL_CRED&>(auth);
if (!ACHADelegateRequestHandler::Unmarshal(aScd, aTuple, principal, pkg, credUse,
logonId, scCred, getKeyFn, getKeyArg)) {
return false;
}
cred = aScd.Allocate<CredHandle>();
expiry = aScd.Allocate<::TimeStamp>();
return true;
}
typedef ResponseInfo<ID_AcquireCredentialsHandleA> ACHARspInfo;
// Response phase must send output parameters
template<> template<>
struct ACHARspInfo::ShouldMarshal<7> { static const bool value = true; };
template<> template<>
struct ACHARspInfo::ShouldMarshal<8> { static const bool value = true; };
/* QueryCredentialsAttributesA */
typedef FunctionBroker<ID_QueryCredentialsAttributesA,
decltype(QueryCredentialsAttributesA)> QueryCredentialsAttributesAFB;
/* FreeCredentialsHandle */
typedef FunctionBroker<ID_FreeCredentialsHandle,
decltype(FreeCredentialsHandle)> FreeCredentialsHandleFB;
typedef FreeCredentialsHandleFB::Request FCHReq;
template<>
bool FCHReq::ShouldBroker(Endpoint endpoint, const PCredHandle& h)
{
// If we are server side then we were already validated since we had to be
// looked up in the "uint64_t <-> CredHandle" hashtable.
// In the client, we check that this is a dummy handle.
return (endpoint == SERVER) ||
((h->dwLower == h->dwUpper) && IsOdd(static_cast<uint64_t>(h->dwLower)));
}
#endif // defined(XP_WIN)
/*****************************************************************************/
#define FUN_HOOK(x) static_cast<FunctionHook*>(x)
void
AddBrokeredFunctionHooks(FunctionHookArray& aHooks)
{
// We transfer ownership of the FunctionHook objects to the array.
#if defined(XP_WIN)
aHooks[ID_GetKeyState] =
FUN_HOOK(new GetKeyStateFB("user32.dll", "GetKeyState", &GetKeyState));
aHooks[ID_SetCursorPos] =
FUN_HOOK(new SetCursorPosFB("user32.dll", "SetCursorPos", &SetCursorPos));
aHooks[ID_GetSaveFileNameW] =
FUN_HOOK(new GetSaveFileNameWFB("comdlg32.dll", "GetSaveFileNameW",
&GetSaveFileNameW));
aHooks[ID_GetOpenFileNameW] =
FUN_HOOK(new GetOpenFileNameWFB("comdlg32.dll", "GetOpenFileNameW",
&GetOpenFileNameW));
aHooks[ID_InternetOpenA] =
FUN_HOOK(new InternetOpenAFB("wininet.dll", "InternetOpenA", &InternetOpenA));
aHooks[ID_InternetConnectA] =
FUN_HOOK(new InternetConnectAFB("wininet.dll", "InternetConnectA",
&InternetConnectA));
aHooks[ID_InternetCloseHandle] =
FUN_HOOK(new InternetCloseHandleFB("wininet.dll", "InternetCloseHandle",
&InternetCloseHandle));
aHooks[ID_InternetQueryDataAvailable] =
FUN_HOOK(new InternetQueryDataAvailableFB("wininet.dll",
"InternetQueryDataAvailable",
&InternetQueryDataAvailable));
aHooks[ID_InternetReadFile] =
FUN_HOOK(new InternetReadFileFB("wininet.dll", "InternetReadFile",
&InternetReadFile));
aHooks[ID_InternetWriteFile] =
FUN_HOOK(new InternetWriteFileFB("wininet.dll", "InternetWriteFile",
&InternetWriteFile));
aHooks[ID_InternetSetOptionA] =
FUN_HOOK(new InternetSetOptionAFB("wininet.dll", "InternetSetOptionA",
&InternetSetOptionA));
aHooks[ID_HttpAddRequestHeadersA] =
FUN_HOOK(new HttpAddRequestHeadersAFB("wininet.dll",
"HttpAddRequestHeadersA",
&HttpAddRequestHeadersA));
aHooks[ID_HttpOpenRequestA] =
FUN_HOOK(new HttpOpenRequestAFB("wininet.dll", "HttpOpenRequestA",
&HttpOpenRequestA));
aHooks[ID_HttpQueryInfoA] =
FUN_HOOK(new HttpQueryInfoAFB("wininet.dll", "HttpQueryInfoA",
&HttpQueryInfoA));
aHooks[ID_HttpSendRequestA] =
FUN_HOOK(new HttpSendRequestAFB("wininet.dll", "HttpSendRequestA",
&HttpSendRequestA));
aHooks[ID_HttpSendRequestExA] =
FUN_HOOK(new HttpSendRequestExAFB("wininet.dll", "HttpSendRequestExA",
&HttpSendRequestExA));
aHooks[ID_InternetQueryOptionA] =
FUN_HOOK(new InternetQueryOptionAFB("wininet.dll", "InternetQueryOptionA",
&InternetQueryOptionA));
aHooks[ID_InternetErrorDlg] =
FUN_HOOK(new InternetErrorDlgFB("wininet.dll", "InternetErrorDlg",
InternetErrorDlg));
aHooks[ID_AcquireCredentialsHandleA] =
FUN_HOOK(new AcquireCredentialsHandleAFB("sspicli.dll",
"AcquireCredentialsHandleA",
&AcquireCredentialsHandleA));
aHooks[ID_QueryCredentialsAttributesA] =
FUN_HOOK(new QueryCredentialsAttributesAFB("sspicli.dll",
"QueryCredentialsAttributesA",
&QueryCredentialsAttributesA));
aHooks[ID_FreeCredentialsHandle] =
FUN_HOOK(new FreeCredentialsHandleFB("sspicli.dll",
"FreeCredentialsHandle",
&FreeCredentialsHandle));
#endif // defined(XP_WIN)
}
#undef FUN_HOOK
} // namespace plugins
} // namespace mozilla

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerChild.h"
#include "FunctionBrokerThread.h"
namespace mozilla {
namespace plugins {
FunctionBrokerChild* FunctionBrokerChild::sInstance = nullptr;
bool
FunctionBrokerChild::IsDispatchThread()
{
return mThread->IsOnThread();
}
void
FunctionBrokerChild::PostToDispatchThread(already_AddRefed<nsIRunnable>&& runnable)
{
mThread->Dispatch(Move(runnable));
}
/* static */ bool
FunctionBrokerChild::Initialize(Endpoint<PFunctionBrokerChild>&& aBrokerEndpoint)
{
MOZ_RELEASE_ASSERT(XRE_IsPluginProcess(),
"FunctionBrokerChild can only be used in plugin processes");
MOZ_ASSERT(!sInstance);
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
if (!thread) {
return false;
}
sInstance = new FunctionBrokerChild(thread, Move(aBrokerEndpoint));
return true;
}
/* static */ FunctionBrokerChild*
FunctionBrokerChild::GetInstance()
{
MOZ_RELEASE_ASSERT(XRE_IsPluginProcess(),
"FunctionBrokerChild can only be used in plugin processes");
MOZ_ASSERT(sInstance, "Must initialize FunctionBrokerChild before using it");
return sInstance;
}
FunctionBrokerChild::FunctionBrokerChild(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerChild>&& aEndpoint) :
mThread(aThread)
, mShutdownDone(false)
, mMonitor("FunctionBrokerChild Lock")
{
MOZ_ASSERT(aThread);
PostToDispatchThread(NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerChild>&&>(
"FunctionBrokerChild::Bind", this, &FunctionBrokerChild::Bind,
Move(aEndpoint)));
}
void
FunctionBrokerChild::Bind(Endpoint<PFunctionBrokerChild>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
}
void
FunctionBrokerChild::ShutdownOnDispatchThread()
{
MOZ_ASSERT(mThread->IsOnThread());
// Set mShutdownDone and notify waiting thread (if any) that we are done.
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
mMonitor.Notify();
}
void
FunctionBrokerChild::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(mThread->IsOnThread());
// Queue up a task on the PD thread. When that task is executed then
// we know that anything queued before ActorDestroy has completed.
// At that point, we can set mShutdownDone and alert any waiting
// threads that it is safe to destroy us.
sInstance->PostToDispatchThread(NewNonOwningRunnableMethod(
"FunctionBrokerChild::ShutdownOnDispatchThread", sInstance,
&FunctionBrokerChild::ShutdownOnDispatchThread));
}
void
FunctionBrokerChild::Destroy()
{
MOZ_ASSERT(NS_IsMainThread());
if (!sInstance) {
return;
}
// mShutdownDone will tell us when ActorDestroy has been run and any tasks
// on the FunctionBrokerThread have completed. At that point, we can
// safely delete the actor.
{
MonitorAutoLock lock(sInstance->mMonitor);
while (!sInstance->mShutdownDone) {
// Release lock and wait. Regain lock when we are notified that
// we have ShutdownOnDispatchThread.
sInstance->mMonitor.Wait();
}
}
delete sInstance;
sInstance = nullptr;
}
} // namespace plugins
} // namespace mozilla

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

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerchild_h
#define mozilla_plugins_functionbrokerchild_h
#include "mozilla/plugins/PFunctionBrokerChild.h"
namespace mozilla {
namespace plugins {
class FunctionBrokerThread;
/**
* Dispatches brokered methods to the Parent process to allow functionality
* that is otherwise blocked by the sandbox.
*/
class FunctionBrokerChild : public PFunctionBrokerChild
{
public:
static bool Initialize(Endpoint<PFunctionBrokerChild>&& aBrokerEndpoint);
static FunctionBrokerChild* GetInstance();
static void Destroy();
bool IsDispatchThread();
void PostToDispatchThread(already_AddRefed<nsIRunnable>&& runnable);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
explicit FunctionBrokerChild(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerChild>&& aEndpoint);
void ShutdownOnDispatchThread();
void Bind(Endpoint<PFunctionBrokerChild>&& aEndpoint);
nsAutoPtr<FunctionBrokerThread> mThread;
// True if tasks on the FunctionBrokerThread have completed
bool mShutdownDone;
// This monitor guards mShutdownDone.
Monitor mMonitor;
static FunctionBrokerChild* sInstance;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerchild_h

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

@ -1,359 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerIPCUtils.h"
#if defined(XP_WIN)
#include <schannel.h>
/* these defines are missing from mingw headers */
#ifndef SP_PROT_TLS1_1_CLIENT
#define SP_PROT_TLS1_1_CLIENT 0x00000200
#endif
#ifndef SP_PROT_TLS1_2_CLIENT
#define SP_PROT_TLS1_2_CLIENT 0x00000800
#endif
namespace mozilla {
namespace plugins {
mozilla::LazyLogModule sPluginHooksLog("PluginHooks");
static const DWORD SCHANNEL_SUPPORTED_PROTOCOLS =
SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
static const DWORD SCHANNEL_SUPPORTED_FLAGS =
SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
SCH_CRED_REVOCATION_CHECK_END_CERT;
void
OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
mHwndOwner = nullptr;
// Filter is double-NULL terminated. mFilter should include the double-NULL.
mHasFilter = aLpofn->lpstrFilter != nullptr;
if (mHasFilter) {
uint32_t dNullIdx = 0;
while (aLpofn->lpstrFilter[dNullIdx] != L'\0' ||
aLpofn->lpstrFilter[dNullIdx+1] != L'\0') {
dNullIdx++;
}
mFilter.assign(aLpofn->lpstrFilter, dNullIdx+2);
}
mHasCustomFilter = aLpofn->lpstrCustomFilter != nullptr;
if (mHasCustomFilter) {
mCustomFilterIn = std::wstring(aLpofn->lpstrCustomFilter);
mNMaxCustFilterOut =
aLpofn->nMaxCustFilter - (wcslen(aLpofn->lpstrCustomFilter) + 1);
}
else {
mNMaxCustFilterOut = 0;
}
mFilterIndex = aLpofn->nFilterIndex;
mFile = std::wstring(aLpofn->lpstrFile);
mNMaxFile = aLpofn->nMaxFile;
mNMaxFileTitle =
aLpofn->lpstrFileTitle != nullptr ? aLpofn->nMaxFileTitle : 0;
mHasInitialDir = aLpofn->lpstrInitialDir != nullptr;
if (mHasInitialDir) {
mInitialDir = std::wstring(aLpofn->lpstrInitialDir);
}
mHasTitle = aLpofn->lpstrTitle != nullptr;
if (mHasTitle) {
mTitle = std::wstring(aLpofn->lpstrTitle);
}
mHasDefExt = aLpofn->lpstrDefExt != nullptr;
if (mHasDefExt) {
mDefExt = std::wstring(aLpofn->lpstrDefExt);
}
mFlags = aLpofn->Flags;
// If the user sets OFN_ALLOWMULTISELECT then we require OFN_EXPLORER
// as well. Without OFN_EXPLORER, the method has ancient legacy
// behavior that we don't support.
MOZ_ASSERT((mFlags & OFN_EXPLORER) || !(mFlags & OFN_ALLOWMULTISELECT));
// We ignore any visual customization and callbacks that the user set.
mFlags &= ~(OFN_ENABLEHOOK | OFN_ENABLETEMPLATEHANDLE | OFN_ENABLETEMPLATE);
mFlagsEx = aLpofn->FlagsEx;
}
void
OpenFileNameIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
aLpofn->lStructSize = sizeof(OPENFILENAMEW);
aLpofn->hwndOwner = mHwndOwner;
if (mHasFilter) {
memcpy(const_cast<LPWSTR>(aLpofn->lpstrFilter),
mFilter.data(), mFilter.size() * sizeof(wchar_t));
}
if (mHasCustomFilter) {
aLpofn->nMaxCustFilter = mCustomFilterIn.size() + 1 + mNMaxCustFilterOut;
wcscpy(aLpofn->lpstrCustomFilter, mCustomFilterIn.c_str());
memset(aLpofn->lpstrCustomFilter + mCustomFilterIn.size() + 1, 0,
mNMaxCustFilterOut * sizeof(wchar_t));
}
else {
aLpofn->nMaxCustFilter = 0;
}
aLpofn->nFilterIndex = mFilterIndex;
if (mNMaxFile > 0) {
wcsncpy(aLpofn->lpstrFile, mFile.c_str(),
std::min(static_cast<uint32_t>(mFile.size()+1), mNMaxFile));
aLpofn->lpstrFile[mNMaxFile - 1] = L'\0';
}
aLpofn->nMaxFile = mNMaxFile;
aLpofn->nMaxFileTitle = mNMaxFileTitle;
if (mHasInitialDir) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrInitialDir), mInitialDir.c_str());
}
if (mHasTitle) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrTitle), mTitle.c_str());
}
aLpofn->Flags = mFlags; /* TODO: Consider adding OFN_NOCHANGEDIR */
if (mHasDefExt) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrDefExt), mDefExt.c_str());
}
aLpofn->FlagsEx = mFlagsEx;
}
void
OpenFileNameIPC::AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const
{
if (mHasFilter) {
// mFilter is double-NULL terminated and it includes the double-NULL in its length.
aLpofn->lpstrFilter =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mFilter.size())));
}
if (mHasCustomFilter) {
aLpofn->lpstrCustomFilter =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * (mCustomFilterIn.size() + 1 + mNMaxCustFilterOut)));
}
aLpofn->lpstrFile =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFile));
if (mNMaxFileTitle > 0) {
aLpofn->lpstrFileTitle =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFileTitle));
}
if (mHasInitialDir) {
aLpofn->lpstrInitialDir =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mInitialDir.size() + 1)));
}
if (mHasTitle) {
aLpofn->lpstrTitle =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mTitle.size() + 1)));
}
if (mHasDefExt) {
aLpofn->lpstrDefExt =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mDefExt.size() + 1)));
}
}
// static
void
OpenFileNameIPC::FreeOfnStrings(LPOPENFILENAMEW aLpofn)
{
if (aLpofn->lpstrFilter) {
free(const_cast<LPWSTR>(aLpofn->lpstrFilter));
}
if (aLpofn->lpstrCustomFilter) {
free(aLpofn->lpstrCustomFilter);
}
if (aLpofn->lpstrFile) {
free(aLpofn->lpstrFile);
}
if (aLpofn->lpstrFileTitle) {
free(aLpofn->lpstrFileTitle);
}
if (aLpofn->lpstrInitialDir) {
free(const_cast<LPWSTR>(aLpofn->lpstrInitialDir));
}
if (aLpofn->lpstrTitle) {
free(const_cast<LPWSTR>(aLpofn->lpstrTitle));
}
if (aLpofn->lpstrDefExt) {
free(const_cast<LPWSTR>(aLpofn->lpstrDefExt));
}
}
void
OpenFileNameRetIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
if (aLpofn->lpstrCustomFilter != nullptr) {
mCustomFilterOut =
std::wstring(aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1);
}
mFile.assign(aLpofn->lpstrFile, aLpofn->nMaxFile);
if (aLpofn->lpstrFileTitle != nullptr) {
mFileTitle.assign(aLpofn->lpstrFileTitle, wcslen(aLpofn->lpstrFileTitle) + 1);
}
mFileOffset = aLpofn->nFileOffset;
mFileExtension = aLpofn->nFileExtension;
}
void
OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
if (aLpofn->lpstrCustomFilter) {
LPWSTR secondString =
aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1;
const wchar_t* customFilterOut = mCustomFilterOut.c_str();
MOZ_ASSERT(wcslen(aLpofn->lpstrCustomFilter) + 1 +
wcslen(customFilterOut) + 1 + 1 <= aLpofn->nMaxCustFilter);
wcscpy(secondString, customFilterOut);
secondString[wcslen(customFilterOut) + 1] = L'\0'; // terminated with two NULLs
}
MOZ_ASSERT(mFile.size() <= aLpofn->nMaxFile);
memcpy(aLpofn->lpstrFile,
mFile.data(), mFile.size() * sizeof(wchar_t));
if (aLpofn->lpstrFileTitle != nullptr) {
MOZ_ASSERT(mFileTitle.size() + 1 < aLpofn->nMaxFileTitle);
wcscpy(aLpofn->lpstrFileTitle, mFileTitle.c_str());
}
aLpofn->nFileOffset = mFileOffset;
aLpofn->nFileExtension = mFileExtension;
}
void
IPCSchannelCred::CopyFrom(const PSCHANNEL_CRED& aSCred)
{
// We assert that the aSCred fields take supported values.
// If they do not then we ignore the values we were given.
MOZ_ASSERT(aSCred->dwVersion == SCHANNEL_CRED_VERSION);
MOZ_ASSERT(aSCred->cCreds == 0);
MOZ_ASSERT(aSCred->paCred == nullptr);
MOZ_ASSERT(aSCred->hRootStore == nullptr);
MOZ_ASSERT(aSCred->cMappers == 0);
MOZ_ASSERT(aSCred->aphMappers == nullptr);
MOZ_ASSERT(aSCred->cSupportedAlgs == 0);
MOZ_ASSERT(aSCred->palgSupportedAlgs == nullptr);
MOZ_ASSERT((aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS) ==
aSCred->grbitEnabledProtocols);
mEnabledProtocols =
aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
mMinStrength = aSCred->dwMinimumCipherStrength;
mMaxStrength = aSCred->dwMaximumCipherStrength;
MOZ_ASSERT(aSCred->dwSessionLifespan == 0);
MOZ_ASSERT((aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS) == aSCred->dwFlags);
mFlags = aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS;
MOZ_ASSERT(aSCred->dwCredFormat == 0);
}
void
IPCSchannelCred::CopyTo(PSCHANNEL_CRED& aSCred) const
{
// Validate values as they come from an untrusted process.
memset(aSCred, 0, sizeof(SCHANNEL_CRED));
aSCred->dwVersion = SCHANNEL_CRED_VERSION;
aSCred->grbitEnabledProtocols =
mEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
aSCred->dwMinimumCipherStrength = mMinStrength;
aSCred->dwMaximumCipherStrength = mMaxStrength;
aSCred->dwFlags = mFlags & SCHANNEL_SUPPORTED_FLAGS;
}
void
IPCInternetBuffers::CopyFrom(const LPINTERNET_BUFFERSA& aBufs)
{
mBuffers.Clear();
LPINTERNET_BUFFERSA inetBuf = aBufs;
while (inetBuf) {
MOZ_ASSERT(inetBuf->dwStructSize == sizeof(INTERNET_BUFFERSA));
Buffer* ipcBuf = mBuffers.AppendElement();
ipcBuf->mHeader.SetIsVoid(inetBuf->lpcszHeader == nullptr);
if (inetBuf->lpcszHeader) {
ipcBuf->mHeader.Assign(inetBuf->lpcszHeader, inetBuf->dwHeadersLength);
}
ipcBuf->mHeaderTotal = inetBuf->dwHeadersTotal;
ipcBuf->mBuffer.SetIsVoid(inetBuf->lpvBuffer == nullptr);
if (inetBuf->lpvBuffer) {
ipcBuf->mBuffer.Assign(static_cast<char*>(inetBuf->lpvBuffer),
inetBuf->dwBufferLength);
}
ipcBuf->mBufferTotal = inetBuf->dwBufferTotal;
inetBuf = inetBuf->Next;
}
}
void
IPCInternetBuffers::CopyTo(LPINTERNET_BUFFERSA& aBufs) const
{
MOZ_ASSERT(!aBufs);
LPINTERNET_BUFFERSA lastBuf = nullptr;
for (size_t idx = 0; idx < mBuffers.Length(); ++idx) {
const Buffer& ipcBuf = mBuffers[idx];
LPINTERNET_BUFFERSA newBuf =
static_cast<LPINTERNET_BUFFERSA>(moz_xcalloc(1, sizeof(INTERNET_BUFFERSA)));
if (idx == 0) {
aBufs = newBuf;
} else {
MOZ_ASSERT(lastBuf);
lastBuf->Next = newBuf;
lastBuf = newBuf;
}
newBuf->dwStructSize = sizeof(INTERNET_BUFFERSA);
newBuf->dwHeadersTotal = ipcBuf.mHeaderTotal;
if (!ipcBuf.mHeader.IsVoid()) {
newBuf->lpcszHeader =
static_cast<LPCSTR>(moz_xmalloc(ipcBuf.mHeader.Length()));
memcpy(const_cast<char*>(newBuf->lpcszHeader), ipcBuf.mHeader.Data(),
ipcBuf.mHeader.Length());
newBuf->dwHeadersLength = ipcBuf.mHeader.Length();
}
newBuf->dwBufferTotal = ipcBuf.mBufferTotal;
if (!ipcBuf.mBuffer.IsVoid()) {
newBuf->lpvBuffer = moz_xmalloc(ipcBuf.mBuffer.Length());
memcpy(newBuf->lpvBuffer, ipcBuf.mBuffer.Data(),
ipcBuf.mBuffer.Length());
newBuf->dwBufferLength = ipcBuf.mBuffer.Length();
}
}
}
/* static */ void
IPCInternetBuffers::FreeBuffers(LPINTERNET_BUFFERSA& aBufs)
{
if (!aBufs) {
return;
}
while (aBufs) {
LPINTERNET_BUFFERSA temp = aBufs->Next;
free(const_cast<char*>(aBufs->lpcszHeader));
free(aBufs->lpvBuffer);
free(aBufs);
aBufs = temp;
}
}
void
IPCPrintDlg::CopyFrom(const LPPRINTDLGW& aDlg)
{
// DLP: Trouble -- my prior impl "worked" but didn't return anything
// AFAIR. So... ??? But it printed a page!!! How?!
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
void
IPCPrintDlg::CopyTo(LPPRINTDLGW& aDlg) const
{
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
} // namespace plugins
} // namespace mozilla
#endif // defined(XP_WIN)

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

@ -1,459 +0,0 @@
#ifndef dom_plugins_ipc_functionbrokeripcutils_h
#define dom_plugins_ipc_functionbrokeripcutils_h 1
#include "PluginMessageUtils.h"
#if defined(XP_WIN)
#define SECURITY_WIN32
#include <security.h>
#include <wininet.h>
#include <schannel.h>
#include <commdlg.h>
#endif // defined(XP_WIN)
namespace mozilla {
namespace plugins {
/**
* This enum represents all of the methods hooked by the main facility in BrokerClient.
* It is used to allow quick lookup in the sFunctionsToHook structure.
*/
enum FunctionHookId
{
#if defined(XP_WIN)
ID_GetWindowInfo = 0
, ID_GetKeyState
, ID_SetCursorPos
, ID_GetSaveFileNameW
, ID_GetOpenFileNameW
, ID_InternetOpenA
, ID_InternetConnectA
, ID_InternetCloseHandle
, ID_InternetQueryDataAvailable
, ID_InternetReadFile
, ID_InternetWriteFile
, ID_InternetSetOptionA
, ID_HttpAddRequestHeadersA
, ID_HttpOpenRequestA
, ID_HttpQueryInfoA
, ID_HttpSendRequestA
, ID_HttpSendRequestExA
, ID_InternetQueryOptionA
, ID_InternetErrorDlg
, ID_AcquireCredentialsHandleA
, ID_QueryCredentialsAttributesA
, ID_FreeCredentialsHandle
, ID_PrintDlgW
, ID_FunctionHookCount
#else // defined(XP_WIN)
ID_FunctionHookCount
#endif // defined(XP_WIN)
};
// Max number of bytes to show when logging a blob of raw memory
static const uint32_t MAX_BLOB_CHARS_TO_LOG = 12;
// Format strings for safe logging despite the fact that they are sometimes
// used as raw binary blobs.
inline nsCString FormatBlob(const nsACString& aParam)
{
if (aParam.IsVoid() || aParam.IsEmpty()) {
return nsCString(aParam.IsVoid() ? "<void>" : "<empty>");
}
nsCString str;
uint32_t totalLen = std::min(MAX_BLOB_CHARS_TO_LOG, aParam.Length());
// If we are printing only a portion of the string then follow it with ellipsis
const char* maybeEllipsis = (MAX_BLOB_CHARS_TO_LOG < aParam.Length()) ? "..." : "";
for (uint32_t idx = 0; idx < totalLen; ++idx) {
// Should be %02x but I've run into a AppendPrintf bug...
str.AppendPrintf("0x%2x ", aParam.Data()[idx] & 0xff);
}
str.AppendPrintf("%s | '", maybeEllipsis);
for (uint32_t idx = 0; idx < totalLen; ++idx) {
str.AppendPrintf("%c", (aParam.Data()[idx] > 0) ? aParam.Data()[idx] : '.');
}
str.AppendPrintf("'%s", maybeEllipsis);
return str;
}
#if defined(XP_WIN)
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
typedef nsTArray<nsCString> StringArray;
// IPC-capable version of the Windows OPENFILENAMEW struct.
typedef struct _OpenFileNameIPC
{
// Allocates memory for the strings in this object. This should usually
// be used with a zeroed out OPENFILENAMEW structure.
void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const;
static void FreeOfnStrings(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
bool operator==(const _OpenFileNameIPC& o) const
{
return (o.mHwndOwner == mHwndOwner) &&
(o.mFilter == mFilter) &&
(o.mHasFilter == mHasFilter) &&
(o.mCustomFilterIn == mCustomFilterIn) &&
(o.mHasCustomFilter == mHasCustomFilter) &&
(o.mNMaxCustFilterOut == mNMaxCustFilterOut) &&
(o.mFilterIndex == mFilterIndex) &&
(o.mFile == mFile) &&
(o.mNMaxFile == mNMaxFile) &&
(o.mNMaxFileTitle == mNMaxFileTitle) &&
(o.mInitialDir == mInitialDir) &&
(o.mHasInitialDir == mHasInitialDir) &&
(o.mTitle == mTitle) &&
(o.mHasTitle == mHasTitle) &&
(o.mFlags == mFlags) &&
(o.mDefExt == mDefExt) &&
(o.mHasDefExt == mHasDefExt) &&
(o.mFlagsEx == mFlagsEx);
}
NativeWindowHandle mHwndOwner;
std::wstring mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true
bool mHasFilter;
std::wstring mCustomFilterIn;
bool mHasCustomFilter;
uint32_t mNMaxCustFilterOut;
uint32_t mFilterIndex;
std::wstring mFile;
uint32_t mNMaxFile;
uint32_t mNMaxFileTitle;
std::wstring mInitialDir;
bool mHasInitialDir;
std::wstring mTitle;
bool mHasTitle;
uint32_t mFlags;
std::wstring mDefExt;
bool mHasDefExt;
uint32_t mFlagsEx;
} OpenFileNameIPC;
// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW
// parameter. This represents those values so that they can be returned via IPC.
typedef struct _OpenFileNameRetIPC
{
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
bool operator==(const _OpenFileNameRetIPC& o) const
{
return (o.mCustomFilterOut == mCustomFilterOut) &&
(o.mFile == mFile) &&
(o.mFileTitle == mFileTitle) &&
(o.mFileOffset == mFileOffset) &&
(o.mFileExtension == mFileExtension);
}
std::wstring mCustomFilterOut;
std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0")
std::wstring mFileTitle;
uint16_t mFileOffset;
uint16_t mFileExtension;
} OpenFileNameRetIPC;
typedef struct _IPCSchannelCred
{
void CopyFrom(const PSCHANNEL_CRED& aSCred);
void CopyTo(PSCHANNEL_CRED& aSCred) const;
bool operator==(const _IPCSchannelCred& o) const
{
return (o.mEnabledProtocols == mEnabledProtocols) &&
(o.mMinStrength == mMinStrength) &&
(o.mMaxStrength == mMaxStrength) &&
(o.mFlags == mFlags);
}
DWORD mEnabledProtocols;
DWORD mMinStrength;
DWORD mMaxStrength;
DWORD mFlags;
} IPCSchannelCred;
typedef struct _IPCInternetBuffers
{
void CopyFrom(const LPINTERNET_BUFFERSA& aBufs);
void CopyTo(LPINTERNET_BUFFERSA& aBufs) const;
bool operator==(const _IPCInternetBuffers& o) const
{
return o.mBuffers == mBuffers;
}
static void FreeBuffers(LPINTERNET_BUFFERSA& aBufs);
struct Buffer
{
nsCString mHeader;
uint32_t mHeaderTotal;
nsCString mBuffer;
uint32_t mBufferTotal;
bool operator==(const Buffer& o) const
{
return (o.mHeader == mHeader) && (o.mHeaderTotal == mHeaderTotal) &&
(o.mBuffer == mBuffer) && (o.mBufferTotal == mBufferTotal);
}
};
nsTArray<Buffer> mBuffers;
} IPCInternetBuffers;
typedef struct _IPCPrintDlg
{
void CopyFrom(const LPPRINTDLGW& aDlg);
void CopyTo(LPPRINTDLGW& aDlg) const;
bool operator==(const _IPCPrintDlg& o) const
{
MOZ_ASSERT_UNREACHABLE("DLP: TODO:"); return false;
}
} IPCPrintDlg;
#endif // defined(XP_WIN)
} // namespace plugins
} // namespace mozilla
namespace IPC {
using mozilla::plugins::FunctionHookId;
#if defined(XP_WIN)
using mozilla::plugins::OpenFileNameIPC;
using mozilla::plugins::OpenFileNameRetIPC;
using mozilla::plugins::IPCSchannelCred;
using mozilla::plugins::IPCInternetBuffers;
using mozilla::plugins::IPCPrintDlg;
using mozilla::plugins::NativeWindowHandle;
using mozilla::plugins::StringArray;
template <>
struct ParamTraits<OpenFileNameIPC>
{
typedef OpenFileNameIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHwndOwner);
WriteParam(aMsg, aParam.mFilter);
WriteParam(aMsg, aParam.mHasFilter);
WriteParam(aMsg, aParam.mCustomFilterIn);
WriteParam(aMsg, aParam.mHasCustomFilter);
WriteParam(aMsg, aParam.mNMaxCustFilterOut);
WriteParam(aMsg, aParam.mFilterIndex);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mNMaxFile);
WriteParam(aMsg, aParam.mNMaxFileTitle);
WriteParam(aMsg, aParam.mInitialDir);
WriteParam(aMsg, aParam.mHasInitialDir);
WriteParam(aMsg, aParam.mTitle);
WriteParam(aMsg, aParam.mHasTitle);
WriteParam(aMsg, aParam.mFlags);
WriteParam(aMsg, aParam.mDefExt);
WriteParam(aMsg, aParam.mHasDefExt);
WriteParam(aMsg, aParam.mFlagsEx);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) &&
ReadParam(aMsg, aIter, &aResult->mFilter) &&
ReadParam(aMsg, aIter, &aResult->mHasFilter) &&
ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) &&
ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) &&
ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFilterIndex) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mHasInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mTitle) &&
ReadParam(aMsg, aIter, &aResult->mHasTitle) &&
ReadParam(aMsg, aIter, &aResult->mFlags) &&
ReadParam(aMsg, aIter, &aResult->mDefExt) &&
ReadParam(aMsg, aIter, &aResult->mHasDefExt) &&
ReadParam(aMsg, aIter, &aResult->mFlagsEx)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %S]", aParam.mFilter.c_str(),
aParam.mCustomFilterIn.c_str(), aParam.mFile.c_str(),
aParam.mTitle.c_str()));
}
};
template <>
struct ParamTraits<OpenFileNameRetIPC>
{
typedef OpenFileNameRetIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mCustomFilterOut);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mFileTitle);
WriteParam(aMsg, aParam.mFileOffset);
WriteParam(aMsg, aParam.mFileExtension);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mFileOffset) &&
ReadParam(aMsg, aIter, &aResult->mFileExtension)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %d, %d]", aParam.mCustomFilterOut.c_str(),
aParam.mFile.c_str(), aParam.mFileTitle.c_str(),
aParam.mFileOffset, aParam.mFileExtension));
}
};
template <>
struct ParamTraits<mozilla::plugins::GetFileNameFunc> :
public ContiguousEnumSerializerInclusive<mozilla::plugins::GetFileNameFunc,
mozilla::plugins::OPEN_FUNC,
mozilla::plugins::SAVE_FUNC>
{};
template <>
struct ParamTraits<IPCSchannelCred>
{
typedef mozilla::plugins::IPCSchannelCred paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, static_cast<uint32_t>(aParam.mEnabledProtocols));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mMinStrength));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mMaxStrength));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mFlags));
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
uint32_t proto, minStr, maxStr, flags;
if (!ReadParam(aMsg, aIter, &proto) ||
!ReadParam(aMsg, aIter, &minStr) ||
!ReadParam(aMsg, aIter, &maxStr) ||
!ReadParam(aMsg, aIter, &flags)) {
return false;
}
aResult->mEnabledProtocols = proto;
aResult->mMinStrength = minStr;
aResult->mMaxStrength = maxStr;
aResult->mFlags = flags;
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%d,%d,%d,%d]",
aParam.mEnabledProtocols, aParam.mMinStrength,
aParam.mMaxStrength, aParam.mFlags));
}
};
template <>
struct ParamTraits<IPCInternetBuffers::Buffer>
{
typedef mozilla::plugins::IPCInternetBuffers::Buffer paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHeader);
WriteParam(aMsg, aParam.mHeaderTotal);
WriteParam(aMsg, aParam.mBuffer);
WriteParam(aMsg, aParam.mBufferTotal);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mHeader) &&
ReadParam(aMsg, aIter, &aResult->mHeaderTotal) &&
ReadParam(aMsg, aIter, &aResult->mBuffer) &&
ReadParam(aMsg, aIter, &aResult->mBufferTotal);
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
nsCString head = mozilla::plugins::FormatBlob(aParam.mHeader);
nsCString buffer = mozilla::plugins::FormatBlob(aParam.mBuffer);
std::string msg = StringPrintf("[%s, %d, %s, %d]",
head.Data(), aParam.mHeaderTotal,
buffer.Data(), aParam.mBufferTotal);
aLog->append(msg.begin(), msg.end());
}
};
template <>
struct ParamTraits<IPCInternetBuffers>
{
typedef mozilla::plugins::IPCInternetBuffers paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mBuffers);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mBuffers);
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
ParamTraits<nsTArray<IPCInternetBuffers::Buffer>>::Log(aParam.mBuffers, aLog);
}
};
template <>
struct ParamTraits<IPCPrintDlg>
{
typedef mozilla::plugins::IPCPrintDlg paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
};
#endif // defined(XP_WIN)
template <>
struct ParamTraits<FunctionHookId> :
public ContiguousEnumSerializer<FunctionHookId,
static_cast<FunctionHookId>(0),
FunctionHookId::ID_FunctionHookCount>
{};
} // namespace IPC
#endif /* dom_plugins_ipc_functionbrokeripcutils_h */

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

@ -1,152 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerParent.h"
#include "FunctionBroker.h"
#include "FunctionBrokerThread.h"
namespace mozilla {
namespace plugins {
#if defined(XP_WIN)
UlongPairToIdMap sPairToIdMap;
IdToUlongPairMap sIdToPairMap;
PtrToIdMap sPtrToIdMap;
IdToPtrMap sIdToPtrMap;
#endif // defined(XP_WIN)
/* static */ FunctionBrokerParent*
FunctionBrokerParent::Create(Endpoint<PFunctionBrokerParent>&& aParentEnd)
{
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
if (!thread) {
return nullptr;
}
// We get the FunctionHooks so that they are created here, not on the
// message thread.
FunctionHook::GetHooks();
return new FunctionBrokerParent(thread, Move(aParentEnd));
}
FunctionBrokerParent::FunctionBrokerParent(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerParent>&& aParentEnd) :
mThread(aThread)
, mMonitor("FunctionBrokerParent Lock")
, mShutdownDone(false)
{
MOZ_ASSERT(mThread);
mThread->Dispatch(NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerParent>&&>(
"FunctionBrokerParent::Bind", this, &FunctionBrokerParent::Bind, Move(aParentEnd)));
}
FunctionBrokerParent::~FunctionBrokerParent()
{
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
// Clean up any file permissions that we granted to the child process.
MOZ_RELEASE_ASSERT(NS_IsMainThread());
RemovePermissionsForProcess(OtherPid());
#endif
}
void
FunctionBrokerParent::Bind(Endpoint<PFunctionBrokerParent>&& aEnd)
{
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
DebugOnly<bool> ok = aEnd.Bind(this);
MOZ_ASSERT(ok);
}
void
FunctionBrokerParent::ShutdownOnBrokerThread()
{
MOZ_ASSERT(mThread->IsOnThread());
Close();
// Notify waiting thread that we are done.
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
mMonitor.Notify();
}
void
FunctionBrokerParent::Destroy(FunctionBrokerParent* aInst)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aInst);
{
// Hold the lock while we destroy the actor on the broker thread.
MonitorAutoLock lock(aInst->mMonitor);
aInst->mThread->Dispatch(NewNonOwningRunnableMethod(
"FunctionBrokerParent::ShutdownOnBrokerThread", aInst,
&FunctionBrokerParent::ShutdownOnBrokerThread));
// Wait for broker thread to complete destruction.
while (!aInst->mShutdownDone) {
aInst->mMonitor.Wait();
}
}
delete aInst;
}
void
FunctionBrokerParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
}
mozilla::ipc::IPCResult
FunctionBrokerParent::RecvBrokerFunction(const FunctionHookId &aFunctionId,
const IpdlTuple &aInTuple,
IpdlTuple *aOutTuple)
{
#if defined(XP_WIN)
MOZ_ASSERT(mThread->IsOnThread());
if (RunBrokeredFunction(OtherPid(), aFunctionId, aInTuple, aOutTuple)) {
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
#else
MOZ_ASSERT_UNREACHABLE("BrokerFunction is currently only implemented on Windows.");
return IPC_FAIL_NO_REASON(this);
#endif
}
// static
bool
FunctionBrokerParent::RunBrokeredFunction(base::ProcessId aClientId,
const FunctionHookId &aFunctionId,
const IPC::IpdlTuple &aInTuple,
IPC::IpdlTuple *aOutTuple)
{
if ((size_t)aFunctionId >= FunctionHook::GetHooks()->Length()) {
MOZ_ASSERT_UNREACHABLE("Invalid function ID");
return false;
}
FunctionHook* hook = FunctionHook::GetHooks()->ElementAt(aFunctionId);
MOZ_ASSERT(hook->FunctionId() == aFunctionId);
return hook->RunOriginalFunction(aClientId, aInTuple, aOutTuple);
}
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions FunctionBrokerParent::sSandboxPermissions;
// static
void
FunctionBrokerParent::RemovePermissionsForProcess(base::ProcessId aClientId)
{
sSandboxPermissions.RemovePermissionsForProcess(aClientId);
}
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
} // namespace plugins
} // namespace mozilla

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

@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerparent_h
#define mozilla_plugins_functionbrokerparent_h
#include "mozilla/plugins/PFunctionBrokerParent.h"
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
#include "sandboxPermissions.h"
#endif
namespace mozilla {
namespace plugins {
class FunctionBrokerThread;
/**
* Top-level actor run on the process to which we broker calls from sandboxed
* plugin processes.
*/
class FunctionBrokerParent : public PFunctionBrokerParent
{
public:
static FunctionBrokerParent* Create(Endpoint<PFunctionBrokerParent>&& aParentEnd);
static void Destroy(FunctionBrokerParent* aInst);
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult
RecvBrokerFunction(const FunctionHookId &aFunctionId, const IpdlTuple &aInTuple,
IpdlTuple *aOutTuple) override;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
static mozilla::SandboxPermissions*
GetSandboxPermissions() { return &sSandboxPermissions; }
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
private:
explicit FunctionBrokerParent(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerParent>&& aParentEnd);
~FunctionBrokerParent();
void ShutdownOnBrokerThread();
void Bind(Endpoint<PFunctionBrokerParent>&& aEnd);
static bool RunBrokeredFunction(base::ProcessId aClientId,
const FunctionHookId &aFunctionId,
const IPC::IpdlTuple &aInTuple,
IPC::IpdlTuple *aOutTuple);
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
static void RemovePermissionsForProcess(base::ProcessId aClientId);
static mozilla::SandboxPermissions sSandboxPermissions;
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
nsAutoPtr<FunctionBrokerThread> mThread;
Monitor mMonitor;
bool mShutdownDone;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerparent_hk

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

@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerthread_h
#define mozilla_plugins_functionbrokerthread_h
#include "nsThreadManager.h"
namespace mozilla {
namespace plugins {
class FunctionBrokerThread
{
public:
void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
{
mThread->Dispatch(Move(aRunnable), nsIEventTarget::NS_DISPATCH_NORMAL);
}
bool IsOnThread()
{
bool on;
return NS_SUCCEEDED(mThread->IsOnCurrentThread(&on)) && on;
}
static FunctionBrokerThread* Create()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThread> thread;
if (NS_FAILED(NS_NewNamedThread("Function Broker", getter_AddRefs(thread)))) {
return nullptr;
}
return new FunctionBrokerThread(thread);
}
~FunctionBrokerThread()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mThread->Shutdown();
}
private:
explicit FunctionBrokerThread(nsIThread* aThread) : mThread(aThread)
{
MOZ_ASSERT(mThread);
}
nsCOMPtr<nsIThread> mThread;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerthread_h

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

@ -1,332 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionHook.h"
#include "FunctionBroker.h"
#include "nsClassHashtable.h"
#include "mozilla/ClearOnShutdown.h"
#if defined(XP_WIN)
#include <shlobj.h>
#endif
namespace mozilla {
namespace plugins {
StaticAutoPtr<FunctionHookArray> FunctionHook::sFunctionHooks;
bool AlwaysHook(int) { return true; }
FunctionHookArray*
FunctionHook::GetHooks()
{
if (sFunctionHooks) {
return sFunctionHooks;
}
// sFunctionHooks is the StaticAutoPtr to the singleton array of FunctionHook
// objects. We free it by clearing the StaticAutoPtr on shutdown.
sFunctionHooks = new FunctionHookArray();
ClearOnShutdown(&sFunctionHooks);
sFunctionHooks->SetLength(ID_FunctionHookCount);
AddFunctionHooks(*sFunctionHooks);
AddBrokeredFunctionHooks(*sFunctionHooks);
return sFunctionHooks;
}
void
FunctionHook::HookFunctions(int aQuirks)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
FunctionHookArray* hooks = FunctionHook::GetHooks();
MOZ_ASSERT(hooks);
for(size_t i=0; i < hooks->Length(); ++i) {
FunctionHook* mhb = hooks->ElementAt(i);
// Check that the FunctionHook array is in the same order as the
// FunctionHookId enum.
MOZ_ASSERT((size_t)mhb->FunctionId() == i);
mhb->Register(aQuirks);
}
}
#if defined(XP_WIN)
// This cache is created when a DLL is registered with a FunctionHook.
// It is cleared on a call to ClearDllInterceptorCache(). It
// must be freed before exit to avoid leaks.
typedef nsClassHashtable<nsCStringHashKey, WindowsDllInterceptor> DllInterceptors;
DllInterceptors* sDllInterceptorCache = nullptr;
WindowsDllInterceptor*
FunctionHook::GetDllInterceptorFor(const char* aModuleName)
{
if (!sDllInterceptorCache) {
sDllInterceptorCache = new DllInterceptors();
}
WindowsDllInterceptor* ret =
sDllInterceptorCache->LookupOrAdd(nsCString(aModuleName), aModuleName);
MOZ_ASSERT(ret);
return ret;
}
void
FunctionHook::ClearDllInterceptorCache()
{
delete sDllInterceptorCache;
sDllInterceptorCache = nullptr;
}
/* GetWindowInfo */
typedef BasicFunctionHook<ID_GetWindowInfo, decltype(GetWindowInfo)> GetWindowInfoFH;
template<>
ShouldHookFunc* const
GetWindowInfoFH::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_GETWINDOWINFO>;
static const wchar_t * kMozillaWindowClass = L"MozillaWindowClass";
static HWND sBrowserHwnd = nullptr;
BOOL WINAPI
GetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
{
if (!pwi) {
return FALSE;
}
MOZ_ASSERT(ID_GetWindowInfo < FunctionHook::GetHooks()->Length());
GetWindowInfoFH* functionHook =
static_cast<GetWindowInfoFH*>(FunctionHook::GetHooks()->ElementAt(ID_GetWindowInfo));
if (!functionHook->OriginalFunction()) {
NS_ASSERTION(FALSE, "Something is horribly wrong in PHGetWindowInfoHook!");
return FALSE;
}
if (!sBrowserHwnd) {
wchar_t szClass[20];
// GetClassNameW returns the length it copied w/o null terminator.
// Therefore, if the name and null-terminator fit then it returns a
// value less than the buffer's length.
int nameLen = GetClassNameW(hWnd, szClass, ArrayLength(szClass));
if ((nameLen < (int)ArrayLength(szClass)) &&
!wcscmp(szClass, kMozillaWindowClass)) {
sBrowserHwnd = hWnd;
}
}
// Oddity: flash does strange rect comparisons for mouse input destined for
// it's internal settings window. Post removing sub widgets for tabs, touch
// this up so they get the rect they expect.
// XXX potentially tie this to a specific major version?
typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
GetWindowInfoPtr gwiFunc =
static_cast<GetWindowInfoPtr>(functionHook->OriginalFunction());
BOOL result = gwiFunc(hWnd, pwi);
if (sBrowserHwnd && sBrowserHwnd == hWnd) {
pwi->rcWindow = pwi->rcClient;
}
return result;
}
/* PrintDlgW */
typedef BasicFunctionHook<ID_PrintDlgW, decltype(PrintDlgW)> PrintDlgWFH;
template<>
ShouldHookFunc* const
PrintDlgWFH::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_PRINTDLGW>;
BOOL WINAPI PrintDlgWHook(LPPRINTDLGW aDlg)
{
// Zero out the HWND supplied by the plugin. We are sacrificing window
// parentage for the ability to run in the NPAPI sandbox.
HWND hwnd = aDlg->hwndOwner;
aDlg->hwndOwner = 0;
MOZ_ASSERT(ID_PrintDlgW < FunctionHook::GetHooks()->Length());
PrintDlgWFH* functionHook =
static_cast<PrintDlgWFH*>(FunctionHook::GetHooks()->ElementAt(ID_PrintDlgW));
MOZ_ASSERT(functionHook);
BOOL ret = functionHook->OriginalFunction()(aDlg);
aDlg->hwndOwner = hwnd;
return ret;
}
// Hooking CreateFileW for protected-mode magic
static WindowsDllInterceptor sKernel32Intercept;
typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR aFname, DWORD aAccess,
DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate);
static CreateFileWPtr sCreateFileWStub = nullptr;
typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR aFname, DWORD aAccess,
DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate);
static CreateFileAPtr sCreateFileAStub = nullptr;
// Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
// CreateFileW from CreateFileA.
// So we hook CreateFileA too to use CreateFileW hook.
static HANDLE WINAPI
CreateFileAHookFn(LPCSTR aFname, DWORD aAccess, DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity, DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate)
{
while (true) { // goto out
// Our hook is for mms.cfg into \Windows\System32\Macromed\Flash
// We don't require supporting too long path.
WCHAR unicodeName[MAX_PATH];
size_t len = strlen(aFname);
if (len >= MAX_PATH) {
break;
}
// We call to CreateFileW for workaround of Windows 8 RTM
int newLen = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, aFname,
len, unicodeName, MAX_PATH);
if (newLen == 0 || newLen >= MAX_PATH) {
break;
}
unicodeName[newLen] = '\0';
return CreateFileW(unicodeName, aAccess, aShare, aSecurity, aCreation, aFlags, aFTemplate);
}
return sCreateFileAStub(aFname, aAccess, aShare, aSecurity, aCreation, aFlags,
aFTemplate);
}
static bool
GetLocalLowTempPath(size_t aLen, LPWSTR aPath)
{
NS_NAMED_LITERAL_STRING(tempname, "\\Temp");
LPWSTR path;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0,
nullptr, &path))) {
if (wcslen(path) + tempname.Length() < aLen) {
wcscpy(aPath, path);
wcscat(aPath, tempname.get());
CoTaskMemFree(path);
return true;
}
CoTaskMemFree(path);
}
// XP doesn't support SHGetKnownFolderPath and LocalLow
if (!GetTempPathW(aLen, aPath)) {
return false;
}
return true;
}
HANDLE WINAPI
CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity, DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate)
{
static const WCHAR kConfigFile[] = L"mms.cfg";
static const size_t kConfigLength = ArrayLength(kConfigFile) - 1;
while (true) { // goto out, in sheep's clothing
size_t len = wcslen(aFname);
if (len < kConfigLength) {
break;
}
if (wcscmp(aFname + len - kConfigLength, kConfigFile) != 0) {
break;
}
// This is the config file we want to rewrite
WCHAR tempPath[MAX_PATH+1];
if (GetLocalLowTempPath(MAX_PATH, tempPath) == 0) {
break;
}
WCHAR tempFile[MAX_PATH+1];
if (GetTempFileNameW(tempPath, L"fx", 0, tempFile) == 0) {
break;
}
HANDLE replacement =
sCreateFileWStub(tempFile, GENERIC_READ | GENERIC_WRITE, aShare,
aSecurity, TRUNCATE_EXISTING,
FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (replacement == INVALID_HANDLE_VALUE) {
break;
}
HANDLE original = sCreateFileWStub(aFname, aAccess, aShare, aSecurity,
aCreation, aFlags, aFTemplate);
if (original != INVALID_HANDLE_VALUE) {
// copy original to replacement
static const size_t kBufferSize = 1024;
char buffer[kBufferSize];
DWORD bytes;
while (ReadFile(original, buffer, kBufferSize, &bytes, NULL)) {
if (bytes == 0) {
break;
}
DWORD wbytes;
WriteFile(replacement, buffer, bytes, &wbytes, NULL);
if (bytes < kBufferSize) {
break;
}
}
CloseHandle(original);
}
static const char kSettingString[] = "\nProtectedMode=0\n";
DWORD wbytes;
WriteFile(replacement, static_cast<const void*>(kSettingString),
sizeof(kSettingString) - 1, &wbytes, NULL);
SetFilePointer(replacement, 0, NULL, FILE_BEGIN);
return replacement;
}
return sCreateFileWStub(aFname, aAccess, aShare, aSecurity, aCreation, aFlags,
aFTemplate);
}
void FunctionHook::HookProtectedMode()
{
// Legacy code. Uses the nsWindowsDLLInterceptor directly instead of
// using the FunctionHook
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
WindowsDllInterceptor k32Intercept("kernel32.dll");
k32Intercept.AddHook("CreateFileW",
reinterpret_cast<intptr_t>(CreateFileWHookFn),
(void**) &sCreateFileWStub);
k32Intercept.AddHook("CreateFileA",
reinterpret_cast<intptr_t>(CreateFileAHookFn),
(void**) &sCreateFileAStub);
}
#endif // defined(XP_WIN)
#define FUN_HOOK(x) static_cast<FunctionHook*>(x)
void
FunctionHook::AddFunctionHooks(FunctionHookArray& aHooks)
{
// We transfer ownership of the FunctionHook objects to the array.
#if defined(XP_WIN)
aHooks[ID_GetWindowInfo] =
FUN_HOOK(new GetWindowInfoFH("user32.dll", "GetWindowInfo",
&GetWindowInfo, &GetWindowInfoHook));
aHooks[ID_PrintDlgW] =
FUN_HOOK(new PrintDlgWFH("comdlg32.dll", "PrintDlgW", &PrintDlgW,
PrintDlgWHook));
#endif // defined(XP_WIN)
}
#undef FUN_HOOK
} // namespace plugins
} // namespace mozilla

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

@ -1,183 +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 dom_plugins_ipc_functionhook_h
#define dom_plugins_ipc_functionhook_h 1
#include "IpdlTuple.h"
#include "base/process.h"
#if defined(XP_WIN)
#include "nsWindowsDllInterceptor.h"
#endif
namespace mozilla {
namespace plugins {
// "PluginHooks" logging helpers
extern mozilla::LazyLogModule sPluginHooksLog;
#define HOOK_LOG(lvl, msg) MOZ_LOG(mozilla::plugins::sPluginHooksLog, lvl, msg);
inline const char *SuccessMsg(bool aVal) { return aVal ? "succeeded" : "failed"; }
class FunctionHook;
class FunctionHookArray;
class FunctionHook
{
public:
virtual ~FunctionHook() {}
virtual FunctionHookId FunctionId() const = 0;
/**
* Register to hook the function represented by this class.
* Returns false if we should have hooked but didn't.
*/
virtual bool Register(int aQuirks) = 0;
/**
* Run the original function with parameters stored in a tuple.
* This is only supported on server-side and for auto-brokered methods.
*/
virtual bool RunOriginalFunction(base::ProcessId aClientId,
const IPC::IpdlTuple &aInTuple,
IPC::IpdlTuple *aOutTuple) const = 0;
/**
* Hook the Win32 methods needed by the plugin process.
*/
static void HookFunctions(int aQuirks);
static FunctionHookArray* GetHooks();
#if defined(XP_WIN)
/**
* Special handler for hooking some kernel32.dll methods that we use to
* disable Flash protected mode.
*/
static void HookProtectedMode();
/**
* Get the WindowsDllInterceptor for the given module. Creates a cache of
* WindowsDllInterceptors by name.
*/
static WindowsDllInterceptor* GetDllInterceptorFor(const char* aModuleName);
/**
* Must be called to clear the cache created by calls to GetDllInterceptorFor.
*/
static void ClearDllInterceptorCache();
#endif // defined(XP_WIN)
private:
static StaticAutoPtr<FunctionHookArray> sFunctionHooks;
static void AddFunctionHooks(FunctionHookArray& aHooks);
};
// The FunctionHookArray deletes its FunctionHook objects when freed.
class FunctionHookArray : public nsTArray<FunctionHook*> {
public:
~FunctionHookArray()
{
for (uint32_t idx = 0; idx < Length(); ++idx) {
FunctionHook* elt = ElementAt(idx);
MOZ_ASSERT(elt);
delete elt;
}
}
};
// Type of function that returns true if a function should be hooked according to quirks.
typedef bool(ShouldHookFunc)(int aQuirks);
template<FunctionHookId functionId, typename FunctionType>
class BasicFunctionHook : public FunctionHook
{
public:
BasicFunctionHook(const char* aModuleName,
const char* aFunctionName, FunctionType* aOldFunction,
FunctionType* aNewFunction) :
mOldFunction(aOldFunction), mIsHooked(false), mModuleName(aModuleName),
mFunctionName(aFunctionName), mNewFunction(aNewFunction)
{
MOZ_ASSERT(mOldFunction);
MOZ_ASSERT(mNewFunction);
}
/**
* Hooks the function if we haven't already and if ShouldHook() says to.
*/
bool Register(int aQuirks) override;
/**
* Can be specialized to perform "extra" operations when running the
* function on the server side.
*/
bool RunOriginalFunction(base::ProcessId aClientId,
const IPC::IpdlTuple &aInTuple,
IPC::IpdlTuple *aOutTuple) const override { return false; }
FunctionHookId FunctionId() const override { return functionId; }
FunctionType* OriginalFunction() const { return mOldFunction; }
protected:
// Once the function is hooked, this field will take the value of a pointer to
// a function that performs the old behavior. Before that, it is a pointer to
// the original function.
FunctionType* mOldFunction;
// True if we have already hooked the function.
bool mIsHooked;
// The name of the module containing the function to hook. E.g. "user32.dll".
const nsCString mModuleName;
// The name of the function in the module.
const nsCString mFunctionName;
// The function that we should replace functionName with. The signature of
// newFunction must match that of functionName.
FunctionType* const mNewFunction;
static ShouldHookFunc* const mShouldHook;
};
// Default behavior is to hook every registered function.
extern bool AlwaysHook(int);
template<FunctionHookId functionId, typename FunctionType>
ShouldHookFunc* const BasicFunctionHook<functionId, FunctionType>::mShouldHook = AlwaysHook;
template <FunctionHookId functionId, typename FunctionType>
bool
BasicFunctionHook<functionId, FunctionType>::Register(int aQuirks)
{
MOZ_RELEASE_ASSERT(XRE_IsPluginProcess());
// If we have already hooked or if quirks tell us not to then don't hook.
if (mIsHooked || !mShouldHook(aQuirks)) {
return true;
}
#if defined(XP_WIN)
WindowsDllInterceptor* dllInterceptor =
FunctionHook::GetDllInterceptorFor(mModuleName.Data());
if (!dllInterceptor) {
return false;
}
mIsHooked =
dllInterceptor->AddHook(mFunctionName.Data(), reinterpret_cast<intptr_t>(mNewFunction),
reinterpret_cast<void**>(&mOldFunction));
#endif
HOOK_LOG(LogLevel::Debug,
("Registering to intercept function '%s' : '%s'", mFunctionName.Data(),
SuccessMsg(mIsHooked)));
return mIsHooked;
}
}
}
#endif // dom_plugins_ipc_functionhook_h

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

@ -1,184 +0,0 @@
#ifndef dom_plugins_ipc_ipdltuple_h
#define dom_plugins_ipc_ipdltuple_h
#include "mozilla/plugins/FunctionBrokerIPCUtils.h"
#include "mozilla/Variant.h"
namespace mozilla {
namespace plugins {
/**
* IpdlTuple is used by automatic function brokering to pass parameter
* lists for brokered functions. It supports a limited set of types
* (see IpdlTuple::IpdlTupleElement).
*/
class IpdlTuple
{
public:
uint32_t NumElements() const { return mTupleElements.Length(); }
template<typename EltType>
EltType* Element(uint32_t index)
{
if ((index >= mTupleElements.Length()) ||
!mTupleElements[index].GetVariant().is<EltType>()) {
return nullptr;
}
return &mTupleElements[index].GetVariant().as<EltType>();
}
template<typename EltType>
const EltType* Element(uint32_t index) const
{
return const_cast<IpdlTuple*>(this)->Element<EltType>(index);
}
template <typename EltType>
void AddElement(const EltType& aElt)
{
IpdlTupleElement* newEntry = mTupleElements.AppendElement();
newEntry->Set(aElt);
}
private:
struct InvalidType {};
// Like Variant but with a default constructor.
template <typename ... Types>
struct MaybeVariant
{
public:
MaybeVariant() : mValue(InvalidType()) {}
MaybeVariant(MaybeVariant&& o) : mValue(Move(o.mValue)) {}
template <typename Param> void Set(const Param& aParam)
{
mValue = mozilla::AsVariant(aParam);
}
typedef mozilla::Variant<InvalidType, Types...> MaybeVariantType;
MaybeVariantType& GetVariant() { return mValue; }
const MaybeVariantType& GetVariant() const { return mValue; }
private:
MaybeVariantType mValue;
};
#if defined(XP_WIN)
typedef MaybeVariant<int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,
int64_t,uint64_t,nsCString,bool,OpenFileNameIPC,
OpenFileNameRetIPC,NativeWindowHandle,
IPCSchannelCred,IPCInternetBuffers,StringArray,
IPCPrintDlg> IpdlTupleElement;
#else
typedef MaybeVariant<int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,
int64_t,uint64_t,nsCString,bool> IpdlTupleElement;
#endif // defined(XP_WIN)
friend struct IPC::ParamTraits<IpdlTuple>;
friend struct IPC::ParamTraits<IpdlTuple::IpdlTupleElement>;
friend struct IPC::ParamTraits<IpdlTuple::InvalidType>;
nsTArray<IpdlTupleElement> mTupleElements;
};
template <> template<>
inline void IpdlTuple::IpdlTupleElement::Set<nsDependentCSubstring>(const nsDependentCSubstring& aParam)
{
mValue = MaybeVariantType(mozilla::VariantType<nsCString>(), aParam);
}
} // namespace plugins
} // namespace mozilla
namespace IPC {
using namespace mozilla::plugins;
template <>
struct ParamTraits<IpdlTuple>
{
typedef IpdlTuple paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mTupleElements);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam)
{
return ReadParam(aMsg, aIter, &aParam->mTupleElements);
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
LogParam(aParam.mTupleElements, aLog);
}
};
template<>
struct ParamTraits<IpdlTuple::IpdlTupleElement>
{
typedef IpdlTuple::IpdlTupleElement paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
MOZ_RELEASE_ASSERT(!aParam.GetVariant().is<IpdlTuple::InvalidType>());
WriteParam(aMsg, aParam.GetVariant());
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam)
{
bool ret = ReadParam(aMsg, aIter, &aParam->GetVariant());
MOZ_RELEASE_ASSERT(!aParam->GetVariant().is<IpdlTuple::InvalidType>());
return ret;
}
struct LogMatcher
{
explicit LogMatcher(std::wstring* aLog) : mLog(aLog) {}
template <typename EntryType>
void match(const EntryType& aParam)
{
LogParam(aParam, mLog);
}
private:
std::wstring* mLog;
};
static void Log(const paramType& aParam, std::wstring* aLog)
{
aParam.GetVariant().match(LogMatcher(aLog));
}
};
template<>
struct ParamTraits<IpdlTuple::InvalidType>
{
typedef IpdlTuple::InvalidType paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
MOZ_ASSERT_UNREACHABLE("Attempt to serialize an invalid tuple element");
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam)
{
MOZ_ASSERT_UNREACHABLE("Attempt to deserialize an invalid tuple element");
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(L"<Invalid Tuple Entry>");
}
};
} // namespace IPC
#endif /* dom_plugins_ipc_ipdltuple_h */

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

@ -1,23 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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/. */
using mozilla::plugins::FunctionHookId from "mozilla/plugins/FunctionBrokerIPCUtils.h";
using IPC::IpdlTuple from "mozilla/plugins/IpdlTuple.h";
namespace mozilla {
namespace plugins {
/**
* Top-level actor that brokers functions for the client process.
*/
sync protocol PFunctionBroker
{
parent:
sync BrokerFunction(FunctionHookId aFunctionId, IpdlTuple aFunctionParams)
returns (IpdlTuple aFunctionRet);
};
} // namespace plugins
} // namespace mozilla

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

@ -7,7 +7,6 @@ include protocol PPluginInstance;
include protocol PPluginScriptableObject;
include protocol PContent;
include protocol PProfiler;
include protocol PFunctionBroker;
using NPError from "npapi.h";
using NPNVariable from "npapi.h";
@ -15,6 +14,9 @@ using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
using class mac_plugin_interposing::NSCursorInfo from "mozilla/plugins/PluginMessageUtils.h";
using struct nsID from "nsID.h";
using struct mozilla::plugins::NPAudioDeviceChangeDetailsIPC from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::GetFileNameFunc from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::OpenFileNameIPC from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::OpenFileNameRetIPC from "mozilla/plugins/PluginMessageUtils.h";
namespace mozilla {
namespace plugins {
@ -96,8 +98,6 @@ child:
async InitPluginModuleChild(Endpoint<PPluginModuleChild> endpoint);
async InitPluginFunctionBroker(Endpoint<PFunctionBrokerChild> endpoint);
parent:
/**
* This message is only used on X11 platforms.
@ -145,8 +145,17 @@ parent:
async ReturnSitesWithData(nsCString[] aSites, uint64_t aCallbackId);
intr GetKeyState(int32_t aVirtKey)
returns (int16_t aState);
intr NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(bool shouldRegister)
returns (NPError result);
// Used to broker the GetOpenFileName/GetSaveFileName file pickers on Windows.
intr GetFileName(GetFileNameFunc aFunc, OpenFileNameIPC aOfnIn)
returns (OpenFileNameRetIPC aOfnOut, bool aResult);
intr SetCursorPos(int x, int y) returns (bool aResult);
};
} // namespace plugins

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

@ -152,5 +152,196 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
VOID_TO_NPVARIANT(*v);
}
#ifdef XP_WIN
void
OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
mHwndOwner = nullptr;
// Filter is double-NULL terminated. mFilter should include the double-NULL.
mHasFilter = aLpofn->lpstrFilter != nullptr;
if (mHasFilter) {
uint32_t dNullIdx = 0;
while (aLpofn->lpstrFilter[dNullIdx] != L'\0' ||
aLpofn->lpstrFilter[dNullIdx+1] != L'\0') {
dNullIdx++;
}
mFilter.assign(aLpofn->lpstrFilter, dNullIdx+2);
}
mHasCustomFilter = aLpofn->lpstrCustomFilter != nullptr;
if (mHasCustomFilter) {
mCustomFilterIn = std::wstring(aLpofn->lpstrCustomFilter);
mNMaxCustFilterOut =
aLpofn->nMaxCustFilter - (wcslen(aLpofn->lpstrCustomFilter) + 1);
}
else {
mNMaxCustFilterOut = 0;
}
mFilterIndex = aLpofn->nFilterIndex;
mFile = std::wstring(aLpofn->lpstrFile);
mNMaxFile = aLpofn->nMaxFile;
mNMaxFileTitle =
aLpofn->lpstrFileTitle != nullptr ? aLpofn->nMaxFileTitle : 0;
mHasInitialDir = aLpofn->lpstrInitialDir != nullptr;
if (mHasInitialDir) {
mInitialDir = std::wstring(aLpofn->lpstrInitialDir);
}
mHasTitle = aLpofn->lpstrTitle != nullptr;
if (mHasTitle) {
mTitle = std::wstring(aLpofn->lpstrTitle);
}
mHasDefExt = aLpofn->lpstrDefExt != nullptr;
if (mHasDefExt) {
mDefExt = std::wstring(aLpofn->lpstrDefExt);
}
mFlags = aLpofn->Flags;
// If the user sets OFN_ALLOWMULTISELECT then we require OFN_EXPLORER
// as well. Without OFN_EXPLORER, the method has ancient legacy
// behavior that we don't support.
MOZ_ASSERT((mFlags & OFN_EXPLORER) || !(mFlags & OFN_ALLOWMULTISELECT));
// We ignore any visual customization and callbacks that the user set.
mFlags &= ~(OFN_ENABLEHOOK | OFN_ENABLETEMPLATEHANDLE | OFN_ENABLETEMPLATE);
mFlagsEx = aLpofn->FlagsEx;
}
void
OpenFileNameIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
aLpofn->lStructSize = sizeof(OPENFILENAMEW);
aLpofn->hwndOwner = mHwndOwner;
if (mHasFilter) {
memcpy(const_cast<LPWSTR>(aLpofn->lpstrFilter),
mFilter.data(), mFilter.size() * sizeof(wchar_t));
}
if (mHasCustomFilter) {
aLpofn->nMaxCustFilter = mCustomFilterIn.size() + 1 + mNMaxCustFilterOut;
wcscpy(aLpofn->lpstrCustomFilter, mCustomFilterIn.c_str());
memset(aLpofn->lpstrCustomFilter + mCustomFilterIn.size() + 1, 0,
mNMaxCustFilterOut * sizeof(wchar_t));
}
else {
aLpofn->nMaxCustFilter = 0;
}
aLpofn->nFilterIndex = mFilterIndex;
if (mNMaxFile > 0) {
wcsncpy(aLpofn->lpstrFile, mFile.c_str(),
std::min(static_cast<uint32_t>(mFile.size()+1), mNMaxFile));
aLpofn->lpstrFile[mNMaxFile - 1] = L'\0';
}
aLpofn->nMaxFile = mNMaxFile;
aLpofn->nMaxFileTitle = mNMaxFileTitle;
if (mHasInitialDir) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrInitialDir), mInitialDir.c_str());
}
if (mHasTitle) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrTitle), mTitle.c_str());
}
aLpofn->Flags = mFlags; /* TODO: Consider adding OFN_NOCHANGEDIR */
if (mHasDefExt) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrDefExt), mDefExt.c_str());
}
aLpofn->FlagsEx = mFlagsEx;
}
void
OpenFileNameIPC::AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const
{
if (mHasFilter) {
// mFilter is double-NULL terminated and it includes the double-NULL in its length.
aLpofn->lpstrFilter =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mFilter.size())));
}
if (mHasCustomFilter) {
aLpofn->lpstrCustomFilter =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * (mCustomFilterIn.size() + 1 + mNMaxCustFilterOut)));
}
aLpofn->lpstrFile =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFile));
if (mNMaxFileTitle > 0) {
aLpofn->lpstrFileTitle =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFileTitle));
}
if (mHasInitialDir) {
aLpofn->lpstrInitialDir =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mInitialDir.size() + 1)));
}
if (mHasTitle) {
aLpofn->lpstrTitle =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mTitle.size() + 1)));
}
if (mHasDefExt) {
aLpofn->lpstrDefExt =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mDefExt.size() + 1)));
}
}
void
OpenFileNameIPC::FreeOfnStrings(LPOPENFILENAMEW aLpofn) const
{
if (aLpofn->lpstrFilter) {
free(const_cast<LPWSTR>(aLpofn->lpstrFilter));
}
if (aLpofn->lpstrCustomFilter) {
free(aLpofn->lpstrCustomFilter);
}
if (aLpofn->lpstrFile) {
free(aLpofn->lpstrFile);
}
if (aLpofn->lpstrFileTitle) {
free(aLpofn->lpstrFileTitle);
}
if (aLpofn->lpstrInitialDir) {
free(const_cast<LPWSTR>(aLpofn->lpstrInitialDir));
}
if (aLpofn->lpstrTitle) {
free(const_cast<LPWSTR>(aLpofn->lpstrTitle));
}
if (aLpofn->lpstrDefExt) {
free(const_cast<LPWSTR>(aLpofn->lpstrDefExt));
}
}
void
OpenFileNameRetIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
if (aLpofn->lpstrCustomFilter != nullptr) {
mCustomFilterOut =
std::wstring(aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1);
}
mFile.assign(aLpofn->lpstrFile, aLpofn->nMaxFile);
if (aLpofn->lpstrFileTitle != nullptr) {
mFileTitle.assign(aLpofn->lpstrFileTitle, wcslen(aLpofn->lpstrFileTitle) + 1);
}
mFileOffset = aLpofn->nFileOffset;
mFileExtension = aLpofn->nFileExtension;
}
void
OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
if (aLpofn->lpstrCustomFilter) {
LPWSTR secondString =
aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1;
const wchar_t* customFilterOut = mCustomFilterOut.c_str();
MOZ_ASSERT(wcslen(aLpofn->lpstrCustomFilter) + 1 +
wcslen(customFilterOut) + 1 + 1 <= aLpofn->nMaxCustFilter);
wcscpy(secondString, customFilterOut);
secondString[wcslen(customFilterOut) + 1] = L'\0'; // terminated with two NULLs
}
MOZ_ASSERT(mFile.size() <= aLpofn->nMaxFile);
memcpy(aLpofn->lpstrFile,
mFile.data(), mFile.size() * sizeof(wchar_t));
if (aLpofn->lpstrFileTitle != nullptr) {
MOZ_ASSERT(mFileTitle.size() + 1 < aLpofn->nMaxFileTitle);
wcscpy(aLpofn->lpstrFileTitle, mFileTitle.c_str());
}
aLpofn->nFileOffset = mFileOffset;
aLpofn->nFileExtension = mFileExtension;
}
#endif // XP_WIN
} // namespace plugins
} // namespace mozilla

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

@ -32,6 +32,9 @@
namespace mac_plugin_interposing { class NSCursorInfo { }; }
#endif
using mac_plugin_interposing::NSCursorInfo;
#ifdef XP_WIN
#include "commdlg.h"
#endif
namespace mozilla {
namespace plugins {
@ -123,9 +126,59 @@ typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
#ifdef XP_WIN
typedef base::SharedMemoryHandle WindowsSharedMemoryHandle;
typedef HANDLE DXGISharedSurfaceHandle;
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
// IPC-capable version of the Windows OPENFILENAMEW struct.
typedef struct _OpenFileNameIPC
{
// Allocates memory for the strings in this object. This should usually
// be used with a zeroed out OPENFILENAMEW structure.
void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const;
void FreeOfnStrings(LPOPENFILENAMEW aLpofn) const;
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
NativeWindowHandle mHwndOwner;
std::wstring mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true
bool mHasFilter;
std::wstring mCustomFilterIn;
bool mHasCustomFilter;
uint32_t mNMaxCustFilterOut;
uint32_t mFilterIndex;
std::wstring mFile;
uint32_t mNMaxFile;
uint32_t mNMaxFileTitle;
std::wstring mInitialDir;
bool mHasInitialDir;
std::wstring mTitle;
bool mHasTitle;
uint32_t mFlags;
std::wstring mDefExt;
bool mHasDefExt;
uint32_t mFlagsEx;
} OpenFileNameIPC;
// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW
// parameter. This represents those values so that they can be returned via IPC.
typedef struct _OpenFileNameRetIPC
{
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
std::wstring mCustomFilterOut;
std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0")
std::wstring mFileTitle;
uint16_t mFileOffset;
uint16_t mFileExtension;
} OpenFileNameRetIPC;
#else // XP_WIN
typedef mozilla::null_t WindowsSharedMemoryHandle;
typedef mozilla::null_t DXGISharedSurfaceHandle;
typedef mozilla::null_t GetFileNameFunc;
typedef mozilla::null_t OpenFileNameIPC;
typedef mozilla::null_t OpenFileNameRetIPC;
#endif
// XXX maybe not the best place for these. better one?
@ -654,6 +707,109 @@ struct ParamTraits<mozilla::plugins::NPAudioDeviceChangeDetailsIPC>
}
};
#ifdef XP_WIN
template <>
struct ParamTraits<mozilla::plugins::_OpenFileNameIPC>
{
typedef mozilla::plugins::_OpenFileNameIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHwndOwner);
WriteParam(aMsg, aParam.mFilter);
WriteParam(aMsg, aParam.mHasFilter);
WriteParam(aMsg, aParam.mCustomFilterIn);
WriteParam(aMsg, aParam.mHasCustomFilter);
WriteParam(aMsg, aParam.mNMaxCustFilterOut);
WriteParam(aMsg, aParam.mFilterIndex);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mNMaxFile);
WriteParam(aMsg, aParam.mNMaxFileTitle);
WriteParam(aMsg, aParam.mInitialDir);
WriteParam(aMsg, aParam.mHasInitialDir);
WriteParam(aMsg, aParam.mTitle);
WriteParam(aMsg, aParam.mHasTitle);
WriteParam(aMsg, aParam.mFlags);
WriteParam(aMsg, aParam.mDefExt);
WriteParam(aMsg, aParam.mHasDefExt);
WriteParam(aMsg, aParam.mFlagsEx);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) &&
ReadParam(aMsg, aIter, &aResult->mFilter) &&
ReadParam(aMsg, aIter, &aResult->mHasFilter) &&
ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) &&
ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) &&
ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFilterIndex) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mHasInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mTitle) &&
ReadParam(aMsg, aIter, &aResult->mHasTitle) &&
ReadParam(aMsg, aIter, &aResult->mFlags) &&
ReadParam(aMsg, aIter, &aResult->mDefExt) &&
ReadParam(aMsg, aIter, &aResult->mHasDefExt) &&
ReadParam(aMsg, aIter, &aResult->mFlagsEx)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %S]", aParam.mFilter.c_str(),
aParam.mCustomFilterIn.c_str(), aParam.mFile.c_str(),
aParam.mTitle.c_str()));
}
};
template <>
struct ParamTraits<mozilla::plugins::_OpenFileNameRetIPC>
{
typedef mozilla::plugins::_OpenFileNameRetIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mCustomFilterOut);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mFileTitle);
WriteParam(aMsg, aParam.mFileOffset);
WriteParam(aMsg, aParam.mFileExtension);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mFileOffset) &&
ReadParam(aMsg, aIter, &aResult->mFileExtension)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %d, %d]", aParam.mCustomFilterOut.c_str(),
aParam.mFile.c_str(), aParam.mFileTitle.c_str(),
aParam.mFileOffset, aParam.mFileExtension));
}
};
template <>
struct ParamTraits<mozilla::plugins::GetFileNameFunc> :
public ContiguousEnumSerializerInclusive<mozilla::plugins::GetFileNameFunc,
mozilla::plugins::OPEN_FUNC,
mozilla::plugins::SAVE_FUNC>
{};
#endif // XP_WIN
} /* namespace IPC */

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

@ -37,12 +37,12 @@
#include "mozilla/Unused.h"
#include "nsNPAPIPlugin.h"
#include "FunctionHook.h"
#include "FunctionBrokerChild.h"
#ifdef XP_WIN
#include "nsWindowsDllInterceptor.h"
#include "mozilla/widget/AudioSession.h"
#include <knownfolders.h>
#include <shlobj.h>
#endif
#ifdef MOZ_WIDGET_COCOA
@ -61,6 +61,7 @@ using namespace mozilla::widget;
#if defined(XP_WIN)
const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
const wchar_t * kMozillaWindowClass = L"MozillaWindowClass";
#endif
namespace {
@ -69,8 +70,49 @@ PluginModuleChild* gChromeInstance = nullptr;
} // namespace
#ifdef XP_WIN
// Hooking CreateFileW for protected-mode magic
static WindowsDllInterceptor sKernel32Intercept;
typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR fname, DWORD access,
DWORD share,
LPSECURITY_ATTRIBUTES security,
DWORD creation, DWORD flags,
HANDLE ftemplate);
static CreateFileWPtr sCreateFileWStub = nullptr;
typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR fname, DWORD access,
DWORD share,
LPSECURITY_ATTRIBUTES security,
DWORD creation, DWORD flags,
HANDLE ftemplate);
static CreateFileAPtr sCreateFileAStub = nullptr;
// Used with fix for flash fullscreen window loosing focus.
static bool gDelayFlashFocusReplyUntilEval = false;
// Used to fix GetWindowInfo problems with internal flash settings dialogs
static WindowsDllInterceptor sUser32Intercept;
typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
static GetWindowInfoPtr sGetWindowInfoPtrStub = nullptr;
static HWND sBrowserHwnd = nullptr;
// sandbox process doesn't get current key states. So we need get it on chrome.
typedef SHORT (WINAPI *GetKeyStatePtr)(int);
static GetKeyStatePtr sGetKeyStatePtrStub = nullptr;
static WindowsDllInterceptor sComDlg32Intercept;
// proxy GetSaveFileName/GetOpenFileName on chrome so that we can know which
// files the user has given permission to access
// We count on GetOpenFileNameA/GetSaveFileNameA calling
// GetOpenFileNameW/GetSaveFileNameW so we don't proxy them explicitly.
typedef BOOL (WINAPI *GetOpenFileNameWPtr)(LPOPENFILENAMEW lpofn);
static GetOpenFileNameWPtr sGetOpenFileNameWPtrStub = nullptr;
typedef BOOL (WINAPI *GetSaveFileNameWPtr)(LPOPENFILENAMEW lpofn);
static GetSaveFileNameWPtr sGetSaveFileNameWPtrStub = nullptr;
typedef BOOL (WINAPI *SetCursorPosPtr)(int x, int y);
static SetCursorPosPtr sSetCursorPosPtrStub = nullptr;
typedef BOOL (WINAPI *PrintDlgWPtr)(LPPRINTDLGW aDlg);
static PrintDlgWPtr sPrintDlgWPtrStub = nullptr;
#endif
/* static */
@ -184,7 +226,7 @@ PluginModuleChild::RecvDisableFlashProtectedMode()
{
MOZ_ASSERT(mIsChrome);
#ifdef XP_WIN
FunctionHook::HookProtectedMode();
HookProtectedMode();
#else
MOZ_ASSERT(false, "Should not be called");
#endif
@ -702,21 +744,6 @@ PluginModuleChild::RecvInitPluginModuleChild(Endpoint<PPluginModuleChild>&& aEnd
return IPC_OK();
}
mozilla::ipc::IPCResult
PluginModuleChild::RecvInitPluginFunctionBroker(Endpoint<PFunctionBrokerChild>&& aEndpoint)
{
#if defined(XP_WIN)
MOZ_ASSERT(mIsChrome);
if (!FunctionBrokerChild::Initialize(Move(aEndpoint))) {
return IPC_FAIL(this,
"InitPluginFunctionBroker failed to initialize broker child.");
}
return IPC_OK();
#else
return IPC_FAIL(this, "InitPluginFunctionBroker not supported on this platform.");
#endif
}
mozilla::ipc::IPCResult
PluginModuleChild::AnswerInitCrashReporter(Shmem&& aShmem, mozilla::dom::NativeThreadId* aOutId)
@ -760,11 +787,6 @@ PluginModuleChild::ActorDestroy(ActorDestroyReason why)
NP_Shutdown();
}
#if defined(XP_WIN)
FunctionBrokerChild::Destroy();
FunctionHook::ClearDllInterceptorCache();
#endif
// doesn't matter why we're being destroyed; it's up to us to
// initiate (clean) shutdown
CrashReporterClient::DestroySingleton();
@ -1767,6 +1789,426 @@ PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings)
return result;
}
#if defined(XP_WIN)
// Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
// CreateFileW from CreateFileA.
// So we hook CreateFileA too to use CreateFileW hook.
static HANDLE WINAPI
CreateFileAHookFn(LPCSTR fname, DWORD access, DWORD share,
LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
HANDLE ftemplate)
{
while (true) { // goto out
// Our hook is for mms.cfg into \Windows\System32\Macromed\Flash
// We don't requrie supporting too long path.
WCHAR unicodeName[MAX_PATH];
size_t len = strlen(fname);
if (len >= MAX_PATH) {
break;
}
// We call to CreateFileW for workaround of Windows 8 RTM
int newLen = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, fname,
len, unicodeName, MAX_PATH);
if (newLen == 0 || newLen >= MAX_PATH) {
break;
}
unicodeName[newLen] = '\0';
return CreateFileW(unicodeName, access, share, security, creation, flags, ftemplate);
}
return sCreateFileAStub(fname, access, share, security, creation, flags,
ftemplate);
}
static bool
GetLocalLowTempPath(size_t aLen, LPWSTR aPath)
{
NS_NAMED_LITERAL_STRING(tempname, "\\Temp");
LPWSTR path;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0,
nullptr, &path))) {
if (wcslen(path) + tempname.Length() < aLen) {
wcscpy(aPath, path);
wcscat(aPath, tempname.get());
::CoTaskMemFree(path);
return true;
}
::CoTaskMemFree(path);
}
// XP doesn't support SHGetKnownFolderPath and LocalLow
if (!GetTempPathW(aLen, aPath)) {
return false;
}
return true;
}
HANDLE WINAPI
CreateFileWHookFn(LPCWSTR fname, DWORD access, DWORD share,
LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
HANDLE ftemplate)
{
static const WCHAR kConfigFile[] = L"mms.cfg";
static const size_t kConfigLength = ArrayLength(kConfigFile) - 1;
while (true) { // goto out, in sheep's clothing
size_t len = wcslen(fname);
if (len < kConfigLength) {
break;
}
if (wcscmp(fname + len - kConfigLength, kConfigFile) != 0) {
break;
}
// This is the config file we want to rewrite
WCHAR tempPath[MAX_PATH+1];
if (GetLocalLowTempPath(MAX_PATH, tempPath) == 0) {
break;
}
WCHAR tempFile[MAX_PATH+1];
if (GetTempFileNameW(tempPath, L"fx", 0, tempFile) == 0) {
break;
}
HANDLE replacement =
sCreateFileWStub(tempFile, GENERIC_READ | GENERIC_WRITE, share,
security, TRUNCATE_EXISTING,
FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (replacement == INVALID_HANDLE_VALUE) {
break;
}
HANDLE original = sCreateFileWStub(fname, access, share, security,
creation, flags, ftemplate);
if (original != INVALID_HANDLE_VALUE) {
// copy original to replacement
static const size_t kBufferSize = 1024;
char buffer[kBufferSize];
DWORD bytes;
while (ReadFile(original, buffer, kBufferSize, &bytes, NULL)) {
if (bytes == 0) {
break;
}
DWORD wbytes;
WriteFile(replacement, buffer, bytes, &wbytes, NULL);
if (bytes < kBufferSize) {
break;
}
}
CloseHandle(original);
}
static const char kSettingString[] = "\nProtectedMode=0\n";
DWORD wbytes;
WriteFile(replacement, static_cast<const void*>(kSettingString),
sizeof(kSettingString) - 1, &wbytes, NULL);
SetFilePointer(replacement, 0, NULL, FILE_BEGIN);
return replacement;
}
return sCreateFileWStub(fname, access, share, security, creation, flags,
ftemplate);
}
void
PluginModuleChild::HookProtectedMode()
{
sKernel32Intercept.Init("kernel32.dll");
sKernel32Intercept.AddHook("CreateFileW",
reinterpret_cast<intptr_t>(CreateFileWHookFn),
(void**) &sCreateFileWStub);
sKernel32Intercept.AddHook("CreateFileA",
reinterpret_cast<intptr_t>(CreateFileAHookFn),
(void**) &sCreateFileAStub);
}
BOOL WINAPI
PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
{
if (!pwi)
return FALSE;
if (!sGetWindowInfoPtrStub) {
NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
return FALSE;
}
if (!sBrowserHwnd) {
wchar_t szClass[20];
if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
!wcscmp(szClass, kMozillaWindowClass)) {
sBrowserHwnd = hWnd;
}
}
// Oddity: flash does strange rect comparisons for mouse input destined for
// it's internal settings window. Post removing sub widgets for tabs, touch
// this up so they get the rect they expect.
// XXX potentially tie this to a specific major version?
BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
if (sBrowserHwnd && sBrowserHwnd == hWnd)
pwi->rcWindow = pwi->rcClient;
return result;
}
SHORT WINAPI PMCGetKeyState(int aVirtKey);
// Runnable that performs GetKeyState on the main thread so that it can be
// synchronously run on the PluginModuleParent via IPC.
// The task alerts the given semaphore when it is finished.
class GetKeyStateTask : public Runnable
{
SHORT* mKeyState;
int mVirtKey;
HANDLE mSemaphore;
public:
explicit GetKeyStateTask(int aVirtKey, HANDLE aSemaphore, SHORT* aKeyState) :
Runnable("GetKeyStateTask"),
mKeyState(aKeyState),
mVirtKey(aVirtKey),
mSemaphore(aSemaphore)
{}
NS_IMETHOD Run() override
{
PLUGIN_LOG_DEBUG_METHOD;
AssertPluginThread();
*mKeyState = PMCGetKeyState(mVirtKey);
if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
};
// static
SHORT WINAPI
PMCGetKeyState(int aVirtKey)
{
if (!IsPluginThread()) {
// synchronously request the key state from the main thread
// Start a semaphore at 0. We Release the semaphore (bringing its count to 1)
// when the synchronous call is done.
HANDLE semaphore = CreateSemaphore(NULL, 0, 1, NULL);
if (semaphore == nullptr) {
MOZ_ASSERT(semaphore != nullptr);
return 0;
}
SHORT keyState;
RefPtr<GetKeyStateTask> task = new GetKeyStateTask(aVirtKey, semaphore, &keyState);
ProcessChild::message_loop()->PostTask(task.forget());
DWORD err = WaitForSingleObject(semaphore, INFINITE);
if (err != WAIT_FAILED) {
CloseHandle(semaphore);
return keyState;
}
PLUGIN_LOG_DEBUG(("Error while waiting for GetKeyState semaphore: %d",
GetLastError()));
MOZ_ASSERT(err != WAIT_FAILED);
CloseHandle(semaphore);
return 0;
}
PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
if (chromeInstance) {
int16_t ret = 0;
if (chromeInstance->CallGetKeyState(aVirtKey, &ret)) {
return ret;
}
}
return sGetKeyStatePtrStub(aVirtKey);
}
class PluginThreadTaskData
{
public:
virtual bool RunTask() = 0;
};
// Runnable that performs a task on the main thread so that the call can be
// synchronously run on the PluginModuleParent via IPC.
// The task alerts the given semaphore when it is finished.
class PluginThreadTask : public Runnable
{
bool mSuccess;
PluginThreadTaskData* mTaskData;
HANDLE mSemaphore;
public:
explicit PluginThreadTask(PluginThreadTaskData* aTaskData,
HANDLE aSemaphore) :
Runnable("PluginThreadTask"),
mSuccess(false),
mTaskData(aTaskData),
mSemaphore(aSemaphore)
{}
NS_IMETHOD Run() override
{
PLUGIN_LOG_DEBUG_METHOD;
AssertPluginThread();
mSuccess = mTaskData->RunTask();
if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
bool Success() { return mSuccess; }
};
// static
BOOL
PostToPluginThread(PluginThreadTaskData* aTaskData)
{
MOZ_ASSERT(!IsPluginThread());
// Synchronously run GetFileNameTask from the main thread.
// Start a semaphore at 0. We release the semaphore (bringing its
// count to 1) when the synchronous call is done.
nsAutoHandle semaphore(CreateSemaphore(NULL, 0, 1, NULL));
if (semaphore == nullptr) {
MOZ_ASSERT(semaphore != nullptr);
return FALSE;
}
RefPtr<PluginThreadTask> task = new PluginThreadTask(aTaskData, semaphore);
ProcessChild::message_loop()->PostTask(do_AddRef(task));
DWORD err = WaitForSingleObject(semaphore, INFINITE);
if (err != WAIT_FAILED) {
return task->Success();
}
PLUGIN_LOG_DEBUG(("Error while waiting for semaphore: %d",
GetLastError()));
MOZ_ASSERT(err != WAIT_FAILED);
return FALSE;
}
BOOL WINAPI PMCGetSaveFileNameW(LPOPENFILENAMEW lpofn);
BOOL WINAPI PMCGetOpenFileNameW(LPOPENFILENAMEW lpofn);
class GetFileNameTaskData : public PluginThreadTaskData
{
public:
GetFileNameTaskData(GetFileNameFunc aFunc, void* aLpOpenFileName) :
mFunc(aFunc), mLpOpenFileName(aLpOpenFileName)
{}
bool RunTask()
{
switch (mFunc) {
case OPEN_FUNC:
return PMCGetOpenFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
case SAVE_FUNC:
return PMCGetSaveFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
}
return false;
}
private:
GetFileNameFunc mFunc;
void* mLpOpenFileName;
};
// static
BOOL WINAPI
PMCGetFileNameW(GetFileNameFunc aFunc, LPOPENFILENAMEW aLpofn)
{
if (!IsPluginThread()) {
GetFileNameTaskData gfnData(aFunc, aLpofn);
return PostToPluginThread(&gfnData);
}
PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
if (chromeInstance) {
bool ret = FALSE;
OpenFileNameIPC inputOfn;
inputOfn.CopyFromOfn(aLpofn);
OpenFileNameRetIPC outputOfn;
if (chromeInstance->CallGetFileName(aFunc, inputOfn,
&outputOfn, &ret)) {
if (ret) {
outputOfn.AddToOfn(aLpofn);
}
}
return ret;
}
switch (aFunc) {
case OPEN_FUNC:
return sGetOpenFileNameWPtrStub(aLpofn);
case SAVE_FUNC:
return sGetSaveFileNameWPtrStub(aLpofn);
}
MOZ_ASSERT_UNREACHABLE("Illegal GetFileNameFunc value");
return FALSE;
}
// static
BOOL WINAPI
PMCGetSaveFileNameW(LPOPENFILENAMEW aLpofn)
{
return PMCGetFileNameW(SAVE_FUNC, aLpofn);
}
// static
BOOL WINAPI
PMCGetOpenFileNameW(LPOPENFILENAMEW aLpofn)
{
return PMCGetFileNameW(OPEN_FUNC, aLpofn);
}
//static
BOOL WINAPI
PMCPrintDlgW(LPPRINTDLGW aDlg)
{
// Zero out the HWND supplied by the plugin. We are sacrificing window
// parentage for the ability to run in the NPAPI sandbox.
HWND hwnd = aDlg->hwndOwner;
aDlg->hwndOwner = 0;
BOOL ret = sPrintDlgWPtrStub(aDlg);
aDlg->hwndOwner = hwnd;
return ret;
}
BOOL WINAPI PMCSetCursorPos(int x, int y);
class SetCursorPosTaskData : public PluginThreadTaskData
{
public:
SetCursorPosTaskData(int x, int y) : mX(x), mY(y) {}
bool RunTask() { return PMCSetCursorPos(mX, mY); }
private:
int mX, mY;
};
// static
BOOL WINAPI
PMCSetCursorPos(int x, int y)
{
if (!IsPluginThread()) {
SetCursorPosTaskData scpData(x, y);
return PostToPluginThread(&scpData);
}
PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
if (chromeInstance) {
bool ret = FALSE;
chromeInstance->CallSetCursorPos(x, y, &ret);
return ret;
}
return sSetCursorPosPtrStub(x, y);
}
#endif
PPluginInstanceChild*
PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType,
const InfallibleTArray<nsCString>& aNames,
@ -1784,7 +2226,40 @@ PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType,
mQuirks = GetChrome()->mQuirks;
#ifdef XP_WIN
FunctionHook::HookFunctions(mQuirks);
sUser32Intercept.Init("user32.dll");
if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) &&
!sGetWindowInfoPtrStub) {
sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook),
(void**) &sGetWindowInfoPtrStub);
}
if ((mQuirks & QUIRK_FLASH_HOOK_GETKEYSTATE) &&
!sGetKeyStatePtrStub) {
sUser32Intercept.AddHook("GetKeyState", reinterpret_cast<intptr_t>(PMCGetKeyState),
(void**) &sGetKeyStatePtrStub);
}
if (!sSetCursorPosPtrStub) {
sUser32Intercept.AddHook("SetCursorPos", reinterpret_cast<intptr_t>(PMCSetCursorPos),
(void**) &sSetCursorPosPtrStub);
}
sComDlg32Intercept.Init("comdlg32.dll");
if (!sGetSaveFileNameWPtrStub) {
sComDlg32Intercept.AddHook("GetSaveFileNameW", reinterpret_cast<intptr_t>(PMCGetSaveFileNameW),
(void**) &sGetSaveFileNameWPtrStub);
}
if (!sGetOpenFileNameWPtrStub) {
sComDlg32Intercept.AddHook("GetOpenFileNameW", reinterpret_cast<intptr_t>(PMCGetOpenFileNameW),
(void**) &sGetOpenFileNameWPtrStub);
}
if ((mQuirks & QUIRK_FLASH_HOOK_PRINTDLGW) &&
!sPrintDlgWPtrStub) {
sComDlg32Intercept.AddHook("PrintDlgW", reinterpret_cast<intptr_t>(PMCPrintDlgW),
(void**) &sPrintDlgWPtrStub);
}
#endif
return new PluginInstanceChild(&mFunctions, aMimeType, aNames,

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

@ -78,9 +78,6 @@ protected:
virtual mozilla::ipc::IPCResult
RecvInitPluginModuleChild(Endpoint<PPluginModuleChild>&& endpoint) override;
virtual mozilla::ipc::IPCResult
RecvInitPluginFunctionBroker(Endpoint<PFunctionBrokerChild>&& endpoint) override;
virtual PPluginInstanceChild*
AllocPPluginInstanceChild(const nsCString& aMimeType,
const InfallibleTArray<nsCString>& aNames,
@ -236,6 +233,10 @@ private:
bool InitGraphics();
void DeinitGraphics();
#if defined(OS_WIN)
void HookProtectedMode();
#endif
#if defined(MOZ_WIDGET_GTK)
static gboolean DetectNestedEventLoop(gpointer data);
static gboolean ProcessBrowserEvents(gpointer data);

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

@ -43,7 +43,6 @@
#include "mozilla/plugins/PluginSurfaceParent.h"
#include "mozilla/widget/AudioSession.h"
#include "PluginHangUIParent.h"
#include "FunctionBrokerParent.h"
#include "PluginUtilsWin.h"
#endif
@ -487,23 +486,6 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
parent->mShutdown = true;
return nullptr;
}
#if defined(XP_WIN)
Endpoint<PFunctionBrokerParent> brokerParentEnd;
Endpoint<PFunctionBrokerChild> brokerChildEnd;
rv = PFunctionBroker::CreateEndpoints(base::GetCurrentProcId(), parent->OtherPid(),
&brokerParentEnd, &brokerChildEnd);
if (NS_FAILED(rv)) {
parent->mShutdown = true;
return nullptr;
}
parent->mBrokerParent =
FunctionBrokerParent::Create(Move(brokerParentEnd));
if (parent->mBrokerParent) {
parent->SendInitPluginFunctionBroker(Move(brokerChildEnd));
}
#endif
return parent.forget();
}
@ -640,7 +622,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
, mHangUIParent(nullptr)
, mHangUIEnabled(true)
, mIsTimerReset(true)
, mBrokerParent(nullptr)
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
, mFlashProcess1(0)
@ -667,6 +648,10 @@ PluginModuleChromeParent::~PluginModuleChromeParent()
false);
#endif
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mSandboxPermissions.RemovePermissionsForProcess(OtherPid());
#endif
if (!mShutdown) {
NS_WARNING("Plugin host deleted the module without shutting down.");
NPError err;
@ -1611,13 +1596,6 @@ PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
// We can't broadcast settings changes anymore.
UnregisterSettingsCallbacks();
#if defined(XP_WIN)
if (mBrokerParent) {
FunctionBrokerParent::Destroy(mBrokerParent);
mBrokerParent = nullptr;
}
#endif
PluginModuleParent::ActorDestroy(why);
}
@ -2901,3 +2879,102 @@ PluginModuleChromeParent::OnCrash(DWORD processID)
}
#endif // MOZ_CRASHREPORTER_INJECTOR
mozilla::ipc::IPCResult
PluginModuleParent::AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet)
{
return IPC_FAIL_NO_REASON(this);
}
mozilla::ipc::IPCResult
PluginModuleChromeParent::AnswerGetKeyState(const int32_t& aVirtKey,
int16_t* aRet)
{
#if defined(XP_WIN)
*aRet = ::GetKeyState(aVirtKey);
return IPC_OK();
#else
return PluginModuleParent::AnswerGetKeyState(aVirtKey, aRet);
#endif
}
mozilla::ipc::IPCResult
PluginModuleChromeParent::AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut,
bool* aResult)
{
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
OPENFILENAMEW ofn;
memset(&ofn, 0, sizeof(ofn));
aOfnIn.AllocateOfnStrings(&ofn);
aOfnIn.AddToOfn(&ofn);
switch (aFunc) {
case OPEN_FUNC:
*aResult = GetOpenFileName(&ofn);
break;
case SAVE_FUNC:
*aResult = GetSaveFileName(&ofn);
break;
default:
*aResult = false;
break;
}
if (*aResult) {
if (ofn.Flags & OFN_ALLOWMULTISELECT) {
// We only support multiselect with the OFN_EXPLORER flag.
// This guarantees that ofn.lpstrFile follows the pattern below.
MOZ_ASSERT(ofn.Flags & OFN_EXPLORER);
// lpstrFile is one of two things:
// 1. A null terminated full path to a file, or
// 2. A path to a folder, followed by a NULL, followed by a
// list of file names, each NULL terminated, followed by an
// additional NULL (so it is also double-NULL terminated).
std::wstring path = std::wstring(ofn.lpstrFile);
MOZ_ASSERT(ofn.nFileOffset > 0);
// For condition #1, nFileOffset points to the file name in the path.
// It will be preceeded by a non-NULL character from the path.
if (ofn.lpstrFile[ofn.nFileOffset-1] != L'\0') {
mSandboxPermissions.GrantFileAccess(OtherPid(), path.c_str(),
aFunc == SAVE_FUNC);
}
else {
// This is condition #2
wchar_t* nextFile = ofn.lpstrFile + path.size() + 1;
while (*nextFile != L'\0') {
std::wstring nextFileStr(nextFile);
std::wstring fullPath =
path + std::wstring(L"\\") + nextFileStr;
mSandboxPermissions.GrantFileAccess(OtherPid(), fullPath.c_str(),
aFunc == SAVE_FUNC);
nextFile += nextFileStr.size() + 1;
}
}
}
else {
mSandboxPermissions.GrantFileAccess(OtherPid(), ofn.lpstrFile,
aFunc == SAVE_FUNC);
}
aOfnOut->CopyFromOfn(&ofn);
}
aOfnIn.FreeOfnStrings(&ofn);
return IPC_OK();
#else
MOZ_ASSERT_UNREACHABLE("GetFileName IPC message is only available on "
"Windows builds with sandbox.");
return IPC_FAIL_NO_REASON(this);
#endif
}
mozilla::ipc::IPCResult
PluginModuleChromeParent::AnswerSetCursorPos(const int &x, const int &y,
bool* aResult)
{
#if defined(XP_WIN)
*aResult = ::SetCursorPos(x, y);
return IPC_OK();
#else
return PluginModuleParent::AnswerSetCursorPos(x, y, aResult);
#endif
}

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

@ -27,6 +27,9 @@
#include "nsIObserver.h"
#ifdef XP_WIN
#include "nsWindowsHelpers.h"
#if defined(MOZ_SANDBOX)
#include "sandboxPermissions.h"
#endif
#endif
class nsPluginTag;
@ -45,7 +48,6 @@ class PluginInstanceParent;
#ifdef XP_WIN
class PluginHangUIParent;
class FunctionBrokerParent;
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
class FinishInjectorInitTask;
@ -166,6 +168,20 @@ protected:
const bool& shouldRegister,
NPError* result) override;
virtual mozilla::ipc::IPCResult
AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut, bool* aResult) override
{
return IPC_FAIL_NO_REASON(this);
}
virtual mozilla::ipc::IPCResult
AnswerSetCursorPos(const int &x, const int &y, bool* aResult) override
{
return IPC_FAIL_NO_REASON(this);
}
protected:
void SetChildTimeout(const int32_t aChildTimeout);
static void TimeoutChanged(const char* aPref, void* aModule);
@ -174,6 +190,8 @@ protected:
virtual mozilla::ipc::IPCResult RecvNotifyContentModuleDestroyed() override { return IPC_OK(); }
virtual mozilla::ipc::IPCResult AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override;
virtual mozilla::ipc::IPCResult RecvReturnClearSiteData(const NPError& aRv,
const uint64_t& aCallbackId) override;
@ -466,6 +484,19 @@ class PluginModuleChromeParent
void CachedSettingChanged();
virtual mozilla::ipc::IPCResult
AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override;
// Proxy GetOpenFileName/GetSaveFileName on Windows.
virtual mozilla::ipc::IPCResult
AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut, bool* aResult) override;
// Proxy SetCursorPos on Windows.
virtual mozilla::ipc::IPCResult
AnswerSetCursorPos(const int &x, const int &y, bool* aResult) override;
private:
virtual void
EnteredCxxStack() override;
@ -557,8 +588,6 @@ private:
*/
void
FinishHangUI();
FunctionBrokerParent* mBrokerParent;
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
@ -600,6 +629,9 @@ private:
nsCOMPtr<nsIObserver> mPluginOfflineObserver;
bool mIsBlocklisted;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions mSandboxPermissions;
#endif
nsCOMPtr<nsIFile> mBrowserDumpFile;
TakeFullMinidumpCallback mTakeFullMinidumpCallback;

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

@ -12,8 +12,6 @@
#include "base/command_line.h"
#include "base/string_util.h"
#include "nsDebugImpl.h"
#include "nsThreadManager.h"
#include "ClearOnShutdown.h"
#if defined(XP_MACOSX)
#include "nsCocoaFeatures.h"
@ -108,14 +106,6 @@ PluginProcessChild::Init(int aArgc, char* aArgv[])
pluginFilename = WideToUTF8(values[0]);
// We don't initialize XPCOM but we need the thread manager and the
// logging framework for the FunctionBroker.
NS_SetMainThread();
mozilla::TimeStamp::Startup();
NS_LogInit();
mozilla::LogModule::Init();
nsThreadManager::get().Init();
#if defined(MOZ_SANDBOX)
// This is probably the earliest we would want to start the sandbox.
// As we attempt to tighten the sandbox, we may need to consider moving this
@ -151,18 +141,6 @@ PluginProcessChild::Init(int aArgc, char* aArgv[])
void
PluginProcessChild::CleanUp()
{
#if defined(OS_WIN)
MOZ_ASSERT(NS_IsMainThread());
// Shutdown components we started in Init. Note that KillClearOnShutdown
// is an event that is regularly part of XPCOM shutdown. We do not
// call XPCOM's shutdown but we need this event to be sent to avoid
// leaking objects labeled as ClearOnShutdown.
nsThreadManager::get().Shutdown();
mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownFinal);
NS_LogTerm();
#endif
nsRegion::ShutdownStatic();
}

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

@ -20,8 +20,6 @@
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsIRunnable.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
namespace mozilla {
namespace plugins {

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

@ -7,8 +7,6 @@
#ifndef dom_plugins_PluginQuirks_h
#define dom_plugins_PluginQuirks_h
#include "nsString.h"
namespace mozilla {
namespace plugins {

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

@ -16,8 +16,6 @@ EXPORTS.mozilla.plugins += [
'BrowserStreamChild.h',
'BrowserStreamParent.h',
'ChildTimer.h',
'FunctionBrokerIPCUtils.h',
'IpdlTuple.h',
'NPEventAndroid.h',
'NPEventOSX.h',
'NPEventUnix.h',
@ -66,15 +64,9 @@ UNIFIED_SOURCES += [
'BrowserStreamChild.cpp',
'BrowserStreamParent.cpp',
'ChildTimer.cpp',
'FunctionBroker.cpp',
'FunctionBrokerChild.cpp',
'FunctionBrokerIPCUtils.cpp',
'FunctionBrokerParent.cpp',
'FunctionHook.cpp',
'PluginBackgroundDestroyer.cpp',
'PluginInstanceParent.cpp',
'PluginMessageUtils.cpp',
'PluginModuleChild.cpp',
'PluginModuleParent.cpp',
'PluginProcessChild.cpp',
'PluginProcessParent.cpp',
@ -85,6 +77,7 @@ UNIFIED_SOURCES += [
SOURCES += [
'PluginInstanceChild.cpp', # 'PluginThreadCallback' : ambiguous symbol
'PluginModuleChild.cpp', # Redefinition of mozilla::WindowsDllInterceptor sUser32Intercept
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
@ -109,7 +102,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
IPDL_SOURCES += [
'PBrowserStream.ipdl',
'PFunctionBroker.ipdl',
'PluginTypes.ipdlh',
'PPluginBackgroundDestroyer.ipdl',
'PPluginInstance.ipdl',
@ -125,7 +117,6 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'../base',
'/xpcom/base/',
'/xpcom/threads/',
]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':

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

@ -310,12 +310,6 @@ struct ParamTraits<int8_t>
{
return aMsg->ReadBytesInto(aIter, aResult, sizeof(*aResult));
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
// Use 0xff to avoid sign extension.
aLog->append(StringPrintf(L"0x%02x", aParam & 0xff));
}
};
template<>
@ -332,11 +326,6 @@ struct ParamTraits<uint8_t>
{
return aMsg->ReadBytesInto(aIter, aResult, sizeof(*aResult));
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"0x%02x", aParam));
}
};
#if !defined(OS_POSIX)

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

@ -659,8 +659,6 @@ description =
description =
[PPluginWidget::SetNativeChildWindow]
description =
[PFunctionBroker::BrokerFunction]
description =
[PPluginInstance::__delete__]
description =
[PPluginInstance::CreateChildPluginWindow]
@ -773,10 +771,16 @@ description =
description =
[PPluginModule::NPN_SetException]
description =
[PPluginModule::GetKeyState]
description =
[PPluginModule::NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges]
description =
[PPluginModule::InitCrashReporter]
description =
[PPluginModule::GetFileName]
description =
[PPluginModule::SetCursorPos]
description =
[PPluginScriptableObject::NPN_Evaluate]
description =
[PPluginScriptableObject::Invalidate]

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

@ -5054,12 +5054,6 @@ XRE_IsContentProcess()
return XRE_GetProcessType() == GeckoProcessType_Content;
}
bool
XRE_IsPluginProcess()
{
return XRE_GetProcessType() == GeckoProcessType_Plugin;
}
bool
XRE_UseNativeEventProcessing()
{

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

@ -5,10 +5,6 @@
#include <shlobj.h>
#include <stdio.h>
#include <commdlg.h>
#define SECURITY_WIN32
#include <security.h>
#include <wininet.h>
#include <schnlsp.h>
#include "mozilla/WindowsVersion.h"
#include "nsWindowsDllInterceptor.h"
@ -444,141 +440,6 @@ bool TestPrintDlgW(void* aFunc)
return true;
}
bool TestInternetConnectA(void* aFunc)
{
auto patchedInternetConnectA =
reinterpret_cast<decltype(&InternetConnectA)>(aFunc);
return patchedInternetConnectA(0, 0, 0, 0, 0, 0, 0, 0) == 0;
}
HINTERNET sInternet = 0;
bool TestInternetOpenA(void* aFunc)
{
auto patchedInternetOpenA =
reinterpret_cast<decltype(&InternetOpenA)>(aFunc);
sInternet = patchedInternetOpenA(0, 0, 0, 0, 0);
return sInternet != 0;
}
bool TestInternetCloseHandle(void* aFunc)
{
auto patchedInternetCloseHandle =
reinterpret_cast<decltype(&InternetCloseHandle)>(aFunc);
return patchedInternetCloseHandle(sInternet);
}
bool TestInternetQueryDataAvailable(void* aFunc)
{
auto patchedInternetQueryDataAvailable =
reinterpret_cast<decltype(&InternetQueryDataAvailable)>(aFunc);
return patchedInternetQueryDataAvailable(0, 0, 0, 0) == FALSE;
}
bool TestInternetReadFile(void* aFunc)
{
auto patchedInternetReadFile =
reinterpret_cast<decltype(&InternetReadFile)>(aFunc);
return patchedInternetReadFile(0, 0, 0, 0) == FALSE;
}
bool TestInternetWriteFile(void* aFunc)
{
auto patchedInternetWriteFile =
reinterpret_cast<decltype(&InternetWriteFile)>(aFunc);
return patchedInternetWriteFile(0, 0, 0, 0) == FALSE;
}
bool TestInternetSetOptionA(void* aFunc)
{
auto patchedInternetSetOptionA =
reinterpret_cast<decltype(&InternetSetOptionA)>(aFunc);
return patchedInternetSetOptionA(0, 0, 0, 0) == FALSE;
}
bool TestHttpAddRequestHeadersA(void* aFunc)
{
auto patchedHttpAddRequestHeadersA =
reinterpret_cast<decltype(&HttpAddRequestHeadersA)>(aFunc);
return patchedHttpAddRequestHeadersA(0, 0, 0, 0) == FALSE;
}
bool TestHttpOpenRequestA(void* aFunc)
{
auto patchedHttpOpenRequestA =
reinterpret_cast<decltype(&HttpOpenRequestA)>(aFunc);
return patchedHttpOpenRequestA(0, 0, 0, 0, 0, 0, 0, 0) == 0;
}
bool TestHttpQueryInfoA(void* aFunc)
{
auto patchedHttpQueryInfoA =
reinterpret_cast<decltype(&HttpQueryInfoA)>(aFunc);
return patchedHttpQueryInfoA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpSendRequestA(void* aFunc)
{
auto patchedHttpSendRequestA =
reinterpret_cast<decltype(&HttpSendRequestA)>(aFunc);
return patchedHttpSendRequestA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpSendRequestExA(void* aFunc)
{
auto patchedHttpSendRequestExA =
reinterpret_cast<decltype(&HttpSendRequestExA)>(aFunc);
return patchedHttpSendRequestExA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpEndRequestA(void* aFunc)
{
auto patchedHttpEndRequestA =
reinterpret_cast<decltype(&HttpEndRequestA)>(aFunc);
return patchedHttpEndRequestA(0, 0, 0, 0) == FALSE;
}
bool TestInternetQueryOptionA(void* aFunc)
{
auto patchedInternetQueryOptionA =
reinterpret_cast<decltype(&InternetQueryOptionA)>(aFunc);
return patchedInternetQueryOptionA(0, 0, 0, 0) == FALSE;
}
bool TestInternetErrorDlg(void* aFunc)
{
auto patchedInternetErrorDlg =
reinterpret_cast<decltype(&InternetErrorDlg)>(aFunc);
return patchedInternetErrorDlg(0, 0, 0, 0, 0) == ERROR_INVALID_HANDLE;
}
CredHandle sCredHandle;
bool TestAcquireCredentialsHandleA(void* aFunc)
{
auto patchedAcquireCredentialsHandleA =
reinterpret_cast<decltype(&AcquireCredentialsHandleA)>(aFunc);
SCHANNEL_CRED cred;
memset(&cred, 0, sizeof(cred));
cred.dwVersion = SCHANNEL_CRED_VERSION;
return patchedAcquireCredentialsHandleA(0, UNISP_NAME, SECPKG_CRED_OUTBOUND,
0, &cred, 0, 0, &sCredHandle, 0) == S_OK;
}
bool TestQueryCredentialsAttributesA(void* aFunc)
{
auto patchedQueryCredentialsAttributesA =
reinterpret_cast<decltype(&QueryCredentialsAttributesA)>(aFunc);
return patchedQueryCredentialsAttributesA(&sCredHandle, 0, 0) == SEC_E_UNSUPPORTED_FUNCTION;
}
bool TestFreeCredentialsHandle(void* aFunc)
{
auto patchedFreeCredentialsHandle =
reinterpret_cast<decltype(&FreeCredentialsHandle)>(aFunc);
return patchedFreeCredentialsHandle(&sCredHandle) == S_OK;
}
int main()
{
// We disable this part of the test because the code coverage instrumentation
@ -695,26 +556,6 @@ int main()
TestHook(TestSetCursorPos, "user32.dll", "SetCursorPos") &&
TestHook(TestTlsAlloc, "kernel32.dll", "TlsAlloc") &&
TestHook(TestTlsFree, "kernel32.dll", "TlsFree") &&
TestHook(TestInternetOpenA, "wininet.dll", "InternetOpenA") &&
TestHook(TestInternetCloseHandle, "wininet.dll", "InternetCloseHandle") &&
TestHook(TestInternetConnectA, "wininet.dll", "InternetConnectA") &&
TestHook(TestInternetQueryDataAvailable, "wininet.dll", "InternetQueryDataAvailable") &&
TestHook(TestInternetReadFile, "wininet.dll", "InternetReadFile") &&
TestHook(TestInternetWriteFile, "wininet.dll", "InternetWriteFile") &&
TestHook(TestInternetSetOptionA, "wininet.dll", "InternetSetOptionA") &&
TestHook(TestHttpAddRequestHeadersA, "wininet.dll", "HttpAddRequestHeadersA") &&
TestHook(TestHttpOpenRequestA, "wininet.dll", "HttpOpenRequestA") &&
TestHook(TestHttpQueryInfoA, "wininet.dll", "HttpQueryInfoA") &&
TestHook(TestHttpSendRequestA, "wininet.dll", "HttpSendRequestA") &&
TestHook(TestHttpSendRequestExA, "wininet.dll", "HttpSendRequestExA") &&
TestHook(TestHttpEndRequestA, "wininet.dll", "HttpEndRequestA") &&
TestHook(TestInternetQueryOptionA, "wininet.dll", "InternetQueryOptionA") &&
TestHook(TestAcquireCredentialsHandleA, "sspicli.dll", "AcquireCredentialsHandleA") &&
TestHook(TestQueryCredentialsAttributesA, "sspicli.dll", "QueryCredentialsAttributesA") &&
TestHook(TestFreeCredentialsHandle, "sspicli.dll", "FreeCredentialsHandle") &&
TestDetour("kernel32.dll", "BaseThreadInitThunk") &&
TestDetour("ntdll.dll", "LdrLoadDll")) {
printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");

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

@ -1043,31 +1043,6 @@ protected:
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x8d) {
// LEA reg, addr
if ((origBytes[nOrigBytes + 1] & kMaskMod) == 0x0 &&
(origBytes[nOrigBytes + 1] & kMaskRm) == 0x5) {
// [rip+disp32]
// convert 32bit offset to 64bit direct and convert instruction
// to a simple 64-bit mov
BYTE reg = (origBytes[nOrigBytes + 1] & kMaskReg) >> kRegFieldShift;
intptr_t absAddr =
reinterpret_cast<intptr_t>(origBytes + nOrigBytes + 6 +
*reinterpret_cast<int32_t*>(origBytes + nOrigBytes + 2));
nOrigBytes += 6;
tramp[nTrampBytes] = 0xb8 + reg; // mov
++nTrampBytes;
intptr_t* trampOperandPtr = reinterpret_cast<intptr_t*>(tramp + nTrampBytes);
*trampOperandPtr = absAddr;
nTrampBytes += 8;
} else {
// Above we dealt with RIP-relative instructions. Any other
// operand form can simply be copied.
int len = CountModRmSib(origBytes + nOrigBytes + 1);
// We handled the kModOperand64 -- ie RIP-relative -- case above
MOZ_ASSERT(len > 0);
COPY_CODES(len + 1);
}
} else if (origBytes[nOrigBytes] == 0x63 &&
(origBytes[nOrigBytes + 1] & kMaskMod) == kModReg) {
// movsxd r64, r32 (move + sign extend)
@ -1102,17 +1077,6 @@ protected:
MOZ_ASSERT_UNREACHABLE("Unrecognized MOV opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x44 &&
origBytes[nOrigBytes+1] == 0x89) {
// mov word ptr [reg+disp8], reg
COPY_CODES(2);
int len = CountModRmSib(origBytes + nOrigBytes);
if (len < 0) {
// no way to support this yet.
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
COPY_CODES(len);
}
} else if ((origBytes[nOrigBytes] & 0xf0) == 0x50) {
// 1-byte push/pop
@ -1258,19 +1222,6 @@ protected:
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x83 &&
(origBytes[nOrigBytes + 1] & 0xf8) == 0x60) {
// and [r+d], imm8
COPY_CODES(5);
} else if (origBytes[nOrigBytes] == 0xc6) {
// mov [r+d], imm8
int len = CountModRmSib(&origBytes[nOrigBytes + 1]);
if (len < 0) {
// RIP-relative not yet supported
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
COPY_CODES(len + 1);
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
@ -1401,15 +1352,10 @@ class WindowsDllInterceptor
int mNHooks;
public:
explicit WindowsDllInterceptor(const char* aModuleName = nullptr,
int aNumHooks = 0)
WindowsDllInterceptor()
: mModuleName(nullptr)
, mNHooks(0)
{
if (aModuleName) {
Init(aModuleName, aNumHooks);
}
}
{}
void Init(const char* aModuleName, int aNumHooks = 0)
{

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

@ -447,9 +447,6 @@ XRE_API(bool,
XRE_API(bool,
XRE_IsGPUProcess, ())
XRE_API(bool,
XRE_IsPluginProcess, ())
/**
* Returns true if the appshell should run its own native event loop. Returns
* false if we should rely solely on the Gecko event loop.