WM_COPYDATA for Taskbar Interface

Each of the SHAppBarMessage, Shell_NotifyIcon, SHEnableServiceObject and SHLoadInProc functions is little more than a gateway for sending data to the taskbar window (and in some few cases, getting data back). The packaging of this data and the methods of its transmission are implementation details, but have much in common across the functions.

The calling process is typically not the process that implements the taskbar window. The standard method of passing data to a window function in another process is with the WM_COPYDATA message. This provides for passing a DWORD in the dwData member of the COPYDATASTRUCT and/or an arbitrary amount in a buffer described by the lpData and cbData members. SHELL32 passes both. The DWORD serves to identify which function the data in the buffer is being passed for:

0 SHAppBarMessage
1 Shell_NotifyIcon
2 SHEnableServiceObject or SHLoadInProc

The buffer layout for SHAppBarMessage is:

Offset Size Remarks
0x00 0x28 bytes enhanced APPBARDATA structure, with cbSize set to 0x28 and lParam sign-extended to QWORD
0x28 dword dwMessage argument
0x2C dword handle to a copy of the enhanced APPBARDATA in shared memory, else NULL
0x30 dword process ID of caller
0x34 0x04 bytes unused, presumed to be padding from QWORD alignment

The point to the shared memory and process ID is that for some values of dwMessage, the SHAppBarMessage function is expected to return information in members of the APPBARDATA structure. However, the WM_COPYDATA mechanism copies data only from the source to the taskbar window, without providing a means to write back. The solution found by SHELL32 is that in the cases where it is needed, the enhanced APPBARDATA that is anyway passed in the buffer is also copied to shared memory and the means for accessing this shared memory is also passed in the buffer.

For Shell_NotifyIcon, the data for the buffer is laid out as follows. In the symbol file for EXPLORER.EXE, Microsoft publishes a name for this otherwise undocumented structure: TRAYNOTIFYDATAW.

Offset Size Remarks
0x00 dword signature: 0x34753423
0x04 dword dwMessage argument
0x08 0x03B8 bytes NOTIFYICONDATAW structure in current layout, constructed on stack from input at lpdata

The SHEnableServiceObject and SHLoadInProc functions reduce to one operation differentiated by flags. The buffer layout is:

Offset Size Remarks
0x00 0x10 bytes CLSID from rclsid argument
0x10 dword 0x01 for SHLoadInProc
0x02 for SHEnableServiceObject if fEnable argument is FALSE
0x03 for SHEnableServiceObject if fEnable argument is non-zero