mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-10-05 11:00:12 +02:00
500 lines
16 KiB
C++
500 lines
16 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is Mozilla IPC.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Darin Fisher <darin@netscape.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#ifndef ipcm_h__
|
|
#define ipcm_h__
|
|
|
|
#include "ipcMessage.h"
|
|
#include "ipcMessagePrimitives.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// IPCM (IPC Manager) protocol support
|
|
//
|
|
|
|
// The IPCM message target identifier:
|
|
extern const nsID IPCM_TARGET;
|
|
|
|
//
|
|
// Every IPCM message has the following structure:
|
|
//
|
|
// +-----------------------------------------+
|
|
// | (ipc message header) |
|
|
// +-----------------------------------------+
|
|
// | DWORD : type |
|
|
// +-----------------------------------------+
|
|
// | DWORD : requestIndex |
|
|
// +-----------------------------------------+
|
|
// . .
|
|
// . (payload) .
|
|
// . .
|
|
// +-----------------------------------------+
|
|
//
|
|
// where |type| is an integer uniquely identifying the message. the type is
|
|
// composed of a message class identifier and a message number. there are 3
|
|
// message classes:
|
|
//
|
|
// ACK - acknowledging a request
|
|
// REQ - making a request
|
|
// PSH - providing unrequested, "pushed" information
|
|
//
|
|
// The requestIndex field is initialized when a request is made. An
|
|
// acknowledgement's requestIndex is equal to that of its corresponding
|
|
// request message. This enables the requesting side of the message exchange
|
|
// to match acknowledgements to requests. The requestIndex field is ignored
|
|
// for PSH messages.
|
|
//
|
|
|
|
// The IPCM message class is stored in the most significant byte.
|
|
#define IPCM_MSG_CLASS_REQ (1 << 24)
|
|
#define IPCM_MSG_CLASS_ACK (2 << 24)
|
|
#define IPCM_MSG_CLASS_PSH (4 << 24)
|
|
|
|
// Requests
|
|
#define IPCM_MSG_REQ_PING (IPCM_MSG_CLASS_REQ | 1)
|
|
#define IPCM_MSG_REQ_FORWARD (IPCM_MSG_CLASS_REQ | 2)
|
|
#define IPCM_MSG_REQ_CLIENT_HELLO (IPCM_MSG_CLASS_REQ | 3)
|
|
#define IPCM_MSG_REQ_CLIENT_ADD_NAME (IPCM_MSG_CLASS_REQ | 4)
|
|
#define IPCM_MSG_REQ_CLIENT_DEL_NAME (IPCM_MSG_CLASS_REQ | 5)
|
|
#define IPCM_MSG_REQ_CLIENT_ADD_TARGET (IPCM_MSG_CLASS_REQ | 6)
|
|
#define IPCM_MSG_REQ_CLIENT_DEL_TARGET (IPCM_MSG_CLASS_REQ | 7)
|
|
#define IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME (IPCM_MSG_CLASS_REQ | 8)
|
|
#define IPCM_MSG_REQ_QUERY_CLIENT_NAMES (IPCM_MSG_CLASS_REQ | 9) // TODO
|
|
#define IPCM_MSG_REQ_QUERY_CLIENT_TARGETS (IPCM_MSG_CLASS_REQ | 10) // TODO
|
|
|
|
// Acknowledgements
|
|
#define IPCM_MSG_ACK_RESULT (IPCM_MSG_CLASS_ACK | 1)
|
|
#define IPCM_MSG_ACK_CLIENT_ID (IPCM_MSG_CLASS_ACK | 2)
|
|
#define IPCM_MSG_ACK_CLIENT_NAMES (IPCM_MSG_CLASS_ACK | 3) // TODO
|
|
#define IPCM_MSG_ACK_CLIENT_TARGETS (IPCM_MSG_CLASS_ACK | 4) // TODO
|
|
|
|
// Push messages
|
|
#define IPCM_MSG_PSH_CLIENT_STATE (IPCM_MSG_CLASS_PSH | 1)
|
|
#define IPCM_MSG_PSH_FORWARD (IPCM_MSG_CLASS_PSH | 2)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// IPCM header
|
|
//
|
|
struct ipcmMessageHeader
|
|
{
|
|
PRUint32 mType;
|
|
PRUint32 mRequestIndex;
|
|
};
|
|
|
|
//
|
|
// returns IPCM message type.
|
|
//
|
|
static inline int
|
|
IPCM_GetType(const ipcMessage *msg)
|
|
{
|
|
return ((const ipcmMessageHeader *) msg->Data())->mType;
|
|
}
|
|
|
|
//
|
|
// return IPCM message request index.
|
|
//
|
|
static inline PRUint32
|
|
IPCM_GetRequestIndex(const ipcMessage *msg)
|
|
{
|
|
return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex;
|
|
}
|
|
|
|
//
|
|
// return a request index that is unique to this process.
|
|
//
|
|
NS_HIDDEN_(PRUint32)
|
|
IPCM_NewRequestIndex();
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// The IPCM protocol is detailed below:
|
|
//
|
|
|
|
// REQUESTS
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_PING
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A PING can be sent from either a client to the daemon, or from the daemon
|
|
// to a client. The expected acknowledgement is a RESULT message with a status
|
|
// code of 0.
|
|
//
|
|
// This request message has no payload.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_FORWARD
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A FORWARD is sent when a client wishes to send a message to another client.
|
|
// The payload of this message is another message that should be forwarded by
|
|
// the daemon's IPCM to the specified client. The expected acknowledgment is
|
|
// a RESULT message with a status code indicating success or failure.
|
|
//
|
|
// When the daemon receives a FORWARD message, it creates a PSH_FORWARD message
|
|
// and sends that on to the destination client.
|
|
//
|
|
// This request message has as its payload:
|
|
//
|
|
// +-----------------------------------------+
|
|
// | DWORD : clientID |
|
|
// +-----------------------------------------+
|
|
// | (innerMsgHeader) |
|
|
// +-----------------------------------------+
|
|
// | (innerMsgData) |
|
|
// +-----------------------------------------+
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_CLIENT_HELLO
|
|
// ack: IPCM_MSG_REQ_CLIENT_ID <or> IPCM_MSG_REQ_RESULT
|
|
//
|
|
// A CLIENT_HELLO is sent when a client connects to the IPC daemon. The
|
|
// expected acknowledgement is a CLIENT_ID message informing the new client of
|
|
// its ClientID. If for some reason the IPC daemon cannot accept the new
|
|
// client, it returns a RESULT message with a failure status code.
|
|
//
|
|
// This request message has no payload.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_CLIENT_ADD_NAME
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A CLIENT_ADD_NAME is sent when a client wishes to register an additional
|
|
// name for itself. The expected acknowledgement is a RESULT message with a
|
|
// status code indicating success or failure.
|
|
//
|
|
// This request message has as its payload a null-terminated ASCII character
|
|
// string indicating the name of the client.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_CLIENT_DEL_NAME
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A CLIENT_DEL_NAME is sent when a client wishes to unregister a name that it
|
|
// has registered. The expected acknowledgement is a RESULT message with a
|
|
// status code indicating success or failure.
|
|
//
|
|
// This request message has as its payload a null-terminated ASCII character
|
|
// string indicating the name of the client.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_CLIENT_ADD_TARGET
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A CLIENT_ADD_TARGET is sent when a client wishes to register an additional
|
|
// target that it supports. The expected acknowledgement is a RESULT message
|
|
// with a status code indicating success or failure.
|
|
//
|
|
// This request message has as its payload a 128-bit UUID indicating the
|
|
// target to add.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_CLIENT_DEL_TARGET
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A CLIENT_DEL_TARGET is sent when a client wishes to unregister a target
|
|
// that it has registered. The expected acknowledgement is a RESULT message
|
|
// with a status code indicating success or failure.
|
|
//
|
|
// This request message has as its payload a 128-bit UUID indicating the
|
|
// target to remove.
|
|
//
|
|
|
|
//
|
|
// req: IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME
|
|
// ack: IPCM_MSG_ACK_CLIENT_ID <or> IPCM_MSG_ACK_RESULT
|
|
//
|
|
// A QUERY_CLIENT_BY_NAME may be sent by a client to discover the client that
|
|
// is known by a common name. If more than one client matches the name, then
|
|
// only the ID of the more recently registered client is returned. The
|
|
// expected acknowledgement is a CLIENT_ID message carrying the ID of the
|
|
// corresponding client. If no client matches the given name or if some error
|
|
// occurs, then a RESULT message with a failure status code is returned.
|
|
//
|
|
// This request message has as its payload a null-terminated ASCII character
|
|
// string indicating the client name to query.
|
|
//
|
|
|
|
// ACKNOWLEDGEMENTS
|
|
|
|
//
|
|
// ack: IPCM_MSG_ACK_RESULT
|
|
//
|
|
// This acknowledgement is returned to indicate a success or failure status.
|
|
//
|
|
// The payload consists of a single DWORD value.
|
|
//
|
|
// Possible status codes are listed below (negative values indicate failure
|
|
// codes):
|
|
//
|
|
#define IPCM_OK 0 // success: generic
|
|
#define IPCM_ERROR_GENERIC -1 // failure: generic
|
|
#define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist
|
|
|
|
//
|
|
// ack: IPCM_MSG_ACK_CLIENT_ID
|
|
//
|
|
// This acknowledgement is returned to specify a client ID.
|
|
//
|
|
// The payload consists of a single DWORD value.
|
|
//
|
|
|
|
// PUSH MESSAGES
|
|
|
|
//
|
|
// psh: ICPM_MSG_PSH_CLIENT_STATE
|
|
//
|
|
// This message is sent to clients to indicate the status of other clients.
|
|
//
|
|
// The payload consists of:
|
|
//
|
|
// +-----------------------------------------+
|
|
// | DWORD : clientID |
|
|
// +-----------------------------------------+
|
|
// | DWORD : clientState |
|
|
// +-----------------------------------------+
|
|
//
|
|
// where, clientState is one of the following values indicating whether the
|
|
// client has recently connected (up) or disconnected (down):
|
|
//
|
|
#define IPCM_CLIENT_STATE_UP 1
|
|
#define IPCM_CLIENT_STATE_DOWN 2
|
|
|
|
//
|
|
// psh: IPCM_MSG_PSH_FORWARD
|
|
//
|
|
// This message is sent by the daemon to a client on behalf of another client.
|
|
// The recipient is expected to unpack the contained message and process it.
|
|
//
|
|
// The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD,
|
|
// with the exception that the clientID field is set to the clientID of the
|
|
// sender of the IPCM_MSG_REQ_FORWARD message.
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// NOTE: This file declares some helper classes that simplify constructing
|
|
// and parsing IPCM messages. Each class subclasses ipcMessage, but
|
|
// adds no additional member variables. |operator new| should be used
|
|
// to allocate one of the IPCM helper classes, e.g.:
|
|
//
|
|
// ipcMessage *msg = new ipcmMessageClientHello("foo");
|
|
//
|
|
// Given an arbitrary ipcMessage, it can be parsed using logic similar
|
|
// to the following:
|
|
//
|
|
// void func(const ipcMessage *unknown)
|
|
// {
|
|
// if (unknown->Topic().Equals(IPCM_TARGET)) {
|
|
// if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) {
|
|
// ipcMessageCast<ipcmMessageClientID> msg(unknown);
|
|
// printf("Client ID: %u\n", msg->ClientID());
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
|
|
// REQUESTS
|
|
|
|
class ipcmMessagePing : public ipcMessage_DWORD_DWORD
|
|
{
|
|
public:
|
|
ipcmMessagePing()
|
|
: ipcMessage_DWORD_DWORD(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_PING,
|
|
IPCM_NewRequestIndex()) {}
|
|
};
|
|
|
|
class ipcmMessageForward : public ipcMessage
|
|
{
|
|
public:
|
|
// @param type the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD
|
|
// @param clientID the client id of the sender or receiver
|
|
// @param target the message target
|
|
// @param data the message data
|
|
// @param dataLen the message data length
|
|
ipcmMessageForward(PRUint32 type,
|
|
PRUint32 clientID,
|
|
const nsID &target,
|
|
const char *data,
|
|
PRUint32 dataLen) NS_HIDDEN;
|
|
|
|
// set inner message data, constrained to the data length passed
|
|
// to this class's constructor.
|
|
NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen);
|
|
|
|
NS_HIDDEN_(PRUint32) ClientID() const;
|
|
NS_HIDDEN_(const nsID &) InnerTarget() const;
|
|
NS_HIDDEN_(const char *) InnerData() const;
|
|
NS_HIDDEN_(PRUint32) InnerDataLen() const;
|
|
};
|
|
|
|
class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD
|
|
{
|
|
public:
|
|
ipcmMessageClientHello()
|
|
: ipcMessage_DWORD_DWORD(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_CLIENT_HELLO,
|
|
IPCM_NewRequestIndex()) {}
|
|
};
|
|
|
|
class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR
|
|
{
|
|
public:
|
|
ipcmMessageClientAddName(const char *name)
|
|
: ipcMessage_DWORD_DWORD_STR(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_CLIENT_ADD_NAME,
|
|
IPCM_NewRequestIndex(),
|
|
name) {}
|
|
|
|
const char *Name() const { return Third(); }
|
|
};
|
|
|
|
class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR
|
|
{
|
|
public:
|
|
ipcmMessageClientDelName(const char *name)
|
|
: ipcMessage_DWORD_DWORD_STR(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_CLIENT_DEL_NAME,
|
|
IPCM_NewRequestIndex(),
|
|
name) {}
|
|
|
|
const char *Name() const { return Third(); }
|
|
};
|
|
|
|
class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID
|
|
{
|
|
public:
|
|
ipcmMessageClientAddTarget(const nsID &target)
|
|
: ipcMessage_DWORD_DWORD_ID(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_CLIENT_ADD_TARGET,
|
|
IPCM_NewRequestIndex(),
|
|
target) {}
|
|
|
|
const nsID &Target() const { return Third(); }
|
|
};
|
|
|
|
class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID
|
|
{
|
|
public:
|
|
ipcmMessageClientDelTarget(const nsID &target)
|
|
: ipcMessage_DWORD_DWORD_ID(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_CLIENT_ADD_TARGET,
|
|
IPCM_NewRequestIndex(),
|
|
target) {}
|
|
|
|
const nsID &Target() const { return Third(); }
|
|
};
|
|
|
|
class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR
|
|
{
|
|
public:
|
|
ipcmMessageQueryClientByName(const char *name)
|
|
: ipcMessage_DWORD_DWORD_STR(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME,
|
|
IPCM_NewRequestIndex(),
|
|
name) {}
|
|
|
|
const char *Name() const { return Third(); }
|
|
PRUint32 RequestIndex() const { return Second(); }
|
|
};
|
|
|
|
// ACKNOWLEDGEMENTS
|
|
|
|
class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD
|
|
{
|
|
public:
|
|
ipcmMessageResult(PRUint32 requestIndex, PRInt32 status)
|
|
: ipcMessage_DWORD_DWORD_DWORD(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_ACK_RESULT,
|
|
requestIndex,
|
|
(PRUint32) status) {}
|
|
|
|
PRInt32 Status() const { return (PRInt32) Third(); }
|
|
};
|
|
|
|
class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD
|
|
{
|
|
public:
|
|
ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID)
|
|
: ipcMessage_DWORD_DWORD_DWORD(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_ACK_CLIENT_ID,
|
|
requestIndex,
|
|
clientID) {}
|
|
|
|
PRUint32 ClientID() const { return Third(); }
|
|
};
|
|
|
|
// PUSH MESSAGES
|
|
|
|
class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD
|
|
{
|
|
public:
|
|
ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus)
|
|
: ipcMessage_DWORD_DWORD_DWORD_DWORD(
|
|
IPCM_TARGET,
|
|
IPCM_MSG_PSH_CLIENT_STATE,
|
|
0,
|
|
clientID,
|
|
clientStatus) {}
|
|
|
|
PRUint32 ClientID() const { return Third(); }
|
|
PRUint32 ClientState() const { return Fourth(); }
|
|
};
|
|
|
|
#endif // !ipcm_h__
|