WSCEnumProtocols, was _SHExpandEnvironmentStrings() should return input string if no % found to expand?

Rolf Kalbermatter rolf.kalbermatter at
Mon Oct 25 02:35:55 CDT 2004

James Hawkins wrote:

>> No, it will work. The cast probably there because the original author
>> didn't want to write two functions. Instead he added a bool to the
>> internal function that specifies whether the buffer is unicode or
>> not. The cast is then needed to keep the compiler happy.
>The fact that the structures have a string in them is one issue that
>you're ignoring.  You can't make a cast from a unicode to an ansi
>string just by casting.  You have to call RtlMultiByteToWideChar to
>convert it.

This isn't a problem here since the helper function which is called has as
last parameter a boolean telling it if the structure should be interpreted
as the ANSI or Unicode version. While this may look asthetically wrong it is
technically correct as long as the strings are embedded as pointers instead
of inlined. There is a string inlined in the structure but it is at the end
of the structure only so even there it is not necessarily a problem although
the internal helper function needs to take extra care to get it right and in
that it might be a better idea to just implement the Unicode version and
convert for the ANSI one.

>The major problem that you're ignoring is that you're
>casting from one kind of struct to another, and they aren't the same. 
>The cast wont work.  You would have to individually pull out the
>relevant fields into a new PROTOCOL_INFO struct like I said in the
>last post.  If by original author I'm assuming you're talking about
>the author of the spec file.  In which case, there was only one
>function in the spec file to begin with, because all functions only
>have one in the spec file originally until someone stubs out that
>function and finds out that it needs and A and a W...which is why I
>didn't want my patch committed.

This would be indeed the real problem if it was the case, but (from my SDK headers): 

int WSPAPI WSCEnumProtocols(IN LPINT lpiProtocols,
                            OUT LPWSAPROTOCOL_INFOW lpProtocolBuffer,
                            IN OUT LPDWORD lpdwBufferLength,
                            OUT LPINT lpErrno);

int WSAAPI WSAEnumProtocolsA(IN LPINT lpiProtocols,
                             OUT LPWSAPROTOCOL_INFOA lpProtocolBuffer,
                             IN OUT LPDWORD lpdwBufferLength);

There is no ANSI version defined for the WSC function. This means either of two
things: It is on all versions of Windows Unicode or it is very much like many
Shell functions really ANSI on non NT systems while NT systems implement it as
Unicode. Seeing that MSDN claims this to be supported on even Win95 I tend to
believe the second one but only tests will show. The fact that modern SDK headers
don't contain any indication of ANSI support means nothing as Microsoft has removed
support for developing Win9x application from many SDK headers and MSDN.

The problem seems to me rather that even the WSAEnumProtocols function casts the
WSAPROTOCOL_INFOA/W structure pointer into PROTOCOL_INFOA and since they have
indeed a completely different layout we are basically causing big trouble. I doubt
that WSAEnumProtocols ever did work properly unless MS has at some point changed
the second parameter of the function. Once this has been fixed, the implementation
as suggested by Hans should actually work fine.

Rolf Kalbermatter

More information about the wine-devel mailing list