The WODM_WRITE message requests a waveform output driver to write a waveform data block to the specified device.
The driver should return MMSYSERR_NOERROR if the operation succeeds. Otherwise it should return one of the MMSYSERR or WAVERR error codes defined in mmsystem.h. See waveOutWrite return values in the Win32 SDK.
A client sends the WODM_WRITE message by calling the user-mode driver’s wodMessage entry point, passing the specified parameters.
If the WHDR_PREPARED flag in the dwFlags member of WAVEHDR is not set, the driver should return WAVERR_UNPREPARED.
Unless the device has been paused with a WODM_PAUSE message, the driver should begin playback the first time it receives a WODM_WRITE message.
User-mode waveform output drivers should handle output asynchronously, by creating a separate thread to handle communication with the kernel-mode driver. Typically, the original thread queues the output buffer, sets its WHDR_INQUEUE flag and clears its WHDR_DONE flag in the WAVEHDR structure, and returns control to the client.
Meanwhile, the new thread starts the output operation by calling DeviceIoControl to send the kernel-mode driver an IOCTL_WAVE_SET_STATE control code, and by calling WriteFileEx to send the kernel-mode driver the client-supplied data. When the kernel-mode driver finishes using a buffer, this thread should set the buffer’s WHDR_DONE flag. clear the buffer’s WHDR_INQUEUE flag, and send a WOM_DONE callback message to the client.
To avoid unnecessarily locking too much memory, do not send the kernel-mode driver too many buffers at once, or buffers that are excessively large.
The driver should continue sending buffers to the kernel-mode driver until the client sends WODM_PAUSE or WIDM_RESET.
The user-mode driver is usually responsible for implementing waveform looping. The driver should check each buffer’s WAVEHDR structure for WHDR_BEGINLOOP and WHDR_ENDLOOP flags, along with an iteration count in the structure’s dwLoops member.
For additional information, see Transferring Waveform Output Data.