TWAIN Working Group

Newsletter Signup
Donate
Help keep TWAIN free
  • About TWAIN
    • What’s New?
    • News
    • Events
    • Membership
    • Consider a Donation
    • Contact Us
  • Why TWAIN?
  • Developers
    • Driver Developer
    • Application Developer
    • TWAIN Features
    • Specification & Tools
    • Self Certification Process
  • Support Forums
  • Scanner End-User
  • Find Certified Drivers
    • Facebook
    • LinkedIn
    • Vimeo

Crash if force close Data Source when acquire image

Forums › TWAIN Classic › Crash if force close Data Source when acquire image

  • This topic has 2 replies, 1 voice, and was last updated 5 years, 10 months ago by kmbui.
Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • March 11, 2015 at 5:52 am #22999 Reply
    kmbui
    Participant
    • Topics - 1
    • Replies - 2
    • Total Posts - 3

    Hi,

    I write a dll that handle image acquire from imaging software data source.
    There is a strange case that cost me days without any solution:
    1. Use PortView (an Twain data source from Port View imaging software).
    2. Open PortView to acquire image.
    3. In PortView, import an image, then close (press X button on UI).
    4. Close data source programmatically:
    (*g_pDSM_Entry) (&g_AppID, 0, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &srcID)
    Then my dll crash.

    In step #3, in does not crash if:
    3a. Close PortView without importing an image (has no image).
    3b. Click Send button on UI to send the image to the dll.

    I try do find any different between the crash case and 3b to do something specially, but there’s nothing:
    – Both case has: event.TWMessage == MSG_XFERREADY (In 3a event.TWMessage == MSG_CLOSEDSREQ).
    – Both case has image transferred back to the dll.

    Any hint would be much appreciated.
    Thanks,

    March 11, 2015 at 6:01 am #26253 Reply
    kmbui
    Participant
    • Topics - 1
    • Replies - 2
    • Total Posts - 3

    More info:
    In step #4, i call 3 commands:

    4.1. (*g_pDSM_Entry) (&g_AppID, &srcID, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &ui)
    4.2. (*g_pDSM_Entry) (&g_AppID, 0, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &srcID)
    4.3 (*g_pDSM_Entry) (&g_AppID, 0, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&hwnd)

    and it crash at #4.2.
    if i comment out #4.1, it crash at 4.3.

    March 11, 2015 at 6:03 am #26254 Reply
    kmbui
    Participant
    • Topics - 1
    • Replies - 2
    • Total Posts - 3

    Here is my whole function:


    static int acquireByName(JNIEnv *env, BOOL showUI, BOOL modal, const char* sourceName, int maxImages, jobjectArray images)
    {
    TW_UINT16 rc;

    // Create a static window whose handle is passed to DSM_Entry() when we
    // open the data source manager.
    HWND hwnd = CreateWindow("STATIC",
    sourceName,
    WS_POPUPWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    HWND_DESKTOP,
    0,
    g_hinstDLL,
    0);

    // If window could not be created, throw exception. Because the exception
    // is not actually thrown until execution returns to Java, we must return
    // a value -- (jobject) 0 was chosen to represent Image null. This value
    // will not be seen in the Java code because of the exception.
    if (hwnd == 0)
    {
    return TWRC_FAILURE;
    }

    // Ensure that the default data source's dialog box does not disappear
    // behind other windows, which can be very disconcerting to the user. We do
    // that by making the hwnd -- created above and passed to DSM_Entry() below
    // -- the handle of the topmost window.
    SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW);

    // Open Data Source Manager
    BLOCK_BEGIN(1)

    // Open the data source manager.
    rc = (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_PARENT,
    MSG_OPENDSM,
    (TW_MEMREF)&hwnd);

    // If data source manager could not be opened, throw exception. Because the
    // exception is not actually thrown until execution returns to Java, we
    // first exit current block to destroy previously-created window and return
    // a value (which isn't seen in the Java code).
    if (rc != TWRC_SUCCESS)
    {
    EXIT_CURRENT_BLOCK
    }

    // Open Data Source
    BLOCK_BEGIN(2)

    // Find the data source match the name
    TW_IDENTITY srcID;
    memset(&srcID, 0, sizeof(srcID));
    BOOL found = FALSE;

    // Check with first DataSource
    rc = (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_IDENTITY,
    MSG_GETFIRST,
    (TW_MEMREF)&srcID);
    if (rc == TWRC_SUCCESS)
    {
    // found
    if (_stricmp(srcID.ProductName, sourceName) == 0)
    {
    found = TRUE;
    }
    else
    {
    do
    {
    rc = (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_IDENTITY,
    MSG_GETNEXT,
    (TW_MEMREF)&srcID);
    if (rc == TWRC_SUCCESS)
    {
    // found
    if (_stricmp(srcID.ProductName, sourceName) == 0)
    {
    found = TRUE;
    break;
    }
    }
    } while (rc == TWRC_SUCCESS);
    }

    if (found != TRUE)
    {
    EXIT_CURRENT_BLOCK
    }
    }
    else
    {
    EXIT_CURRENT_BLOCK
    }

    // Open the selected data source.
    rc = (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_IDENTITY,
    MSG_OPENDS,
    &srcID);

    // If default data source could not be opened, throw exception. Because the
    // exception is not actually thrown until execution returns to Java, we
    // first exit current block to close data source manager and destroy the
    // previously-created window.
    if (rc != TWRC_SUCCESS)
    {
    EXIT_CURRENT_BLOCK
    }

    // Does capturing
    BLOCK_BEGIN(3)

    // Prepare to enable the default data source. Make sure to show the data
    // source's own user interface (dialog box).
    TW_USERINTERFACE ui;
    ui.ShowUI = showUI;
    ui.ModalUI = modal;
    ui.hParent = hwnd;

    // Enable the default data source.
    rc = (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_USERINTERFACE,
    MSG_ENABLEDS,
    &ui);

    // If default data source could not be enabled, throw exception. Because
    // the exception is not actually thrown until execution returns to Java, we
    // first exit current block to close data source, close data source
    // manager and destroy the previously-created window.
    if (rc != TWRC_SUCCESS)
    {
    EXIT_CURRENT_BLOCK
    }

    // Begin the event-handling loop. Data transfer takes place in this loop.
    MSG msg;
    TW_EVENT event;
    TW_PENDINGXFERS pxfers;
    memset(&pxfers, 0, sizeof(TW_PENDINGXFERS));

    while (GetMessage((LPMSG)&msg, 0, 0, 0))
    {
    // Each window message must be forwarded to the data source.
    event.pEvent = (TW_MEMREF)&msg;
    event.TWMessage = MSG_NULL;

    rc = (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_EVENT,
    MSG_PROCESSEVENT,
    (TW_MEMREF)&event);

    // If the message does not correspond to a data source event, we must
    // dispatch it to the appropriate Windows window.
    if (rc == TWRC_NOTDSEVENT)
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);
    continue;
    }

    // If the default data source is requesting that the data source's
    // dialog box be closed (user pressed Cancel), we must break out of the
    // message loop.
    if (event.TWMessage == MSG_CLOSEDSREQ)
    break;

    // If the default data source is requesting that it is ready to begin
    // the data transfer, we must perform that transfer.
    if (event.TWMessage == MSG_XFERREADY)
    {
    int acquiredImages = 0;
    do
    {
    // Obtain information about the first image to be transferred.
    TW_IMAGEINFO ii;
    rc = (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_IMAGE,
    DAT_IMAGEINFO,
    MSG_GET,
    (TW_MEMREF)&ii);

    // If unable to obtain image information ...
    if (rc != TWRC_SUCCESS)
    {
    // Cancel all transfers.
    (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_PENDINGXFERS,
    MSG_RESET,
    (TW_MEMREF)&pxfers);

    // break out of event loop.
    break;
    }

    // If image is compressed or is not 8-bit color and not 24-bit color ...
    if (ii.Compression != TWCP_NONE || ii.BitsPerPixel != 8 && ii.BitsPerPixel != 24)
    {
    // Cancel all transfers.
    (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_PENDINGXFERS,
    MSG_RESET,
    (TW_MEMREF)&pxfers);

    // break out of event loop.
    break;
    }

    // Perform the transfer.
    TW_UINT32 handle;

    rc = (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_IMAGE,
    DAT_IMAGENATIVEXFER,
    MSG_GET,
    (TW_MEMREF)&handle);

    // If image not successfully transferred ...
    if (rc != TWRC_XFERDONE)
    {
    // Cancel all remaining transfers.
    (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_PENDINGXFERS,
    MSG_RESET,
    (TW_MEMREF)&pxfers);

    // break out of event loop.
    break;
    }

    rc = (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_PENDINGXFERS,
    MSG_ENDXFER,
    (TW_MEMREF)&pxfers);

    // Transfer Windows-based DIB to a Java-based Image (via a MemoryImageSource).
    LPBITMAPINFOHEADER lpbmih;
    lpbmih = (LPBITMAPINFOHEADER)GlobalLock((HANDLE)handle);

    jobject image;
    /*if (ii.BitsPerPixel == 8)
    {
    image = xferDIB8toImage(lpbmih, env);
    }
    else
    {
    image = xferDIB24toImage(lpbmih, env);
    }
    env->SetObjectArrayElement(images, acquiredImages, image);*/

    GlobalUnlock((HANDLE)handle);
    GlobalFree((HANDLE)handle);

    acquiredImages++;
    if (acquiredImages >= maxImages)
    {
    // Cancel all remaining transfers.
    (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_PENDINGXFERS,
    MSG_RESET,
    (TW_MEMREF)&pxfers);

    // break out of acquire loop.
    break;
    }
    } while (pxfers.Count != 0);

    // break out of event loop.
    break;
    }
    }

    // Disable the data source.
    (*g_pDSM_Entry) (&g_AppID,
    &srcID,
    DG_CONTROL,
    DAT_USERINTERFACE,
    MSG_DISABLEDS,
    &ui);

    BLOCK_END(3)

    // Close the data source.
    (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_IDENTITY,
    MSG_CLOSEDS,
    &srcID);

    BLOCK_END(2)

    // Close the data source manager.
    (*g_pDSM_Entry) (&g_AppID,
    0,
    DG_CONTROL,
    DAT_PARENT,
    MSG_CLOSEDSM,
    (TW_MEMREF)&hwnd);

    BLOCK_END(1)

    DestroyWindow(hwnd);

    return TWRC_SUCCESS;
    }
  • Author
    Posts
Viewing 3 posts - 1 through 3 (of 3 total)
Reply To: Crash if force close Data Source when acquire image
Your information:




Quick Links

Service Providers
TWAIN Support Forums
Membership
Contact Us
Privacy Policy

Newsletter Signup

TWAIN Working Group Family

TWAIN Working Group
TWAIN Direct®
TWAIN Resources
TWAIN Certified Drivers
PDF/raster

  • Facebook
  • GitHub
  • LinkedIn
  • Vimeo

Recent Topics

  • EPSON V600 TWAIN and WIA on Windows 10
  • When and how to use WaitForEvents command ?
  • Problem enumerating list of installed scanners in windows server 2012
  • Failed to create TWAIN progress! Error code is 1260.
  • To get the list of scanners from javascript client side (browser)
  • Quarterly Newsletter
  • TWAIN Working Group Membership
  • Logo Usage
  • TWAIN License
  • Contact Us
Privacy Policy • Privacy Tools • Copyright © 2021 TWAIN Working Group • by iHwy, LLC • Log in

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.