dynarithmic / twain_library

Dynarithmic TWAIN Library, Version 5.x
Apache License 2.0
64 stars 26 forks source link

Application crashing when acquiring images #119

Open sean-neeley opened 1 month ago

sean-neeley commented 1 month ago

We have a customer using our scanning application we wrote in C# that uses the latest DTWAIN library. While acquiring images, sometimes there is an application crash. The scanner is an HP Scanjet Enterprise N6600 FNW1.

I'm not too familiar with how to read the DTWAIN logs. I was hoping you could look over the log we captured and see if anything stands out to you. Our own app log shows DTWAIN errors 1038, 1101, 1106, followed by 1005:

2024-09-17 09:02:40,323 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=DTWAIN_TN_GENERALERROR
2024-09-17 09:02:40,323 [1] INFO  PProScanning.MainForm - Error -1101: TWAIN Condition Code: No Error
2024-09-17 09:02:40,336 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=1106
2024-09-17 09:02:40,336 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=1005
2024-09-17 09:25:36,594 [1] INFO  PProScanning.MainForm - Application exiting.
2024-09-17 09:25:36,640 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=DTWAIN_TN_GENERALERROR
2024-09-17 09:25:36,640 [1] INFO  PProScanning.MainForm - Error -32: -32
2024-09-17 09:25:36,640 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=DTWAIN_TN_GENERALERROR
2024-09-17 09:25:36,656 [1] INFO  PProScanning.MainForm - Error -32: -32
2024-09-17 09:25:36,656 [1] INFO  PProScanning.MainForm - TwainCallbackProc wParam=DTWAIN_TN_GENERALERROR
2024-09-17 09:25:36,656 [1] INFO  PProScanning.MainForm - Error -1102: TWAIN Condition Code: Unknown cause of failure

The end of the DTWAIN log shows:

DSM_Entry(pSource=00000270371A3EB8H, pDest=0000000000000000H, DG_CONTROL, DAT_STATUS, MSG_GET, TW_MEMREF=000000AB46FF9A80H) called
Decoded pSource:
{
    Id=1
    Version Number=1.0
    Version Language=13
    Version Country=1
    Version Info=4.0.3.1
    ProtocolMajor=2
    ProtocolMinor=5
    SupportedGroups= DG_CONTROL, DG_IMAGE, DG_AUDIO, DF_DSM2, DF_APP2
    Manufacturer=Produce Pro
    Product Family=Produce Pro
    Product Name=PPro Scanning
}

No information for pDest

TW_MEMREF is TW_STATUS:
{
    ConditionCode=0  TWCC_SUCCESS
}

[2024-09-17 09:02:40] To callback: 
DTWAIN Message(HWND = 0000000000000000, MSG = 49668, Notification code = 1038, LPARAM = -1101

[2024-09-17 09:02:40]          ===>>>Entering DTWAIN_GetLastError()
[2024-09-17 09:02:40]          <<<===Exiting DTWAIN_GetLastError returning value of -1101
[2024-09-17 09:02:40]          ===>>>Entering DTWAIN_GetErrorString(lError=-1101, lpszBuffer=000000AB46FF8F60, nMaxLen=256)
[2024-09-17 09:02:40]          <<<===Exiting DTWAIN_GetErrorString returning value of 31
[2024-09-17 09:02:40] 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_TWAINPAGEFAILED, LPARAM = 2680985347424

[2024-09-17 09:02:40] To callback: 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_TWAINPAGEFAILED, LPARAM = 2680985347424

[2024-09-17 09:02:40] 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_PAGEFAILED, LPARAM = 2680985347424

[2024-09-17 09:02:40] To callback: 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_PAGEFAILED, LPARAM = 2680985347424

[2024-09-17 09:02:40] Input: 
DSM_Entry(pSource=00000270371A3EB8H, pDest=00000270372DE624H, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, TW_MEMREF=000000AB46FF9A22H) called
Decoded pSource:
{
    Id=1
    Version Number=1.0
    Version Language=13
    Version Country=1
    Version Info=4.0.3.1
    ProtocolMajor=2
    ProtocolMinor=5
    SupportedGroups= DG_CONTROL, DG_IMAGE, DG_AUDIO, DF_DSM2, DF_APP2
    Manufacturer=Produce Pro
    Product Family=Produce Pro
    Product Name=PPro Scanning
}

Decoded pDest:
{
    Id=1
    Version Number=2.4
    Version Language=2
    Version Country=1
    Version Info=2.4
    ProtocolMajor=2
    ProtocolMinor=4
    SupportedGroups= DG_CONTROL, DG_IMAGE, DF_DS2
    Manufacturer=HP Inc.
    Product Family=HP
    Product Name=HP TWAIN USB
}

TW_MEMREF is TW_PENDINGXFERS:
{
    Count=0
    EOJ=0
}

[2024-09-17 09:02:40] 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_TWAINTRIPLETBEGIN, LPARAM = 0

[2024-09-17 09:02:40] To callback: 
DTWAIN Message(HWND = 00000000000400E2, MSG = 49668, Notification code = DTWAIN_TN_TWAINTRIPLETBEGIN, LPARAM = 0

[2024-09-17 09:25:36]          ===>>>Entering DTWAIN_SysDestroy()
[2024-09-17 09:25:36]             ===>>>Entering DTWAIN_EndTwainSession()

Attached is the full log.

DTWAIN.log

Thank you!

dynarithmic commented 1 month ago

From the DTWAIN logs, it seems to be that the scanner's driver did not fill in the information about the strip that is to be transferred to DTWAIN when acquiring in buffered mode.

Starting at line 515780 of the DTWAIN log, that is where DTWAIN sets up the TW_IMAGEMEMXFER structure. This structure is then sent to the TWAIN driver to fill in with the information on the next strip. The returned value from the scanner starts at line 515838. Note that values you see there are the original ones DTWAIN set up, meaning the scanner failed to rewrite those values with sensible ones. The scanner did return a failure code, but the reason for the failure is basically unknown, as all the previous calls using TW_IMAGEMEMXFER all pass with a success code.

For example, contrast this to what you see at line 514948 (the input set up by DTWAIN), with the follow-up data returned by the scanner on line 515006 (the output sent by the scanner). The values returned by the scanner are reasonable.

The application shouldn't crash, but report a failure and stop the buffered transfer. I will see what DTWAIN does in event of a failed TW_IMAGEMEMXFER / MSG_GET operation, but as far as to why the scanner failed, I really don't have an explanation of what the issue would be.

If you acquired the image using native mode, is there still an issue?

dynarithmic commented 1 month ago

Also, if you set DTWAIN_SetMaxRetryAttempts to 0, possibly the application won't crash, since there will be no retry of the failed page.

Also, you can trap the DTWAIN_TN_PAGEFAILED notification and return 0 for this notification so as to stop the processing of the page.

sean-neeley commented 1 month ago

As always, we appreciate your suggestions. Will investigate and get back to you!