Can the display mirror driver call into the original display card's DrvEnablePDEV?

Discussion in 'Windows Vista Drivers' started by lucy, Aug 25, 2004.

  1. lucy

    lucy Guest

    Dear all drivers/GDI gurus,

    I have already got comments from experts such as Tim and Vipin that I cannot
    call into the original display card's DrvEnablePDEV from my dummy
    DrvEnablePDEV in the MSDDK sample mirror driver. I just want to ask if this
    is fundamentally not going to work?

    Then what is the easiest way to modify the sample mirror driver to call the
    original display card's DrvEnablePDEV? All I need is that GDIINFO
    structure...

    If the mirror driver cannot fundamentally not do that, what shall I do?

    Here is my code in the enable.c inside the mirror\disp\ directory. As you
    can see, I passed the parameters from GDI to the display card's
    DrvEnablePDEV directly without any change(except that I created two local
    structure: pDevInfo1, and pGdiInfo1, and passed to the display card's
    DrvEnablePDEV, and hope the display card's DrvEnablePDEV will fill these two
    structure upon returnning, then I copy these two structure back to return to
    GDI).

    The program successfully runs into the following command:

    DISPDBG((0,"DISP Succeeded in locating DrvEnablePDEV in ati2dvag.dll%d\n",
    pOldDrvEnablePDEV));

    Then upon calling "ppdev=(PPDEV)((pOldDrvEnablePDEV)( ...)", it BSOD
    UNEXPECTED_KERNEL_MODE_TRAP_M...

    What might be the problem? Any thought? Your
    comments/help/advice/suggestions/hints would be greatly appreciated!

    Thank you so much!

    -Lucy
    ----------------------------------------------------------------

    DHPDEV DrvEnablePDEV(
    DEVMODEW *pDevmode, // Pointer to DEVMODE
    PWSTR pwszLogAddress, // Logical address
    ULONG cPatterns, // number of patterns
    HSURF *ahsurfPatterns, // return standard patterns
    ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
    ULONG *pGdiInfo, // Pointer to GdiInfo structure
    ULONG cjDevInfo, // Length of following PDEVINFO structure
    DEVINFO *pDevInfo, // physical device information structure
    HDEV hdev, // HDEV, used for callbacks
    PWSTR pwszDeviceName, // DeviceName - not used
    HANDLE hDriver) // Handle to base driver
    {
    GDIINFO * pGdiInfo1;
    DEVINFO * pDevInfo1;
    PPDEV ppdev = (PPDEV) NULL;
    HANDLE hh;
    OLDDRVENABLEDRIVER pOldDrvEnableDriver;
    PFN pOldDrvEnablePDEV;
    LPWSTR drivername=L"ati2dvag.dll";
    LPSTR functionname1="DrvEnableDriver";
    DRVENABLEDATA *pded;
    ULONG i;

    DISPDBG((0,"DrvEnablePDEV:\n"));

    UNREFERENCED_PARAMETER(pwszLogAddress);
    UNREFERENCED_PARAMETER(pwszDeviceName);


    pGdiInfo1 = (GDIINFO *) EngAllocMem(FL_NONPAGED_MEMORY|FL_ZERO_MEMORY,
    sizeof(GDIINFO), ALLOC_TAG);
    if (pGdiInfo1 == (GDIINFO *) NULL)
    {
    RIP("DISP DrvEnablePDEV failed EngAllocMem for GDIINFO\n");
    return((DHPDEV) 0);
    }

    pDevInfo1 = (DEVINFO *) EngAllocMem(FL_NONPAGED_MEMORY|FL_ZERO_MEMORY,
    sizeof(DEVINFO), ALLOC_TAG);
    if (pDevInfo1 == (DEVINFO *) NULL)
    {
    RIP("DISP DrvEnablePDEV failed EngAllocMem for DEVINFO\n");
    return((DHPDEV) 0);
    }


    pded = (DRVENABLEDATA *) EngAllocMem(FL_NONPAGED_MEMORY|FL_ZERO_MEMORY,
    sizeof(DEVINFO), ALLOC_TAG);
    if (pded == (DRVENABLEDATA *) NULL)
    {
    RIP("DISP DrvEnablePDEV failed EngAllocMem for DRVENABLEDATA\n");
    return((DHPDEV) 0);
    }
    // Allocate a physical device structure.
    ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);

    if (ppdev == (PPDEV) NULL)
    {
    RIP("DISP DrvEnablePDEV failed EngAllocMem for PPDEV\n");
    return((DHPDEV) 0);
    }

    memset(ppdev, 0, sizeof(PDEV));

    // Save the screen handle in the PDEV.

    ppdev->hDriver = hDriver;

    // Get the current screen mode information. Set up device caps and
    devinfo.

    hh=EngLoadImage(drivername);
    DISPDBG((0,"DISP Load old ati2dvag.dll %d\n", hh));

    pOldDrvEnableDriver=(OLDDRVENABLEDRIVER)EngFindImageProcAddress(hh,
    functionname1);
    DISPDBG((0,"DISP Load DrvEnableDriver in old ati2dvag.dll %d\n",
    pOldDrvEnableDriver));

    if ((BOOL)(pOldDrvEnableDriver)(DDI_DRIVER_VERSION_NT5_01,
    sizeof(DRVENABLEDATA), pded))
    {
    DISPDBG((0,"DISP Load DrvEnableDriver in old ati2dvag.dll
    succeeded\n"));

    pOldDrvEnablePDEV=NULL;
    for (i=0; i<pded->c; i++)
    if (pded->pdrvfn.iFunc==INDEX_DrvEnablePDEV)
    {
    pOldDrvEnablePDEV=pded->pdrvfn.pfn;
    break;
    }

    if (pOldDrvEnablePDEV!=NULL)
    {
    DISPDBG((0,"DISP Succeeded in locating DrvEnablePDEV in
    ati2dvag.dll%d\n", pOldDrvEnablePDEV));
    ppdev=(PPDEV)((pOldDrvEnablePDEV)(pDevmode, // Pointer to
    DEVMODE
    pwszLogAddress, // Logical address
    cPatterns, // number of patterns
    ahsurfPatterns, // return standard patterns
    sizeof(GDIINFO), // Length of memory pointed to by
    pGdiInfo
    (ULONG *)pGdiInfo1, // Pointer to GdiInfo structure
    sizeof(DEVINFO), // Length of following PDEVINFO structure
    pDevInfo1, // physical device information structure
    hdev, // HDEV, used for callbacks
    pwszDeviceName, // DeviceName - not used
    hDriver)); // Handle to base driver

    if (ppdev!=NULL)
    {
    DISPDBG((0,"DISP Calling Old DrvEnablePDEV Succeeded GDIINFO\n"));
    DISPDBG((0, "Gamma=%d\n", pGdiInfo1->ulPhysicalPixelGamma));
    }
    else
    DISPDBG((0,"DISP Calling Old DrvEnablePDEV Failed %d\n", ppdev));

    }
    else
    DISPDBG((0,"DISP Failed in locating DrvEnablePDEV in
    ati2dvag.dll\n", pOldDrvEnablePDEV));
    }
    else
    DISPDBG((0,"DISP Load DrvEnableDriver in old ati2dvag.dll failed\n"));



    //EngUnloadImage(hh);

    -----------------------------------------------------------
    Here is the clash dump:

    1: kd> !analyze -v
    ****************************************************************************
    ***
    *
    *
    * Bugcheck Analysis
    *
    *
    *
    ****************************************************************************
    ***

    UNEXPECTED_KERNEL_MODE_TRAP_M (1000007f)
    This means a trap occurred in kernel mode, and it's a trap of a kind
    that the kernel isn't allowed to have/catch (bound trap) or that
    is always instant death (double fault). The first number in the
    bugcheck parens is the number of the trap (8 = double fault, etc)
    Consult an Intel x86 family manual to learn more about what these
    traps are. Here is a *portion* of those codes:
    If kv shows a taskGate
    use .tss on the part before the colon, then kv.
    Else if kv shows a trapframe
    use .trap on that value
    Else
    .trap on the appropriate frame will show where the trap was taken
    (on x86, this will be the ebp that goes with the procedure KiTrap)
    Endif
    kb will then show the corrected stack.
    Arguments:
    Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
    Arg2: f7727d70
    Arg3: 00000000
    Arg4: 00000000

    Debugging Details:
    ------------------


    BUGCHECK_STR: 0x7f_8

    CUSTOMER_CRASH_COUNT: 5

    DEFAULT_BUCKET_ID: COMMON_SYSTEM_FAULT

    LAST_CONTROL_TRANSFER: from bac7edf9 to bac7edf1

    STACK_TEXT:
    WARNING: Stack unwind information not available. Following frames may be
    wrong.
    b82ba028 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df1
    b82ba064 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba0a0 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba0dc bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba118 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba154 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba190 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba1cc bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba208 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba244 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba280 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba2bc bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba2f8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba334 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba370 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba3ac bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba3e8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba424 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba460 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba49c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba4d8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba514 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba550 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba58c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba5c8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba604 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba640 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba67c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba6b8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba6f4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba730 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba76c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba7a8 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba7e4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba820 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba85c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba898 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba8d4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba910 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba94c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba988 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82ba9c4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baa00 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baa3c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baa78 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baab4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baaf0 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82bab2c bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82bab68 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9
    b82baba4 bac7edf9 00000000 e154c508 00000000 siwvid+0x7df9


    FOLLOWUP_IP:
    siwvid+7df1
    bac7edf1 ff7510 push dword ptr [ebp+0x10]

    SYMBOL_STACK_INDEX: 0

    FOLLOWUP_NAME: MachineOwner

    SYMBOL_NAME: siwvid+7df1

    MODULE_NAME: siwvid

    IMAGE_NAME: siwvid.sys

    DEBUG_FLR_IMAGE_TIMESTAMP: 3fd8b4b2

    STACK_COMMAND: kb

    BUCKET_ID: 0x7f_8_siwvid+7df1

    Followup: MachineOwner
    ---------
     
    lucy, Aug 25, 2004
    #1
    1. Advertisements

  2. lucy

    vipin Guest

    simple:-
    PDEV/SURFOBJ coming into the mirror driver is meant to be used by the mirror
    driver and not by someother driver which won't be able to understand the
    mirror driver's PDEV. Just build a dll(referring to permedia/mirror sample)
    and then put in the directory of the real driver. Rename the dll to the real
    driver's name and Rename the real driver dll to something like
    realname-load.dll. Now do an EngLoadImage(...) from the filter dll and call
    the right functions.

    Thanks
    vipin

     
    vipin, Aug 26, 2004
    #2
    1. Advertisements

  3. lucy

    lucy Guest

    Hi Vipin,

    Thank you for your very great suggestions. But I have one question regarding
    this approach. Is your idea the same as filter driver? A simple mirror which
    only implements few DrvXXXXXX cannot pretend to be the real ATI driver,
    because maybe the real ATI driver has many DrvXXXXXX functions and other
    stranger functions which I don't know...

    If the real ATI driver dll is "ati2dvag.dll", and I changed it to
    "oldati2dvag.dll";

    Then I pretend my mirror driver to be the real ATI driver, by changing the
    name from "mirror.dll" to "ati2dvag.dll", ...

    Then the system will regard the mirror driver as the real ATI's driver, so I
    have to fullfill every functionality of the real ATI's driver, otherwise the
    sytem will be screwed up... am I right?

    In order to fulfill every functionality of the real ATI's driver, I need to
    know all those functions from its DrvEnableDriver function and the returned
    value of PDRVENABLEDATA structure... Then I need to write a wrapper function
    for all of these functions, when the GDI calls me on these functions, I in
    turn call the original real ATI driver. This is concept of filter driver...
    am I right?

    The problem is that I don't know how many such functions does the real ATI's
    driver implement and expose, ... how do I write these functions before
    compile time? And how do I know their calling conventions and argument
    types? I also suspect that different display card, from ATI, or Nividia, has
    different number of the DrvXXXXX functions implemented, so I have to write
    wrapper functions for each of these cards one by one, and then compile the
    filter drivers for these cards one by one... because they implements and
    exports different set of DrvXXXXX functions... am I right?

    The worst case is that if their DLL file has more functions than the
    DrvXXXXXX functions which I don't know, and thus I don't have wrapper
    function for these stranger functions, then by pretending I am the real ATI
    driver, the system will be screwed up...

    Any more thoughts? Thanks a lot for your help!

    static DRVFN gadrvfn[] =
    {
    { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
    { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
    { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
    { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
    { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
    { INDEX_DrvAssertMode, (PFN) DrvAssertMode },
    { INDEX_DrvEscape, (PFN) DrvEscape },
    { INDEX_DrvCreateDeviceBitmap, (PFN) DrvCreateDeviceBitmap },
    { INDEX_DrvDeleteDeviceBitmap, (PFN) DrvDeleteDeviceBitmap },
    { INDEX_DrvTextOut, (PFN) DrvTextOut },
    { INDEX_DrvBitBlt, (PFN) DrvBitBlt },
    { INDEX_DrvCopyBits, (PFN) DrvCopyBits },
    { INDEX_DrvStrokePath, (PFN) DrvStrokePath },
    };
     
    lucy, Aug 26, 2004
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.