IPC via Message Queue APIs in Windows Mobile 6.5
In Windows Mobile 6.5, the Point-to-Point Message Queue (MsgQueue) APIs provided a dedicated, lightweight inter-process communication (IPC) mechanism designed to pass data reliably between distinct processes or between user-mode applications and device drivers. Built upon the Windows Embedded CE 6.0 kernel, these APIs allowed developers to create synchronized, kernel-managed FIFO (First-In, First-Out) data pipelines. This architecture eliminated the risks of direct cross-process memory access while ensuring low latency and predictable performance on resource-constrained mobile hardware.
Architectural Context of Windows Mobile 6.5
Windows Mobile 6.5 utilized the Windows Embedded CE 6.0 kernel, which introduced a fully 32-bit virtual memory model supporting up to 32,000 concurrent processes, each with a private 2 GB virtual address space. Because processes were strictly isolated from one another to ensure system stability, direct pointer sharing was prohibited.
To overcome this isolation without the heavy overhead of COM or
network-based sockets, the operating system exposed Point-to-Point
Message Queues. Unlike traditional desktop Windows message queues tied
to window handles (HWND) and user interface threads,
Point-to-Point Message Queues were headless, data-centric, and managed
directly by the kernel.
Core Message Queue APIs
The Point-to-Point Message Queue interface relied on a small, specialized set of C/C++ Win32 functions:
CreateMsgQueue: Initializes a new message queue. The creating process defines the queue attributes using theMSGQUEUEOPTIONSstructure, specifying properties such as whether the queue is for reading or writing, the maximum number of messages, the maximum allowed message size, and whether the queue is named.OpenMsgQueue: Allows a client process to obtain a handle to an existing named message queue created by another process, specifying desired access rights (read or write).WriteMsgQueue: Inserts a data packet into the target queue. It allows the caller to specify a timeout interval, dynamic buffer size, and message priority.ReadMsgQueue: Extracts a message from the queue into a local memory buffer. Like the write operation, it supports configurable timeouts and tracks message flags.CloseMsgQueue: Releases the handle to the queue and cleans up kernel resources when all handles are closed.
How IPC Was Established
Point-to-Point Message Queues operated primarily in a unidirectional fashion. Full-duplex communication required establishing two separate queues: one for outgoing requests and one for incoming responses.
- Queue Creation: The server process called
CreateMsgQueue, passing a globally identifiable string name and configuring thebReadAccessflag toTRUE. The kernel allocated memory buffers for the queue inside the kernel address space. - Queue Connection: The client process called
OpenMsgQueue, targeting the same queue name and setting thebReadAccessflag toFALSE(indicating write access). - Data Marshalling: When the client invoked
WriteMsgQueue, the kernel copied the message payload out of the client's virtual memory space directly into the kernel's message buffer. - Data Retrieval: When the server invoked
ReadMsgQueue, the kernel copied the buffered data from kernel space into the server's target buffer.
Because the kernel handled the copying of data between disjoint
address spaces, applications did not need to coordinate complex
shared-memory mappings via CreateFileMapping or manually
marshal pointers.
Synchronization and Event-Driven Processing
A critical advantage of the Point-to-Point Message Queue implementation was its integration with standard Win32 synchronization primitives. Queue handles acted as waitable kernel objects.
A reader process did not need to poll the queue continuously with
ReadMsgQueue. Instead, it passed the queue handle directly
to WaitForSingleObject or
WaitForMultipleObjects. The kernel signaled the queue
handle whenever a new message arrived, waking the reading thread
immediately. If the queue filled to maximum capacity, write operations
would automatically block until space became available or until an
optional user-defined timeout expired, preventing memory exhaustion on
physical mobile devices.