When MSLU functions fail...

by Michael S. Kaplan, published on 2005/10/04 03:31 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/10/04/476764.aspx

Last week, over in the microsoft.public.platformsdk.mslayerforunicode newsgroup, Dan Mitchell asked:

We have a unicode app (working just fine with unicows) that needs to check the version of one of our DLLs. The DLL is non-unicode, and works fine if we load it and call our functions on it. (though none of those functions pass strings as parameters).

The problem is that if we call GetFileVersionInfoSize() on that DLL, we get an error back and GetLastError() returns 120 ("the function is not supported").

It works fine on WinXP etc, so it seems to be just something about unicode. (and it didn't do this before we switched our main app to unicode).

Is there anything we can do about this? If I try guessing that 64k should be enough as a safe fake return from GetFileVersionInfoSize(), the call to GetFileVersionInfo() fails the same way (getlasterror=120), and I don't think I can usefully spoof the call to that.

thanks,

-- dan

Of course, last week was pretty busy with the MVP Summit and all, so I did not see the message right away. Luckily, David Lowndes was checking the group in the evenings. He ran through some of the basic troubleshooting steps that I would have done, such as:

Pointing out that it really ought to work (helps morale!)

Asking if the call work with other DLLs, or even the EXE that it is being called from (it wasn't)

Finding out if the 'A' version of the function works (it was)

Asking what version of the DLL was being used (it was 1.1.3790, the latest one)

Now that is the point where I finally had a chance to check out the group. Now the above questions are pretty typical ones to ask and I probably would have done the same had I been around, luckily David saved me the trouble. :-)

So I realized based on the problem description and the answers what might be going on. It was one of two possibilities, with the second one being the most likely:

The error 120 (ERROR_CALL_NOT_IMPLEMENTED) is what the MSLU loader returns when it is unable to do the LoadLibrary/GetProcAddress on the function.

Of course the reason for that is that it is the same thing that a Win9x OS will return if you call its "W" stub.

The most likely cause is improper linking to unicows.dll -- the best way to check is to do a dumpbin on the imports of the file calling unicows, and see if GetFileVersionInfoSize is there -- if it is, then that means that the unicows.dll one is not being called....

That's the problem alright. I have no idea what's wrong with it, though -- the last time I hit this problem it was openssl that was pulling advapi32.lib in, which was solvable by rebuilding openssl.

I have no idea what's pulling version.lib in this time; it doesn't seem to be any of our libraries, and I don't think it's openssl. I guess it's just a matter of poking around until I find where it's coming from.

It is an interesting problem when some other library is pulling in the .LIB files in a way that overrides your own attempts to order the .LIBs for MSLU's behavior. Sometimes the key is even to include a .LIB file more than once, though that is a solution that is really best avoided if possible since it makes things a lot more complicated. In many cases, careful reordering can do the trick. I'll cover one of the more awful examples of this issue another time....

Special thanks to David who allowed me to swoop in and look like a genius. :-)

This post brought to you by "Ю" (U+042e, a.k.a. CYRILLIC CAPITAL LETTER YU)