Bug 458256. Use LoadLibraryW instead of LoadLibrary (patch by DougT). r+sr=vlad
[wine-gecko.git] / ipc / ipcd / shared / src / ipcm.h
blob4f4c59c84268d6aef710171860b3777e67a70ae2
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is Mozilla IPC.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2002
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Darin Fisher <darin@netscape.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef ipcm_h__
39 #define ipcm_h__
41 #include "ipcMessage.h"
42 #include "ipcMessagePrimitives.h"
44 //-----------------------------------------------------------------------------
47 // IPCM (IPC Manager) protocol support
50 // The IPCM message target identifier:
51 extern const nsID IPCM_TARGET;
54 // Every IPCM message has the following structure:
56 // +-----------------------------------------+
57 // | (ipc message header) |
58 // +-----------------------------------------+
59 // | DWORD : type |
60 // +-----------------------------------------+
61 // | DWORD : requestIndex |
62 // +-----------------------------------------+
63 // . .
64 // . (payload) .
65 // . .
66 // +-----------------------------------------+
68 // where |type| is an integer uniquely identifying the message. the type is
69 // composed of a message class identifier and a message number. there are 3
70 // message classes:
72 // ACK - acknowledging a request
73 // REQ - making a request
74 // PSH - providing unrequested, "pushed" information
76 // The requestIndex field is initialized when a request is made. An
77 // acknowledgement's requestIndex is equal to that of its corresponding
78 // request message. This enables the requesting side of the message exchange
79 // to match acknowledgements to requests. The requestIndex field is ignored
80 // for PSH messages.
83 // The IPCM message class is stored in the most significant byte.
84 #define IPCM_MSG_CLASS_REQ (1 << 24)
85 #define IPCM_MSG_CLASS_ACK (2 << 24)
86 #define IPCM_MSG_CLASS_PSH (4 << 24)
88 // Requests
89 #define IPCM_MSG_REQ_PING (IPCM_MSG_CLASS_REQ | 1)
90 #define IPCM_MSG_REQ_FORWARD (IPCM_MSG_CLASS_REQ | 2)
91 #define IPCM_MSG_REQ_CLIENT_HELLO (IPCM_MSG_CLASS_REQ | 3)
92 #define IPCM_MSG_REQ_CLIENT_ADD_NAME (IPCM_MSG_CLASS_REQ | 4)
93 #define IPCM_MSG_REQ_CLIENT_DEL_NAME (IPCM_MSG_CLASS_REQ | 5)
94 #define IPCM_MSG_REQ_CLIENT_ADD_TARGET (IPCM_MSG_CLASS_REQ | 6)
95 #define IPCM_MSG_REQ_CLIENT_DEL_TARGET (IPCM_MSG_CLASS_REQ | 7)
96 #define IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME (IPCM_MSG_CLASS_REQ | 8)
97 #define IPCM_MSG_REQ_QUERY_CLIENT_NAMES (IPCM_MSG_CLASS_REQ | 9) // TODO
98 #define IPCM_MSG_REQ_QUERY_CLIENT_TARGETS (IPCM_MSG_CLASS_REQ | 10) // TODO
100 // Acknowledgements
101 #define IPCM_MSG_ACK_RESULT (IPCM_MSG_CLASS_ACK | 1)
102 #define IPCM_MSG_ACK_CLIENT_ID (IPCM_MSG_CLASS_ACK | 2)
103 #define IPCM_MSG_ACK_CLIENT_NAMES (IPCM_MSG_CLASS_ACK | 3) // TODO
104 #define IPCM_MSG_ACK_CLIENT_TARGETS (IPCM_MSG_CLASS_ACK | 4) // TODO
106 // Push messages
107 #define IPCM_MSG_PSH_CLIENT_STATE (IPCM_MSG_CLASS_PSH | 1)
108 #define IPCM_MSG_PSH_FORWARD (IPCM_MSG_CLASS_PSH | 2)
110 //-----------------------------------------------------------------------------
113 // IPCM header
115 struct ipcmMessageHeader
117 PRUint32 mType;
118 PRUint32 mRequestIndex;
122 // returns IPCM message type.
124 static inline int
125 IPCM_GetType(const ipcMessage *msg)
127 return ((const ipcmMessageHeader *) msg->Data())->mType;
131 // return IPCM message request index.
133 static inline PRUint32
134 IPCM_GetRequestIndex(const ipcMessage *msg)
136 return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex;
140 // return a request index that is unique to this process.
142 NS_HIDDEN_(PRUint32)
143 IPCM_NewRequestIndex();
145 //-----------------------------------------------------------------------------
148 // The IPCM protocol is detailed below:
151 // REQUESTS
154 // req: IPCM_MSG_REQ_PING
155 // ack: IPCM_MSG_ACK_RESULT
157 // A PING can be sent from either a client to the daemon, or from the daemon
158 // to a client. The expected acknowledgement is a RESULT message with a status
159 // code of 0.
161 // This request message has no payload.
165 // req: IPCM_MSG_REQ_FORWARD
166 // ack: IPCM_MSG_ACK_RESULT
168 // A FORWARD is sent when a client wishes to send a message to another client.
169 // The payload of this message is another message that should be forwarded by
170 // the daemon's IPCM to the specified client. The expected acknowledgment is
171 // a RESULT message with a status code indicating success or failure.
173 // When the daemon receives a FORWARD message, it creates a PSH_FORWARD message
174 // and sends that on to the destination client.
176 // This request message has as its payload:
178 // +-----------------------------------------+
179 // | DWORD : clientID |
180 // +-----------------------------------------+
181 // | (innerMsgHeader) |
182 // +-----------------------------------------+
183 // | (innerMsgData) |
184 // +-----------------------------------------+
188 // req: IPCM_MSG_REQ_CLIENT_HELLO
189 // ack: IPCM_MSG_REQ_CLIENT_ID <or> IPCM_MSG_REQ_RESULT
191 // A CLIENT_HELLO is sent when a client connects to the IPC daemon. The
192 // expected acknowledgement is a CLIENT_ID message informing the new client of
193 // its ClientID. If for some reason the IPC daemon cannot accept the new
194 // client, it returns a RESULT message with a failure status code.
196 // This request message has no payload.
200 // req: IPCM_MSG_REQ_CLIENT_ADD_NAME
201 // ack: IPCM_MSG_ACK_RESULT
203 // A CLIENT_ADD_NAME is sent when a client wishes to register an additional
204 // name for itself. The expected acknowledgement is a RESULT message with a
205 // status code indicating success or failure.
207 // This request message has as its payload a null-terminated ASCII character
208 // string indicating the name of the client.
212 // req: IPCM_MSG_REQ_CLIENT_DEL_NAME
213 // ack: IPCM_MSG_ACK_RESULT
215 // A CLIENT_DEL_NAME is sent when a client wishes to unregister a name that it
216 // has registered. The expected acknowledgement is a RESULT message with a
217 // status code indicating success or failure.
219 // This request message has as its payload a null-terminated ASCII character
220 // string indicating the name of the client.
224 // req: IPCM_MSG_REQ_CLIENT_ADD_TARGET
225 // ack: IPCM_MSG_ACK_RESULT
227 // A CLIENT_ADD_TARGET is sent when a client wishes to register an additional
228 // target that it supports. The expected acknowledgement is a RESULT message
229 // with a status code indicating success or failure.
231 // This request message has as its payload a 128-bit UUID indicating the
232 // target to add.
236 // req: IPCM_MSG_REQ_CLIENT_DEL_TARGET
237 // ack: IPCM_MSG_ACK_RESULT
239 // A CLIENT_DEL_TARGET is sent when a client wishes to unregister a target
240 // that it has registered. The expected acknowledgement is a RESULT message
241 // with a status code indicating success or failure.
243 // This request message has as its payload a 128-bit UUID indicating the
244 // target to remove.
248 // req: IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME
249 // ack: IPCM_MSG_ACK_CLIENT_ID <or> IPCM_MSG_ACK_RESULT
251 // A QUERY_CLIENT_BY_NAME may be sent by a client to discover the client that
252 // is known by a common name. If more than one client matches the name, then
253 // only the ID of the more recently registered client is returned. The
254 // expected acknowledgement is a CLIENT_ID message carrying the ID of the
255 // corresponding client. If no client matches the given name or if some error
256 // occurs, then a RESULT message with a failure status code is returned.
258 // This request message has as its payload a null-terminated ASCII character
259 // string indicating the client name to query.
262 // ACKNOWLEDGEMENTS
265 // ack: IPCM_MSG_ACK_RESULT
267 // This acknowledgement is returned to indicate a success or failure status.
269 // The payload consists of a single DWORD value.
271 // Possible status codes are listed below (negative values indicate failure
272 // codes):
274 #define IPCM_OK 0 // success: generic
275 #define IPCM_ERROR_GENERIC -1 // failure: generic
276 #define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist
279 // ack: IPCM_MSG_ACK_CLIENT_ID
281 // This acknowledgement is returned to specify a client ID.
283 // The payload consists of a single DWORD value.
286 // PUSH MESSAGES
289 // psh: ICPM_MSG_PSH_CLIENT_STATE
291 // This message is sent to clients to indicate the status of other clients.
293 // The payload consists of:
295 // +-----------------------------------------+
296 // | DWORD : clientID |
297 // +-----------------------------------------+
298 // | DWORD : clientState |
299 // +-----------------------------------------+
301 // where, clientState is one of the following values indicating whether the
302 // client has recently connected (up) or disconnected (down):
304 #define IPCM_CLIENT_STATE_UP 1
305 #define IPCM_CLIENT_STATE_DOWN 2
308 // psh: IPCM_MSG_PSH_FORWARD
310 // This message is sent by the daemon to a client on behalf of another client.
311 // The recipient is expected to unpack the contained message and process it.
313 // The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD,
314 // with the exception that the clientID field is set to the clientID of the
315 // sender of the IPCM_MSG_REQ_FORWARD message.
318 //-----------------------------------------------------------------------------
321 // NOTE: This file declares some helper classes that simplify constructing
322 // and parsing IPCM messages. Each class subclasses ipcMessage, but
323 // adds no additional member variables. |operator new| should be used
324 // to allocate one of the IPCM helper classes, e.g.:
326 // ipcMessage *msg = new ipcmMessageClientHello("foo");
328 // Given an arbitrary ipcMessage, it can be parsed using logic similar
329 // to the following:
331 // void func(const ipcMessage *unknown)
332 // {
333 // if (unknown->Topic().Equals(IPCM_TARGET)) {
334 // if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) {
335 // ipcMessageCast<ipcmMessageClientID> msg(unknown);
336 // printf("Client ID: %u\n", msg->ClientID());
337 // }
338 // }
339 // }
342 // REQUESTS
344 class ipcmMessagePing : public ipcMessage_DWORD_DWORD
346 public:
347 ipcmMessagePing()
348 : ipcMessage_DWORD_DWORD(
349 IPCM_TARGET,
350 IPCM_MSG_REQ_PING,
351 IPCM_NewRequestIndex()) {}
354 class ipcmMessageForward : public ipcMessage
356 public:
357 // @param type the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD
358 // @param clientID the client id of the sender or receiver
359 // @param target the message target
360 // @param data the message data
361 // @param dataLen the message data length
362 ipcmMessageForward(PRUint32 type,
363 PRUint32 clientID,
364 const nsID &target,
365 const char *data,
366 PRUint32 dataLen) NS_HIDDEN;
368 // set inner message data, constrained to the data length passed
369 // to this class's constructor.
370 NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen);
372 NS_HIDDEN_(PRUint32) ClientID() const;
373 NS_HIDDEN_(const nsID &) InnerTarget() const;
374 NS_HIDDEN_(const char *) InnerData() const;
375 NS_HIDDEN_(PRUint32) InnerDataLen() const;
378 class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD
380 public:
381 ipcmMessageClientHello()
382 : ipcMessage_DWORD_DWORD(
383 IPCM_TARGET,
384 IPCM_MSG_REQ_CLIENT_HELLO,
385 IPCM_NewRequestIndex()) {}
388 class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR
390 public:
391 ipcmMessageClientAddName(const char *name)
392 : ipcMessage_DWORD_DWORD_STR(
393 IPCM_TARGET,
394 IPCM_MSG_REQ_CLIENT_ADD_NAME,
395 IPCM_NewRequestIndex(),
396 name) {}
398 const char *Name() const { return Third(); }
401 class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR
403 public:
404 ipcmMessageClientDelName(const char *name)
405 : ipcMessage_DWORD_DWORD_STR(
406 IPCM_TARGET,
407 IPCM_MSG_REQ_CLIENT_DEL_NAME,
408 IPCM_NewRequestIndex(),
409 name) {}
411 const char *Name() const { return Third(); }
414 class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID
416 public:
417 ipcmMessageClientAddTarget(const nsID &target)
418 : ipcMessage_DWORD_DWORD_ID(
419 IPCM_TARGET,
420 IPCM_MSG_REQ_CLIENT_ADD_TARGET,
421 IPCM_NewRequestIndex(),
422 target) {}
424 const nsID &Target() const { return Third(); }
427 class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID
429 public:
430 ipcmMessageClientDelTarget(const nsID &target)
431 : ipcMessage_DWORD_DWORD_ID(
432 IPCM_TARGET,
433 IPCM_MSG_REQ_CLIENT_ADD_TARGET,
434 IPCM_NewRequestIndex(),
435 target) {}
437 const nsID &Target() const { return Third(); }
440 class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR
442 public:
443 ipcmMessageQueryClientByName(const char *name)
444 : ipcMessage_DWORD_DWORD_STR(
445 IPCM_TARGET,
446 IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME,
447 IPCM_NewRequestIndex(),
448 name) {}
450 const char *Name() const { return Third(); }
451 PRUint32 RequestIndex() const { return Second(); }
454 // ACKNOWLEDGEMENTS
456 class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD
458 public:
459 ipcmMessageResult(PRUint32 requestIndex, PRInt32 status)
460 : ipcMessage_DWORD_DWORD_DWORD(
461 IPCM_TARGET,
462 IPCM_MSG_ACK_RESULT,
463 requestIndex,
464 (PRUint32) status) {}
466 PRInt32 Status() const { return (PRInt32) Third(); }
469 class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD
471 public:
472 ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID)
473 : ipcMessage_DWORD_DWORD_DWORD(
474 IPCM_TARGET,
475 IPCM_MSG_ACK_CLIENT_ID,
476 requestIndex,
477 clientID) {}
479 PRUint32 ClientID() const { return Third(); }
482 // PUSH MESSAGES
484 class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD
486 public:
487 ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus)
488 : ipcMessage_DWORD_DWORD_DWORD_DWORD(
489 IPCM_TARGET,
490 IPCM_MSG_PSH_CLIENT_STATE,
492 clientID,
493 clientStatus) {}
495 PRUint32 ClientID() const { return Third(); }
496 PRUint32 ClientState() const { return Fourth(); }
499 #endif // !ipcm_h__