mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
c1e0f526a1
Differential Revision: https://phabricator.services.mozilla.com/D99658
437 lines
14 KiB
C++
437 lines
14 KiB
C++
/* -*- 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_functionbrokeripcutils_h
|
|
#define dom_plugins_ipc_functionbrokeripcutils_h 1
|
|
|
|
#include "ipc/EnumSerializer.h"
|
|
#include "ipc/IPCMessageUtilsSpecializations.h"
|
|
#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_HttpEndRequestA,
|
|
ID_InternetQueryOptionA,
|
|
ID_InternetErrorDlg,
|
|
ID_AcquireCredentialsHandleA,
|
|
ID_QueryCredentialsAttributesA,
|
|
ID_FreeCredentialsHandle,
|
|
ID_PrintDlgW,
|
|
ID_CreateMutexW
|
|
# if defined(MOZ_SANDBOX)
|
|
,
|
|
ID_GetFileAttributesW
|
|
# endif // defined(MOZ_SANDBOX)
|
|
,
|
|
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 CopyableTArray<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);
|
|
}
|
|
};
|
|
CopyableTArray<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::IPCInternetBuffers;
|
|
using mozilla::plugins::IPCPrintDlg;
|
|
using mozilla::plugins::IPCSchannelCred;
|
|
using mozilla::plugins::NativeWindowHandle;
|
|
using mozilla::plugins::OpenFileNameIPC;
|
|
using mozilla::plugins::OpenFileNameRetIPC;
|
|
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"[%ls, %ls, %ls, %ls]", 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"[%ls, %ls, %ls, %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 */
|