Chrome IPC Internals – Part III

We didn’t specify anything about the message ID in the IPC “protocol” header. Did we? Yes we did specify about the message ID in indirect manner. In this blog we will answer few questions.

1) Did we specify message ID?
2) How message ID is calculated?
3) Why we need to specify the message macros in a header file?

Yes we did specify the message ID when we defined the “data type” exchanged between client and server. In the Part II of this series, I have defined two different messages using macro IPC_MESSAGE_CONTROL2. This macro defines a message/type with two parameters in it. In the end of this part, we will see how this macro is expanded for one of the message we have defined.

During the IPC_MESSAGE_CONTROL2 macro expansion, message ID is calculated using this macro:

#define IPC_MESSAGE_ID() ((IPC_MESSAGE_START << 16) + __LINE__)

There are two different parameters in the above macro. IPC_MESSAGE_START is what we have defined in our header file and it uses the __LINE__ to calculate the message ID. This answer, why we need to define this macro in a header file and include it in your program!

Let’s see how IPC_MESSAGE_CONTROL2 macro is expanded for one of the message we have defined in the previous part.

After macro expansion,

// IPC_MESSAGE_CONTROL2 macro expansion

class IPC_MESSAGE_EXPORT MsgClassIS : public IPC::Message {
        typedef IPC::MessageSchema<Tuple2<int, std::wstring> > Schema;
        typedef Schema::Param Param;
        enum { ID = ((IPC_MESSAGE_START << 16) + __LINE__)};
        MsgClassIS(const int& arg1, const std::wstring& arg2);
        virtual ~MsgClassIS();
        static bool Read(const Message* msg, Schema::Param* p);
        static void Log(std::string* name, const Message* msg, std::string* l);
        template<class T, class S, class Method>
        static bool Dispatch(const Message* msg, T* obj, S* sender, Method func)
            Schema::Param p;
            if (Read(msg, &p)) {
                DispatchToMethod(obj, func, p);
                return true;
            return false;
        template<class T, class S, typename TA, typename TB>
        static bool Dispatch(const Message* msg, T* obj, S* sender,void (T::*func)(const Message&, TA, TB))
            Schema::Param p;
            if (Read(msg, &p)) {
                (obj->*func)(*msg, p.a, p.b);
                return true;
            return false;
        template<typename TA, typename TB>
        static bool Read(const IPC::Message* msg, TA* a, TB* b) {
            Schema::Param p;
            if (!Read(msg, &p))
                return false;
            *a = p.a;
            *b = p.b;
            return true;

MsgClassIS::MsgClassIS(const int& arg1, const std::wstring& arg2) :  IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL)
    Schema::Write(this, MakeRefTuple(arg1, arg2));

MsgClassIS::~MsgClassIS() {}
bool MsgClassIS::Read(const Message* msg, Schema::Param* p)
    return Schema::Read(msg, p);

void MsgClassIS::Log(std::string* name,const Message* msg,std::string* l)
    if (name)
        *name = “MsgClassIS”;
    if (!msg || !l)
    Schema::Param p;
    if (Schema::Read(msg, &p))
        IPC::LogParam(p, l);

If you replace “IPC_MESSAGE_CONTROL2(MsgClassIS, int, std::wstring)” with the above code and you have a working program. This one creates a message with routing ID MSG_ROUTING_CONTROL and priority PRIORITY_NORMAL.

As per \ipc\ipc_message.h, MSG_ROUTING_CONTROL means “indicates a general message not sent to a particular tab.”

This entry was posted in C/C++, Chrome, Cr-48, Internals and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s