A customer reported that some of their clients were getting an error message when running their program:
contoso.exe – Ordinal Not Found
The ordinal 380 could not be located in the dynamic link library C:\Program Files\Contoso\Contoso.exe.
The first thing to note is that this error message is misleading. It’s true that the missing ordinal is 380, but Contoso.exe is not the dynamic link library. Rather, it is the module that contains the reference to the missing ordinal. Unfortunately, the error message doesn’t tell us the DLL that lacks the desired ordinal 380 export. We’ll have to go find it ourselves.
We can use the LINK /DUMP /IMPORTS command to find all the functions that Contoso.exe imports, and search for a 380.
And there it is:
COMCTL32.dll
100B76110 Import Address Table
100EC5868 Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 380
And if you look in comctl32.dll version 6, you’ll find that it’s
380 7F 000C0DA0 LoadIconMetric
Okay, so they are trying to link to the function LoadIconMetric
in comctl32.dll, and it’s not there.
At this point, you may remember that there are two versions of comctl32.dll: Version 5 and version 6. Version 5 is the one you get by default, and to get version 6, you need to specify it in your application manifest.
The evidence suggests therefore that on the affected systems, something is wrong with their application manifest and the system is not processing it properly.
The customer liaison took this information back to the customer. I haven’t heard back from them, so I’m hoping they figured out why their manifests aren’t working on some systems.
Why are they still importing by ordinal; isn’t importing by name the norm in 32-bit code? I seem to remember reading about it somewhere… oh yes, it was here: https://devblogs.microsoft.com/oldnewthing/20060718-32/?p=30483
BTW, could anyone suggest a sane tool to check manifests are there and are perfectly valid?
By sane I mean freeware, lightweight, portable, no stupid .NET/Java/Python/C++ runtime dependencies — something that just runs out of the box and does its job letting one be sure that the manifest will just work. You know, just what they (should have?) taught them since the first computer programming class.
I remember trying some console utility and a few other programs...
If a “sane” tool can’t require a runtime, then I suppose any tool written in Visual C++ that doesn’t link the UCRT is off limits. Because as we all know, Windows is not a Microsoft Visual C/C++ Run-Time delivery channel.
From Windows 1.0 up to Windows 7 the equivalent error message used to be: “The ordinal 380 could not be located in the dynamic link library comctl32.dll” or the more common “The procedure entry point LoadIconMetric could not be located in the dynamic link library comctl32.dll”.
Why regress to the more confusing “… Contoso.exe” flavor?