Konica Minolta Twain Driver Not Recognized

I recently had a problem getting the Konica Minolta Twain Driver for the C253 scanner (among others) to be recognized by the twain device manager, and thus it was not listed as one of the twain devices available, either in PhotoShop or in Atalasoft DotTwain.  The nice people at our local Hughes Calihan Konica Minolta here in Phoenix helped me figure this out, along with Lou Franco of Atalasoft (see his comments below), and I wanted to post the solution for anyone having a similar problem.

Ultimately, the problem was that another software package (I believe it was Business Object’s Crystal Reports XI Release 2), installed a copy of the LIBEAY32.dll into the C:WindowsSystem32 directory.  LIBEAY32.dll is part of the open source OpenSSL suite, and I have 18 (!) different versions on my system.  They mostly live in harmony, but when the Konica Minolta twain driver tried to load, it would get the version of LIBEAY32.dll that Crystal Reports had put into System32 (since that is very early in the Dynamic Link Library Search Order — see http://msdn.microsoft.com/en-us/library/ms682586.aspx) and when the LIBEAY32.dll that was loaded did not have the proper ordinal entry point, the Konica Minolta twain driver would not be loaded by the twain device manager.

When PhotoShop loaded, it would emit an error message about the missing ordinal in LIBEAY32.dll; when File/Import was pulled up in the menu, the Konica Minolta twain device would just be missing, and there would be no error here.

Compounding the problem was that my test application using the Twain source manager via the Atalasoft DotTwain ShowSelectSource() function did NOT issue any error.

However, a test application I made with Visual C++ loading the Twain device source library for the Konica Minolta scanner did produce the error.

It turns out that the only difference between my test application and Photoshop was the SetErrorMode() function, which sets the process’ ErrorMode. You can call GetErrorMode() and SetErrorMode() following these imports:
[DllImport("Kernel32.dll")]
private extern static uint SetErrorMode(uint mode);

[DllImport("Kernel32.dll")]
private extern static uint GetErrorMode();

If you then call SetErrorMode(0) before the Atalasoft ShowSelectSource() function, the user DOES see the error messages from the operating system. However, the Twain Source Manager twain_32.dll does not return any error code to ShowSelectSource(), so obviously ShowSelectSource() cannot return any error code either. As noted below, the only way for a calling program to get an indication that a source did not load is to call the twain source DLL directly rather than through the Twain Source Manager, and observe that the LoadLibrary call returns NULL.

Having figured out that the problem was that the Business Objects LIBEAY32.dll was in the System32 directory, the solution was a little difficult.  The Konica Minolta Twain Driver worked once the LIBEAY32.dll was removed  (or renamed) in System32, but Crystal Reports XI Release 2 tries to repair it’s installation if if finds that file missing. 

However, by placing the LIBEAY32.dll from the Konica Minota twain driver directory (in a subdirectory of C:windowstwain_32, where the twain device files live) into System32, both the Konica Minota twain driver and Crystal Reports seem to be happy.  For good measure, I put a copy of the LIBEAY32.dll that Crystal had put into System32 into Crystal’s own directory (since that has higher priority in the .dll search order) so that Crystal should load its own LIBEAY32.dll

For reference, I tracked down the problem by making a test Visual Studio C++ app and trying to load the Konica Minolta twain device driver (mostly from http://msdn.microsoft.com/en-us/library/784bt7z7.aspx) :

#include <windows.h>

Then, in the click handler:

HINSTANCE hDLL; // Handle to DLL
UINT uErrorMode = SetErrorMode(0); // so you get an error message from the OS
LPCWSTR str=L"C:\Windows\twain_32\KONICA MINOLTA\RTM_V3\kmtw3R.ds";
hDLL = LoadLibrary(str);

The LoadLibrary call produces a MessageBox (see the SetErorrMode() docs) with the error, and returns NULL, if there is a problem loading the twain source driver library. Note that the twain device driver will need other files in that directory, and you will get those errors first; you can fix that problem by adding it to the PATH for testing. The System32 will still be ahead of the PATH (but not ahead of the application .exe directory) so you will get the error message you are looking for. Also note that the twain device driver library, in actual use, will NOT need the PATH to be set; the twain device manager appears to take care of that.

Another approach that works is to change the current working directory to the directory containing the twain source driver before calling LoadLibrary on the driver, as this will more closely approximate the DLL Search Order used by the twain source manager. Again, the problem is that, although the source driver does install the files it needs into its own directory, the LIBEAY32.dll that Crystal installs into System32 is still AHEAD of the LIBEAY32.dll installed into the source driver’s directory! (see Lou Franco’s comments below) DLL Search Order is a fairly complex topic, and can vary depending on a number of factors; google “Dynamic Link Library Search Order” for info. Note that, unless SafeDllSearchMode is disabled, changing the current working directory does not change the DLL search order.

Also, when I tried this with a 64 bit version of Vista, Crystal installs LIBEAY32.dll into /Windows/SysWOW64, which is the directory that takes the place of /Windows/System32.

Regretably, when LoadLibrary fails, FormatMessage produces only a message that the operating system could not run the file. The only detailed info available seems to be the message box provided directly to the user by the OS, and only when SetErrorMode(0) is in effect.

See also: http://www.cube316.net/blog/archives/200710/147.html for a similar problem.

— Edited 12/31/08 10PM to add info about using SetErrorMode() to show the error message box, that the lack of error reporting to the application occurs at the Twain Source Manager level, to reinforce the info about DLL Search Order, and to take Lou Franco’s comments into account; Edited 12/3/09 to add info re 64 bit Vista – JMN

6 thoughts on “Konica Minolta Twain Driver Not Recognized

  1. Good sleuthing! Thank you for reporting this.

    I will try to explain what happened from the DotTWAIN side.

    DotTWAIN relies on the twain_32.dll to report an error. In this case, ShowSelectSource() asks the twain_32.dll to show a dialog with installed TWAIN devices — it did that (probably failing to load the Minolta driver), and did not report an error — as far as we know the call completed successfully.

    Photoshop probably has their own device list dialog (to match their GUI), so they see the error directly (meaning they don’t ask twain_32.dll to show the dialog)

    When you see a missing ordinal error, one thing to do is to run DEPENDS.EXE (comes with Visual Studio) on the dll — it will show you all of the dlls it will try to load and whether they have the entry points — it should have flagged LIBEAY32.dll and told you which one it was trying to load.

    Also, probably the driver should have installed all of the dependent dlls into the C:WINDOWStwain_32 directory — that way they wouldn’t be affected by other installations.

    Again, thanks for documenting this — and if you run into a problem like this again, please give us a call. We install some diagnostic tools with the SDK and have a driver compatibility database at inspectortwain.com that can sometimes also help.

  2. Also, twain_32.dll logs into

    C:Documents and SettingsLOGIN_NAMELocal SettingsTemptwain.log

    Sometimes you see errors like this in there.

    (Replace LOGIN_NAME with your login name in the path above)

  3. Thanks, Lou! Great tips!

    The log looks great for sorting out twain control issues, but in this case it didn’t show any evidence of the problem loading the driver. There is a message: “Why Can’t We Find The Thunker Window?” in the log, but that message occurs whether or not the KM twain device driver loads.

    Note that on my Vista machine the log is in C:usersLOGIN_NAME_AppDataLocalTemptwain.log, and it looks like it logs all of the calls, including result and condition codes.

    I hadn’t thought of using DEPENDS.EXE to look at the actual .ds DLL, but when I do, I do NOT get the error message, and in fact DEPENDS loads the LIBEAY32.dll preferentially from the same directory that the .ds twain device driver is in! Thus, DEPENDS is not using the same DLL Search Order that the twain device manager does, and does not load the LIBEAY32.dll that Crystal put into c:windowssystem32

    Photoshop actually lists the available twain devices in a submenu of the main File menu (rather than in a dialog), and appears to be searching for them on startup, since that is when the “The ordinal 2524 could not be located in the dynamic link library LIBEAY32.dll” message occurs.

    I got the same error when I called LoadLibrary on the twain device driver .ds DLL (i.e., NOT the way a twain client would normally use twain). I will let you know if I get an error if I try to call twain_32.dll

  4. Lou: You are correct — the User Select command (DG_CONTROL / DAT_IDENTITY / MSG_USERSELECT) does NOT provide any indication to the caller that one of the drivers did not load unless SetErrorMode(0) is called first, and even then only provides it via a message box shown directly to the user (i.e., no indication to the calling application that there was a problem).

    Even enumerating the sources with MSG_GETFIRST and MSG_GETNEXT does not produce any indication to the application that there was a problem. The message box is shown directly to the user if SetErrorMode(0) had been called, but the twain source manager just skips the source with the problem and returns the next one in line, so the source returned by the Twain source manager is NOT the one that caused the error message box shown by the OS!

    Thus, troubleshooting a twain device source failing to load appears best done by calling LoadLibrary on the source library .ds file AFTER setting the current directory to the directory of the .ds file, and after calling SetErrorMode(0). The only indication to the application that there was a problem will be that LoadLibrary will return NULL, but the user will see a more informative error message box from the OS.

    The twain source manager provides no clue that anything is wrong, so there is nothing that the Atalasoft DotTwain library could report.

Leave a Reply

Your email address will not be published. Required fields are marked *