/* -*- 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 # include # include # include #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() ? "" : ""); } 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 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 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 { 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 { 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 : public ContiguousEnumSerializerInclusive< mozilla::plugins::GetFileNameFunc, mozilla::plugins::OPEN_FUNC, mozilla::plugins::SAVE_FUNC> {}; template <> struct ParamTraits { typedef mozilla::plugins::IPCSchannelCred paramType; static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, static_cast(aParam.mEnabledProtocols)); WriteParam(aMsg, static_cast(aParam.mMinStrength)); WriteParam(aMsg, static_cast(aParam.mMaxStrength)); WriteParam(aMsg, static_cast(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 { 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 { 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>::Log(aParam.mBuffers, aLog); } }; template <> struct ParamTraits { 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 : public ContiguousEnumSerializer(0), FunctionHookId::ID_FunctionHookCount> {}; } // namespace IPC #endif /* dom_plugins_ipc_functionbrokeripcutils_h */