http://bugs.winehq.org/show_bug.cgi?id=2474
------- Additional Comments From a_villacis@palosanto.com 2005-22-03 11:54 ------- I have been reviewing what happens when MP3GainGUI starts up that triggers the first of the errors (the dialog box that claims mp3gain.exe could not be found). The source code of MP3GainGUI has been helpful for this.
MP3GainGui tries to invoke mp3gain.exe at startup in order to get the program version. This backend reports its version on stdout when invoked with a /v switch. So, the VB frontend opens a pipe and connects the backend stdout to it in order to read the version string from it. Since the routine to fetch a program's stdout is a generic one, and the execution of the program might take a while, the routine polls for available data from the pipe (much in the way the select() call is used in Unix) before reading, and calls DoEvents (a VB keyword that yields control to the GUI in order to process window events) if no data is available. The function called to poll for available data is PeekNamedPipe(), with a (supposedly) NULL buffer pointer, and a buffer length of zero. The Wine implementation of PeekNamedPipe() checks for a NULL pointer before attempting to read data from the pipe with recv() and the MSG_PEEK flag.
The problem arises because the VB frontend fails at specifying a NULL pointer for the buffer pointer of PeekNamedPipe(). Because of some poorly-documented rule about the way an Any parameter in VB behaves, the attempt to pass a literal 0& (which is, as far as I can remeber, an equivalent of "0L" in C) to the lpBuffer parameter (declared as Any in the VB file) does NOT translate into a NULL pointer, but to a non-NULL pointer that points to the zero value (or so I think). Then PeekNamedPipe() receives a non-NULL pointer, which it interprets as a valid buffer, and fails to check that the buffer length is set to 0, so it end up trying to perform a zero-length peek on an invalid buffer with recv(). This operation is (apparently) not supported, and so it says in the errno value.
The PeekNamedPipe() function should check for the buffer length as well as the buffer pointer before trying to perform the recv() peek on the pipe.