Win32 IPC Transport


The Win32 IPC transport uses Windows messages to direct the request to Snarl.  In order for this to work, Snarl creates a hidden window with a known title and class name.  Applications should populate a COPYDATASTRUCT data type with the request and send it to this window.


  • This transport only supports local-to-local communication - that is, an application can only communicate with Snarl running on the same computer
  • Dynamic callback support is limited to 16-bit integer values.

Communication Overview

Requests are sent as Windows messages via the WM_COPYDATA message.  This message allows for very simple but powerful process-to-process communication within a Windows session.

The Win32 IPC transport expects all notification content to be in UTF-8 format.  Hence, the communication process is as follows:
  1. Locate Snarl's message handling window;
  2. Convert request (or, at least, the notification elements of it) into UTF-8;
  3. Bundle into a COPYDATASTRUCT type;
  4. Send to Snarl using the Windows messaging mechanism.
This translates into the following pseudo-code:

hWndSnarl int32
lResult int32

hWndSnarl = FindWindow("w>Snarl", "Snarl")
Request = ToUTF8(Request)

pcds->dwData = 0x534e4c03 // "SNL",0x03
pcds->cdData = SizeOf(Request)
pcds->lpData = *Request

hr = SendMessageTimeout(hWndSnarl, WM_COPYDATA, GetCurrentProcessId(), pcds, SMTO_ABORTIFHUNG, 1000, lResult)

Request Structure

Other than converting the request into UTF-8 and bundling it into a COPYDATASTRUCT data type, no other changes should be made.

Response Structure

All Win32 IPC requests return a 32-bit integer result as a result of the call to SendMessageTimeout().  If it succeeds (result is non-zero), the status code of the request will be returned in lResult; if it fails (result is zero), the exact cause of the failure can be determined by calling GetLastError().

The returned status code is encoded as follows: a negative value indicates an error, a result of zero indicates success, and a positive value indicates success and some information was returned (for example, a notification's token).  Translation into a real status code is simply a case of converting to an absolute value, as follows:

If returned_value = 0 Then
    /* success */
    Print "success"

ElseIf returned_value < 0 Then
    /* error */
    Print "error " + Abs(returned_value) + " occurred"

ElseIf returned_value > 0 Thern
    / * success and data returned */
    Print "data returned was: " + (returned_value)


Events and Callbacks

In order to receive events, the application must supply two additional pieces of information to Snarl when registering:
  • A handle to a window (HWND) to send notification to
  • A Windows message to use to identify the application
The handle to the window should be included in the reply-to argument; the message should be in the reply-with argument.  As the message will be returned to the application, it is recommended that the message is chosen from the user message range.  For example:

int32 hWnd
int32 lMsg

    hWnd = CreateWindowEx(...)
    lMsg = WM_USER + 1

    snarl_do_request("register?app-sig=some/app&title=Some App&reply-to=" + hWnd + "&reply-with=" + lMsg)

Subsequent events will then appear in the window's message queue as follows:
  • hWnd - handle to the window itself
  • uMsg - the message provided in the reply-with argument
  • wParam - the lower 16 bits (LOWORD) contain the event code; the upper 16 bits (HIWORD) contain information specific to the event code
  • lParam - the notification's unique token
wParam Encoding

The following table explains how wParam is encoded for the different events:

Event (LoWord) HiWord 
SNARL_NOTIFY_MENU One-based index of menu item selected
SNARL_NOTIFY_ACTION Action identifier converted into a 16-bit value

Action Identifiers

Note that although Snarl supports alphanumeric identifiers, the Win32 IPC transport does not.  Consequently, it must be possible to convert the identifier into a valid 16-bit integer for it to work.  So, @1234, @-1 and @65535 are valid, while @HELLO, @65536 and @123$ are not.