Index: trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp	(revision 103563)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp	(revision 103569)
@@ -38,6 +38,4 @@
 #define LOG_GROUP LOG_GROUP_IPC
 #include "ipcDConnectService.h"
-#include "ipcMessageWriter.h"
-#include "ipcMsgReader.h"
 
 #include "nsIServiceManagerUtils.h"
@@ -321,5 +319,5 @@
 
 static nsresult
-SerializeParam(ipcMessageWriter &writer, const nsXPTType &t, const nsXPTCMiniVariant &v)
+SerializeParam(PIPCMSGWRITER pMsgWriter, const nsXPTType &t, const nsXPTCMiniVariant &v)
 {
   switch (t.TagPart())
@@ -327,40 +325,40 @@
     case nsXPTType::T_I8:
     case nsXPTType::T_U8:
-      writer.PutInt8(v.val.u8);
+      IPCMsgWriterPutU8(pMsgWriter, v.val.u8);
       break;
 
     case nsXPTType::T_I16:
     case nsXPTType::T_U16:
-      writer.PutInt16(v.val.u16);
+      IPCMsgWriterPutU16(pMsgWriter, v.val.u16);
       break;
 
     case nsXPTType::T_I32:
     case nsXPTType::T_U32:
-      writer.PutInt32(v.val.u32);
+      IPCMsgWriterPutU32(pMsgWriter, v.val.u32);
       break;
 
     case nsXPTType::T_I64:
     case nsXPTType::T_U64:
-      writer.PutBytes(&v.val.u64, sizeof(PRUint64));
+      IPCMsgWriterPutU64(pMsgWriter, v.val.u64);
       break;
 
     case nsXPTType::T_FLOAT:
-      writer.PutBytes(&v.val.f, sizeof(float));
+      IPCMsgWriterPutBytes(pMsgWriter, &v.val.f, sizeof(float));
       break;
 
     case nsXPTType::T_DOUBLE:
-      writer.PutBytes(&v.val.d, sizeof(double));
+      IPCMsgWriterPutBytes(pMsgWriter, &v.val.d, sizeof(double));
       break;
 
     case nsXPTType::T_BOOL:
-      writer.PutBytes(&v.val.b, sizeof(PRBool));
+      IPCMsgWriterPutBytes(pMsgWriter, &v.val.b, sizeof(PRBool));
       break;
 
     case nsXPTType::T_CHAR:
-      writer.PutBytes(&v.val.c, sizeof(char));
+      IPCMsgWriterPutBytes(pMsgWriter, &v.val.c, sizeof(char));
       break;
 
     case nsXPTType::T_WCHAR:
-      writer.PutBytes(&v.val.wc, sizeof(PRUnichar));
+      IPCMsgWriterPutBytes(pMsgWriter, &v.val.wc, sizeof(PRUnichar));
       break;
 
@@ -368,5 +366,5 @@
       {
         AssertReturn(v.val.p, NS_ERROR_INVALID_POINTER);
-        writer.PutBytes(v.val.p, sizeof(nsID));
+        IPCMsgWriterPutBytes(pMsgWriter, v.val.p, sizeof(nsID));
       }
       break;
@@ -377,11 +375,11 @@
         {
           int len = strlen((const char *) v.val.p);
-          writer.PutInt32(len);
-          writer.PutBytes(v.val.p, len);
+          IPCMsgWriterPutU32(pMsgWriter, len);
+          IPCMsgWriterPutBytes(pMsgWriter, v.val.p, len);
         }
         else
         {
           // put -1 to indicate null string
-          writer.PutInt32((PRUint32) -1);
+          IPCMsgWriterPutU32(pMsgWriter, (PRUint32) -1);
         }
       }
@@ -393,11 +391,11 @@
         {
           int len = 2 * nsCRT::strlen((const PRUnichar *) v.val.p);
-          writer.PutInt32(len);
-          writer.PutBytes(v.val.p, len);
+          IPCMsgWriterPutU32(pMsgWriter, len);
+          IPCMsgWriterPutBytes(pMsgWriter, v.val.p, len);
         }
         else
         {
           // put -1 to indicate null string
-          writer.PutInt32((PRUint32) -1);
+          IPCMsgWriterPutU32(pMsgWriter, (PRUint32) -1);
         }
       }
@@ -418,6 +416,6 @@
         const PRUnichar *data = str->BeginReading(begin).get();
 
-        writer.PutInt32(len);
-        writer.PutBytes(data, len);
+        IPCMsgWriterPutU32(pMsgWriter, len);
+        IPCMsgWriterPutBytes(pMsgWriter, data, len);
       }
       break;
@@ -432,6 +430,6 @@
         const char *data = str->BeginReading(begin).get();
 
-        writer.PutInt32(len);
-        writer.PutBytes(data, len);
+        IPCMsgWriterPutU32(pMsgWriter, len);
+        IPCMsgWriterPutBytes(pMsgWriter, data, len);
       }
       break;
@@ -996,5 +994,5 @@
 static nsresult
 SerializeArrayParam(ipcDConnectService *dConnect,
-                    ipcMessageWriter &writer, PRUint32 peerID,
+                    PIPCMSGWRITER pMsgWriter, PRUint32 peerID,
                     nsIInterfaceInfo *iinfo, uint16 methodIndex,
                     const nsXPTMethodInfo &methodInfo,
@@ -1006,10 +1004,10 @@
   {
     // put 0 to indicate null array
-    writer.PutInt8(0);
+    IPCMsgWriterPutU8(pMsgWriter, 0);
     return NS_OK;
   }
 
   // put 1 to indicate non-null array
-  writer.PutInt8(1);
+  IPCMsgWriterPutU8(pMsgWriter, 1);
 
   PRUint32 size = 0;
@@ -1032,5 +1030,5 @@
   {
     // this is a simple arithmetic type, write the whole array at once
-    writer.PutBytes(array, length * elemSize);
+    IPCMsgWriterPutBytes(pMsgWriter, array, length * elemSize);
     return NS_OK;
   }
@@ -1050,10 +1048,10 @@
                                           iid);
       if (NS_SUCCEEDED(rv))
-        rv = dConnect->SerializeInterfaceParam(writer, peerID, iid,
+        rv = dConnect->SerializeInterfaceParam(pMsgWriter, peerID, iid,
                                                (nsISupports *) v.val.p,
                                                wrappers);
     }
     else
-      rv = SerializeParam(writer, elemType, v);
+      rv = SerializeParam(pMsgWriter, elemType, v);
 
     if (NS_FAILED(rv))
@@ -1631,5 +1629,5 @@
 
 nsresult
-ipcDConnectService::SerializeInterfaceParam(ipcMessageWriter &writer,
+ipcDConnectService::SerializeInterfaceParam(PIPCMSGWRITER pMsgWriter,
                                             PRUint32 peer, const nsID &iid,
                                             nsISupports *obj,
@@ -1661,5 +1659,5 @@
     // write null address
     DConAddr nullobj = 0;
-    writer.PutBytes(&nullobj, sizeof(nullobj));
+    IPCMsgWriterPutBytes(pMsgWriter, &nullobj, sizeof(nullobj));
   }
   else
@@ -1670,5 +1668,5 @@
     {
       DConAddr p = stub->Instance();
-      writer.PutBytes(&p, sizeof(p));
+      IPCMsgWriterPutBytes(pMsgWriter, &p, sizeof(p));
     }
     else
@@ -1721,5 +1719,5 @@
       NS_ASSERTION((bits & PTRBITS_REMOTE_BIT) == 0, "remote bit wrong)");
       bits |= PTRBITS_REMOTE_BIT;
-      writer.PutBytes(&bits, sizeof(bits));
+      IPCMsgWriterPutBytes(pMsgWriter, &bits, sizeof(bits));
     }
     NS_IF_RELEASE(stub);
@@ -1952,5 +1950,5 @@
 
 nsresult
-ipcDConnectService::SerializeException(ipcMessageWriter &writer,
+ipcDConnectService::SerializeException(PIPCMSGWRITER pMsgWriter,
                                        PRUint32 peer, nsIException *xcpt,
                                        nsVoidArray &wrappers)
@@ -1976,7 +1974,7 @@
       // see ipcDConnectService::DeserializeException()!
       PtrBits bits = 0;
-      writer.PutBytes(&bits, sizeof(bits));
+      IPCMsgWriterPutBytes(pMsgWriter, &bits, sizeof(bits));
 #else
-      writer.PutBytes(&xcpt, sizeof(xcpt));
+      IPCMsgWriterPutBytes(pMsgWriter, &xcpt, sizeof(xcpt));
 #endif
     }
@@ -1989,5 +1987,5 @@
         // send the wrapper instance back to the peer
         DConAddr p = stub->Stub()->Instance();
-        writer.PutBytes(&p, sizeof(p));
+        IPCMsgWriterPutBytes(pMsgWriter, &p, sizeof(p));
       }
       else
@@ -2039,5 +2037,5 @@
         // to the remote party that this is a remote instance wrapper.
         PtrBits bits = ((PtrBits)(uintptr_t) wrapper) | PTRBITS_REMOTE_BIT;
-        writer.PutBytes(&bits, sizeof(bits));
+        IPCMsgWriterPutBytes(pMsgWriter, &bits, sizeof(bits));
 
         // we want to cache fields to minimize the number of IPC calls when
@@ -2063,14 +2061,14 @@
     nsACString::const_iterator begin;
     const char *data = str.BeginReading(begin).get();
-    writer.PutInt32(len);
-    writer.PutBytes(data, len);
+    IPCMsgWriterPutU32(pMsgWriter, len);
+    IPCMsgWriterPutBytes(pMsgWriter, data, len);
   }
   else
-    writer.PutInt32(0);
+    IPCMsgWriterPutU32(pMsgWriter, 0);
 
   // result
   nsresult res = 0;
   xcpt->GetResult(&res);
-  writer.PutInt32(res);
+  IPCMsgWriterPutU32(pMsgWriter, res);
 
   // name
@@ -2081,9 +2079,9 @@
     nsACString::const_iterator begin;
     const char *data = str.BeginReading(begin).get();
-    writer.PutInt32(len);
-    writer.PutBytes(data, len);
+    IPCMsgWriterPutU32(pMsgWriter, len);
+    IPCMsgWriterPutBytes(pMsgWriter, data, len);
   }
   else
-    writer.PutInt32(0);
+    IPCMsgWriterPutU32(pMsgWriter, 0);
 
   // filename
@@ -2094,21 +2092,21 @@
     nsACString::const_iterator begin;
     const char *data = str.BeginReading(begin).get();
-    writer.PutInt32(len);
-    writer.PutBytes(data, len);
+    IPCMsgWriterPutU32(pMsgWriter, len);
+    IPCMsgWriterPutBytes(pMsgWriter, data, len);
   }
   else
-    writer.PutInt32(0);
+    IPCMsgWriterPutU32(pMsgWriter, 0);
 
   // lineNumber
   num = 0;
   xcpt->GetLineNumber(&num);
-  writer.PutInt32(num);
+  IPCMsgWriterPutU32(pMsgWriter, num);
 
   // columnNumber
   num = 0;
   xcpt->GetColumnNumber(&num);
-  writer.PutInt32(num);
-
-  return writer.HasError() ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+  IPCMsgWriterPutU32(pMsgWriter, num);
+
+  return IPCMsgWriterHasError(pMsgWriter) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
 }
 
@@ -2526,6 +2524,6 @@
 #endif
 
-
-  ipcMessageWriter writer(16 * paramCount);
+  IPCMSGWRITER MsgWriter;
+  IPCMsgWriterInit(&MsgWriter, 16 * paramCount);
 
   // INVOKE message header
@@ -2540,5 +2538,5 @@
   Log(("  request-index=%d\n", (PRUint32) invoke.request_index));
 
-  writer.PutBytes(&invoke, sizeof(invoke));
+  IPCMsgWriterPutBytes(&MsgWriter, &invoke, sizeof(invoke));
 
   // list of wrappers that get created during parameter serialization.  if we
@@ -2560,10 +2558,10 @@
                                              aMethodIndex, aParams, PR_FALSE, iid);
         if (NS_SUCCEEDED(rv))
-          rv = dConnect->SerializeInterfaceParam(writer, mPeerID, iid,
+          rv = dConnect->SerializeInterfaceParam(&MsgWriter, mPeerID, iid,
                                                  (nsISupports *) aParams[i].val.p,
                                                  wrappers);
       }
       else
-        rv = SerializeParam(writer, type, aParams[i]);
+        rv = SerializeParam(&MsgWriter, type, aParams[i]);
 
       AssertMsgBreak(NS_SUCCEEDED(rv), ("i=%d rv=%#x\n", i, rv));
@@ -2582,4 +2580,5 @@
     // INVOKE message wasn't sent; clean up wrappers
     dConnect->ReleaseWrappers(wrappers, mPeerID);
+    IPCMsgWriterCleanup(&MsgWriter);
     return rv;
   }
@@ -2595,5 +2594,5 @@
         paramInfo.IsIn() && !paramInfo.IsDipper())
     {
-      rv = SerializeArrayParam(dConnect, writer, mPeerID, mIInfo, aMethodIndex,
+      rv = SerializeArrayParam(dConnect, &MsgWriter, mPeerID, mIInfo, aMethodIndex,
                                *aInfo, aParams, PR_FALSE, paramInfo,
                                aParams[i].val.p, wrappers);
@@ -2602,4 +2601,5 @@
         // INVOKE message wasn't sent; clean up wrappers
         dConnect->ReleaseWrappers(wrappers, mPeerID);
+        IPCMsgWriterCleanup(&MsgWriter);
         return rv;
       }
@@ -2612,6 +2612,8 @@
 
   rv = IPC_SendMessage(mPeerID, kDConnectTargetID,
-                       writer.GetBuffer(),
-                       writer.GetSize());
+                       IPCMsgWriterGetBuf(&MsgWriter),
+                       IPCMsgWriterGetSize(&MsgWriter));
+  IPCMsgWriterCleanup(&MsgWriter);
+
   Log(("DConnectStub::CallMethod: IPC_SendMessage()=%08X\n", rv));
   if (NS_FAILED(rv))
@@ -3584,5 +3586,6 @@
   }
 
-  ipcMessageWriter writer(64);
+  IPCMSGWRITER MsgWriter;
+  IPCMsgWriterInit(&MsgWriter, 64 /*cbInitial*/);
 
   DConnectSetupReply msg;
@@ -3597,9 +3600,9 @@
     msg.flags |= DCON_OP_FLAGS_REPLY_EXCEPTION;
 
-  writer.PutBytes(&msg, sizeof(msg));
+  IPCMsgWriterPutBytes(&MsgWriter, &msg, sizeof(msg));
 
   if (got_exception)
   {
-    rv = SerializeException(writer, peer, exception, wrappers);
+    rv = SerializeException(&MsgWriter, peer, exception, wrappers);
     NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialize exception");
   }
@@ -3611,5 +3614,5 @@
   else
     rv = IPC_SendMessage(peer, kDConnectTargetID,
-                         writer.GetBuffer(), writer.GetSize());
+                         IPCMsgWriterGetBuf(&MsgWriter), IPCMsgWriterGetSize(&MsgWriter));
 
   if (NS_FAILED(rv))
@@ -3618,4 +3621,6 @@
     ReleaseWrappers(wrappers, peer);
   }
+
+  IPCMsgWriterCleanup(&MsgWriter);
 }
 
@@ -3813,5 +3818,6 @@
     wrapper->Release();
 
-  ipcMessageWriter writer(64);
+  IPCMSGWRITER MsgWriter;
+  IPCMsgWriterInit(&MsgWriter, 64 /*cbInitial*/);
 
   DConnectInvokeReply reply;
@@ -3825,5 +3831,5 @@
     reply.flags |= DCON_OP_FLAGS_REPLY_EXCEPTION;
 
-  writer.PutBytes(&reply, sizeof(reply));
+  IPCMsgWriterPutBytes(&MsgWriter, &reply, sizeof(reply));
 
   nsVoidArray wrappers;
@@ -3846,9 +3852,9 @@
                                     invoke->method_index, params, PR_TRUE, iid);
           if (NS_SUCCEEDED(rv))
-            rv = SerializeInterfaceParam(writer, peer, iid,
+            rv = SerializeInterfaceParam(&MsgWriter, peer, iid,
                                          (nsISupports *) params[i].val.p, wrappers);
         }
         else
-          rv = SerializeParam(writer, type, params[i]);
+          rv = SerializeParam(&MsgWriter, type, params[i]);
 
         if (NS_FAILED(rv))
@@ -3872,5 +3878,5 @@
             (paramInfo.IsRetval() || paramInfo.IsOut()))
         {
-          rv = SerializeArrayParam(this, writer, peer, iinfo, invoke->method_index,
+          rv = SerializeArrayParam(this, &MsgWriter, peer, iinfo, invoke->method_index,
                                    *methodInfo, params, PR_TRUE, paramInfo,
                                    params[i].val.p, wrappers);
@@ -3887,5 +3893,5 @@
   if (got_exception)
   {
-    rv = SerializeException(writer, peer, exception, wrappers);
+    rv = SerializeException(&MsgWriter, peer, exception, wrappers);
     NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialize exception");
   }
@@ -3894,5 +3900,5 @@
     rv = IPC_SendMessage(peer, kDConnectTargetID, (const PRUint8 *) &reply, sizeof(reply));
   else
-    rv = IPC_SendMessage(peer, kDConnectTargetID, writer.GetBuffer(), writer.GetSize());
+    rv = IPC_SendMessage(peer, kDConnectTargetID, IPCMsgWriterGetBuf(&MsgWriter), IPCMsgWriterGetSize(&MsgWriter));
   if (NS_FAILED(rv))
   {
@@ -3917,3 +3923,5 @@
     RTMemFree(params);
   }
-}
+
+  IPCMsgWriterCleanup(&MsgWriter);
+}
Index: trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h	(revision 103563)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h	(revision 103569)
@@ -40,4 +40,5 @@
 
 #include "ipcMsgReader.h"
+#include "ipcMsgWriter.h"
 
 #include "nsIInterfaceInfo.h"
@@ -57,5 +58,4 @@
 
 class nsIException;
-class ipcMessageWriter;
 
 // a key class used to identify DConnectInstance objects stored in a hash table
@@ -194,5 +194,5 @@
                                             nsID &result);
 
-  NS_HIDDEN_(nsresult) SerializeInterfaceParam(ipcMessageWriter &writer,
+  NS_HIDDEN_(nsresult) SerializeInterfaceParam(PIPCMSGWRITER pMsgWriter,
                                                PRUint32 peer, const nsID &iid,
                                                nsISupports *obj,
@@ -202,5 +202,5 @@
                                                      nsISupports *&obj);
 
-  NS_HIDDEN_(nsresult) SerializeException(ipcMessageWriter &writer,
+  NS_HIDDEN_(nsresult) SerializeException(PIPCMSGWRITER pMsgWriter,
                                           PRUint32 peer, nsIException *xcpt,
                                           nsVoidArray &wrappers);
Index: trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcMsgWriter.h
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcMsgWriter.h	(revision 103569)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcMsgWriter.h	(revision 103569)
@@ -0,0 +1,328 @@
+/* $Id$ */
+/** @file
+ * XPCOM - IPC message writer helper.
+ */
+
+/* ***** 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) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Conrad Carlen <ccarlen@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 ***** */
+/*
+ * Copyright (C) 2024 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+#ifndef ipcMsgWriter_h__
+#define ipcMsgWriter_h__
+
+#include <iprt/types.h>
+#include <iprt/string.h>
+#include <iprt/mem.h>
+
+/** Whether to allow unaligned memory access for the message writer. */
+#define IPC_MSG_WRITER_UNALIGNED_ACCESS
+
+/**
+ * The message writer state.
+ */
+typedef struct IPCMSGWRITER
+{
+    /** The buffer base (for freeing). */
+    uint8_t             *pbBuf;
+    /** The current buffer pointer. */
+    uint8_t             *pbBufCur;
+    /** The end of the buffer (exclusive). */
+    uint8_t             *pbBufEnd;
+    /** Flag whether an error occurred. */
+    bool                fError;
+} IPCMSGWRITER;
+/** Pointer to a IPC message reader. */
+typedef IPCMSGWRITER *PIPCMSGWRITER;
+/** Pointer to a const IPC message reader. */
+typedef const IPCMSGWRITER *PCIPCMSGWRITER;
+
+
+/**
+ * Initialises the given IPC message writer state and allocates the given amount
+ * initial buffer space.
+ *
+ * @param   pThis           The IPC message writer to initialize.
+ * @param   cbInitial       How much space to reserve in the buffer in bytes initially.
+ */
+DECLINLINE(void) IPCMsgWriterInit(PIPCMSGWRITER pThis, size_t cbInitial)
+{
+    pThis->pbBuf = (uint8_t *)RTMemAlloc(cbInitial);
+    if (RT_UNLIKELY(!pThis->pbBuf))
+    {
+        pThis->pbBufCur = NULL;
+        pThis->pbBufEnd = NULL;
+        pThis->pbBufCur = NULL;
+        pThis->fError   = true;
+        return;
+    }
+
+    pThis->fError   = false;
+    pThis->pbBufCur = pThis->pbBuf;
+    pThis->pbBufEnd = pThis->pbBuf + cbInitial;
+}
+
+
+/**
+ * Cleans up the given message writer instance, freeing all allocated resources.
+ *
+ * @param   pThis           The IPC message writer instance.
+ */
+DECLINLINE(void) IPCMsgWriterCleanup(PIPCMSGWRITER pThis)
+{
+    if (pThis->pbBuf)
+        RTMemFree(pThis->pbBuf);
+}
+
+
+/**
+ * Returns whether the given IPC message writer encountered an error (out of memory)
+ * during its current lifetime.
+ *
+ * @param   pThis           The IPC message writer instance.
+ */
+DECL_FORCE_INLINE(bool) IPCMsgWriterHasError(PCIPCMSGWRITER pThis)
+{
+    return pThis->fError;
+}
+
+
+/**
+ * Returns a pointer to the message buffer of the given IPC message writer instance.
+ *
+ * @returns Pointer to the start of the message buffer.
+ * @param   pThis           The IPC message writer instance.
+ */
+DECL_FORCE_INLINE(const uint8_t *) IPCMsgWriterGetBuf(PCIPCMSGWRITER pThis)
+{
+    return pThis->pbBuf;
+}
+
+
+/**
+ * Returns the current size of the message in bytes of the given IPC message writer instance.
+ *
+ * @returns Size of the message in bytes.
+ * @param   pThis           The IPC message writer instance.
+ */
+DECL_FORCE_INLINE(size_t) IPCMsgWriterGetSize(PCIPCMSGWRITER pThis)
+{
+    return pThis->pbBufCur - pThis->pbBuf;
+}
+
+
+/**
+ * Grows the message buffer of the given IPC message writer instance by at least the
+ * given amount of bytes.
+ *
+ * @returns true if success, false on out of memory error (error flag is set).
+ * @param   pThis           The IPC message writer instance.
+ * @param   cbAdditional    How much to grow the buffer in bytes.
+ */
+DECLINLINE(bool) IPCMsgWriterEnsureCapacitySlow(PIPCMSGWRITER pThis, size_t cbAdditional)
+{
+    if (RT_UNLIKELY(pThis->fError))
+        return false;
+
+    const size_t cbOld = pThis->pbBufEnd - pThis->pbBuf;
+    const size_t cbNew = RT_ALIGN_Z(cbOld + cbAdditional, 128);
+    uint8_t *pbBufNew = (uint8_t *)RTMemRealloc(pThis->pbBuf, cbNew);
+    if (RT_UNLIKELY(!pbBufNew))
+    {
+        pThis->fError = true;
+        return false;
+    }
+
+    const size_t offBufCur = pThis->pbBufCur - pThis->pbBuf;
+    pThis->pbBuf    = pbBufNew;
+    pThis->pbBufCur = pThis->pbBuf + offBufCur;
+    pThis->pbBufEnd = pThis->pbBuf + cbNew;
+    return true;
+}
+
+
+/**
+ * Forced inline helper ensuring that message buffer of the given IPC message writer instance
+ * has at least the given amount of free bytes left, trying to grow the buffer.
+ *
+ * @returns true if success, false on out of memory error (error flag is set).
+ * @param   pThis           The IPC message writer instance.
+ * @param   cbAdditional    How much to grow the buffer in bytes.
+ */
+DECL_FORCE_INLINE(bool) IPCMsgWriterEnsureCapacity(PIPCMSGWRITER pThis, size_t cbAdditional)
+{
+    if (RT_LIKELY(pThis->pbBufCur + cbAdditional <= pThis->pbBufEnd))
+        return true;
+
+    return IPCMsgWriterEnsureCapacitySlow(pThis, cbAdditional);
+}
+
+
+/**
+ * Appends the given byte to the message for the given message writer.
+ *
+ * @param   pThis           The IPC message writer instance.
+ * @param   u8              The byte value to append.
+ */
+DECL_FORCE_INLINE(void) IPCMsgWriterPutU8(PIPCMSGWRITER pThis, uint8_t u8)
+{
+    if (IPCMsgWriterEnsureCapacity(pThis, sizeof(uint8_t)))
+    { /* likely */ }
+    else return;
+
+    *pThis->pbBufCur++ = u8;
+}
+
+
+/**
+ * Appends the given 16-bit value to the message for the given message writer.
+ *
+ * @param   pThis           The IPC message writer instance.
+ * @param   u16             The 16-bit value to append.
+ */
+DECL_FORCE_INLINE(void) IPCMsgWriterPutU16(PIPCMSGWRITER pThis, uint16_t u16)
+{
+    if (IPCMsgWriterEnsureCapacity(pThis, sizeof(uint16_t)))
+    { /* likely */ }
+    else return;
+
+#ifdef IPC_MSG_WRITER_UNALIGNED_ACCESS
+    *(uint16_t *)pThis->pbBufCur = u16;
+#else
+    uint8_t abTmp[2];
+    *(uint16_t *)&abTmp[0] = u16;
+    *pThis->pbBufCur++ = abTmp[0];
+    *pThis->pbBufCur++ = abTmp[1];
+#endif
+    pThis->pbBufCur += sizeof(uint16_t);
+}
+
+
+/**
+ * Appends the given 32-bit value to the message for the given message writer.
+ *
+ * @param   pThis           The IPC message writer instance.
+ * @param   u32             The 32-bit value to append.
+ */
+DECL_FORCE_INLINE(void) IPCMsgWriterPutU32(PIPCMSGWRITER pThis, uint32_t u32)
+{
+    if (IPCMsgWriterEnsureCapacity(pThis, sizeof(uint32_t)))
+    { /* likely */ }
+    else return;
+
+#ifdef IPC_MSG_WRITER_UNALIGNED_ACCESS
+    *(uint32_t *)pThis->pbBufCur = u32;
+#else
+    uint8_t abTmp[4];
+    *(uint32_t *)&abTmp[0] = u32;
+    *pThis->pbBufCur++ = abTmp[0];
+    *pThis->pbBufCur++ = abTmp[1];
+    *pThis->pbBufCur++ = abTmp[2];
+    *pThis->pbBufCur++ = abTmp[3];
+#endif
+    pThis->pbBufCur += sizeof(uint32_t);
+}
+
+
+/**
+ * Appends the given 64-bit value to the message for the given message writer.
+ *
+ * @param   pThis           The IPC message writer instance.
+ * @param   u64             The 64-bit value to append.
+ */
+DECL_FORCE_INLINE(void) IPCMsgWriterPutU64(PIPCMSGWRITER pThis, uint64_t u64)
+{
+    if (IPCMsgWriterEnsureCapacity(pThis, sizeof(uint64_t)))
+    { /* likely */ }
+    else return;
+
+#ifdef IPC_MSG_WRITER_UNALIGNED_ACCESS
+    *(uint64_t *)pThis->pbBufCur = u64;
+#else
+    uint8_t abTmp[8];
+    *(uint64_t *)&abTmp[0] = u64;
+    *pThis->pbBufCur++ = abTmp[0];
+    *pThis->pbBufCur++ = abTmp[1];
+    *pThis->pbBufCur++ = abTmp[2];
+    *pThis->pbBufCur++ = abTmp[3];
+    *pThis->pbBufCur++ = abTmp[4];
+    *pThis->pbBufCur++ = abTmp[5];
+    *pThis->pbBufCur++ = abTmp[6];
+    *pThis->pbBufCur++ = abTmp[7];
+#endif
+    pThis->pbBufCur += sizeof(uint64_t);
+}
+
+
+/**
+ * Appends the given buffer to the message for the given message writer.
+ *
+ * @param   pThis           The IPC message writer instance.
+ * @param   pvBuf           The buffer to append.
+ * @param   cbBuf           How many bytes to append.
+ */
+DECL_FORCE_INLINE(void) IPCMsgWriterPutBytes(PIPCMSGWRITER pThis, const void *pvBuf, size_t cbBuf)
+{
+    if (IPCMsgWriterEnsureCapacity(pThis, cbBuf))
+    { /* likely */ }
+    else return;
+
+    memcpy(pThis->pbBufCur, pvBuf, cbBuf);
+    pThis->pbBufCur += cbBuf;
+}
+
+#endif /* ipcMsgWriter_h__ */
