twain / twain-cs

A C# interface for TWAIN
165 stars 66 forks source link

TwainDSM is crashing #32

Closed gwyn17 closed 5 years ago

gwyn17 commented 5 years ago

I have a program in C# that accesses TwainDSM via twain-cs. I’m scanning with a Kodak i1440 scanner. When I scan 8.5×11 or 8.5×14 pages, it works fine and reliably. The i1440’s automatic page size detection. But when I scan a cashier coupon (long and skinny) my program simply crashes – no error message, no stack trace.

In twaindsm.log, the last message is as follows, which is pretty useless...


[125757452 dsm.cpp  2368     0 000015B4] Quaero Scanner Workstation -> KODAK Scanner: i1410/i1420/i1440
[125757452 dsm.cpp  2373     0 000015B4] DG_CONTROL/DAT_CAPABILITY/MSG_GETCURRENT/ICAP_XFERMECH
[125757452 dsm.cpp  2432     0 000015B4] TWRC_SUCCESS TWON_ONEVALUE 

[125757453 dsm.cpp  2368     0 00001DC0] Quaero Scanner Workstation -> KODAK Scanner: i1410/i1420/i1440
[125757453 dsm.cpp  2377     0 00001DC0] DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET
[125757605 dsm.cpp  2432     0 00001DC0] TWRC_XFERDONE

TwainDSM 2.4.2 Same problem happening with a Fujitsu fi-6130Z A scan with a custom size of 4.2×11 (inches) works A scan with a custom size of 4.125×11 (inches) crashes.

mlmcl62 commented 5 years ago

First off, make sure that the latest TWAIN driver supplied by the vendor is installed and in use on the system you're having a problem with.

The lasst message in the log file indicates that the TWAIN Driver and DSM successfully transferred the image data to the application. Assuming that no log information was lost, this suggests that the problem occurred within the application code. The health of the system can be confirmed by using a different application.

If you run the TWAIN Test Tool that comes with the TWAIN CS program, you should be able to do a scan session doing native transfers through the following steps: send: DG_CONTROL / DAT_PARENT / MSG_OPENDSM send: DG_CONTROL / DAT_ENTRYPOINT / MSG_GET

For the next two commands, stop as soon as you see the scanner you want to use: send: DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST send: DG_CONTROL / DAT_IDENTITY / MSG_GETNEXT

Open the scanner driver: send: DG_CONTROL / DAT_IDENTITY / MSG_OPENDS

Select native transfer: Clear any text in the text box, and enter: ICAP_XFERMECH send: DG_CONTROL / DAT_CAPABILITY / MSG_GETCURRENT If the last number in the text back is 0, you're done. If it's anything other than 0, then change it to 0, and then send: DG_CONTROL / DAT_CAPABILITY / MSG_SET

Press the scan button, and insert a document that causes a crash. If the test tool crashes or fails to display the image, this will implicate either TWAIN CS or TWAINDSM as being the source of the problem. If the scan is successful, then it's quite likely a problem is occurring when the application is processing the bitmap data.

One trick that's useful when debugging C# (assuming Visual Studio is being used) is to go to the Debug menu item and bring up the Exceptions windows. If in doubt, check everything. This will allow the debugger to break when try/catch statements occur, and may help point to where the problem is occurring.

gwyn17 commented 5 years ago

BTW, yes I'm using the absolute latest TWAIN drivers.

I spent a long time last night going through the code and single stepping in VS. It came down to TWAIN.DatImagenativexfer() TWAIN.DsmMemFree(ref intptrBitmap) on line 5463 of TWAIN.cs. This ends up as ::GlobalFree() in dsm.cpp line 3808 (https://github.com/twain/twain-dsm/blob/master/TWAIN_DSM/src/dsm.cpp).

So I commented out that call, and now I can scan small images on the Fujitsu (I don't have easy access to the Kodak) I spent an hour repeatedly scanning 37 pages through the sheet feeder to convince myself that my .exe isn't leaking memory. (Would memory allocated by the TWAIN driver .dll show up as memory used by the .exe? I'm no Windows expert.)

To recap - 8.5" x 11" images the DsmMemFree() was fine. With 4" x 11" images, the DsmMemFree() was cauisng the app to crash. What's more, If I switch to IMAGEFILEXFER, I can't scan 8.5" x 11" images fine, but the 4" x 11" images get the scan width wrong, so the resulting tiff has every line skewed a few pixels. In other words, "Something's fucky" and I suspect it's in the driver.

Next I have to test on the Kodak.

mlmcl62 commented 5 years ago

It looks like an older version of TWAIN CS is being used. The latest version has that line in TWAIN.CS at about 6363.

Looking at the TWAIN CS.rtf file, and the Source Forge tickets (before we moved to github), I think there's an excellent chance the problem will be resolved by moving to the latest code.

gwyn17 commented 5 years ago

Will try it out. Thank you.

gwyn17 commented 5 years ago

I can confirm that version 2.4.0.0 doesn't crash on the Fujitsu. I have also confirmed that my "patch" didn't crash on the Kodak.

I notice that 2.4.0.0 uses Marshal.FreeHGlobal() to free intptrBitmap, where 2.3.1.2 used DsmMemFree().

mlmcl62 commented 5 years ago

Thanks for the info. Hopefully the patch isn't needed with any scanner when using the latest TWAIN CS. Ideally TWAIN CS would use DsmMemFree(), which is defined by the DSM. But I seem to remember the Marshaller giving me grief, implying that Marshal.FreeHGlobal() does more than ::GlobalFree(), which is why I had to make the switch. It seems likely that some memory corruption was going on under the hood using ::GlobalFree(), and the DSM was just the lucky bit of code that ran into it...

gwyn17 commented 5 years ago

Almost makes you think Marshal.FreeHGlobal() can detect which heap memory was allocated from and deallocate it correctly.

gwyn17 commented 5 years ago

Update to say that 2.4.0.0 does not crash on Kodak i1440. This is great news and we can close this ticket.