⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddraw.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * PURPOSE:          Native DirectDraw implementation
 * FILE:             subsys/win32k/ntddraw/ddraw.c
 * PROGRAMER:        Peter Bajusz (hyp-x@stormregion.com)
 * PROGRAMER:        Magnus olsen (magnus@greatlord.com)
 * REVISION HISTORY:
 *       25-10-2003  PB  Created
         from 2003 to year 2007
 *       rewrote almost all code Peter did.
 *       only few line are left from him
 */

#include <w32k.h>

//#define NDEBUG
#include <debug.h>

/* swtich this off to get rid of all dx debug msg */
#define DX_DEBUG

#define DdHandleTable GdiHandleTable




/************************************************************************/
/* DIRECT DRAW OBJECT                                                   */
/************************************************************************/

BOOL INTERNAL_CALL
DD_Cleanup(PVOID ObjectBody)
{
    PDD_DIRECTDRAW pDirectDraw = (PDD_DIRECTDRAW) ObjectBody;

    DPRINT1("DD_Cleanup\n");

    if (!pDirectDraw)
    {
        return FALSE;
    }

    if (pDirectDraw->Global.dhpdev == NULL)
    {
        return FALSE;
    }

    if (pDirectDraw->DrvDisableDirectDraw == NULL)
    {
        return FALSE;
    }

    pDirectDraw->DrvDisableDirectDraw(pDirectDraw->Global.dhpdev);
    return TRUE;
}

/* code for enable and reanble the drv */
BOOL
intEnableDriver(PDD_DIRECTDRAW pDirectDraw)
{
     BOOL success;
     DD_HALINFO HalInfo;

    /*clean up some of the cache entry */
    RtlZeroMemory(&pDirectDraw->DD,   sizeof(DD_CALLBACKS));
    RtlZeroMemory(&pDirectDraw->Surf, sizeof(DD_SURFACECALLBACKS));
    RtlZeroMemory(&pDirectDraw->Pal,  sizeof(DD_PALETTECALLBACKS));
    RtlZeroMemory(&pDirectDraw->Hal,  sizeof(DD_HALINFO));
    RtlZeroMemory(&HalInfo,  sizeof(DD_HALINFO));
    pDirectDraw->dwNumHeaps =0;
    pDirectDraw->dwNumFourCC = 0;
    pDirectDraw->pdwFourCC = NULL;
    pDirectDraw->pvmList = NULL;

    /* Get DirectDraw infomations form the driver 
     * DDK say pvmList, pdwFourCC is always NULL in frist call here 
     * but we get back how many pvmList it whant we should alloc, same 
     * with pdwFourCC.
     */
    if (pDirectDraw->DrvGetDirectDrawInfo)
    {
        success = pDirectDraw->DrvGetDirectDrawInfo( pDirectDraw->Global.dhpdev, 
                                                     &HalInfo,
                                                     &pDirectDraw->dwNumHeaps,
                                                     NULL,
                                                     &pDirectDraw->dwNumFourCC,
                                                     NULL);
        if (!success)
        {
            DPRINT1("DrvGetDirectDrawInfo  frist call fail\n");
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }


        /* The driver are not respnose to alloc the memory for pvmList
         * but it is win32k responsible todo, Windows 9x it is gdi32.dll
         */
        if (pDirectDraw->dwNumHeaps != 0)
        {
            DPRINT1("Setup pvmList\n");
            pDirectDraw->pvmList = (PVIDEOMEMORY) ExAllocatePoolWithTag(PagedPool, pDirectDraw->dwNumHeaps * sizeof(VIDEOMEMORY), TAG_DXPVMLIST);
            if (pDirectDraw->pvmList == NULL)
            {
                DPRINT1("pvmList memmery alloc fail\n");
                return FALSE;
            }
        }

        /* The driver are not respnose to alloc the memory for pdwFourCC
         * but it is win32k responsible todo, Windows 9x it is gdi32.dll
         */

        if (pDirectDraw->dwNumFourCC != 0)
        {
            DPRINT1("Setup pdwFourCC\n");
            pDirectDraw->pdwFourCC = (LPDWORD) ExAllocatePoolWithTag(PagedPool, pDirectDraw->dwNumFourCC * sizeof(DWORD), TAG_DXFOURCC);

            if (pDirectDraw->pdwFourCC == NULL)
            {
                DPRINT1("pdwFourCC memmery alloc fail\n");
                return FALSE;
            }
        }
        success = pDirectDraw->DrvGetDirectDrawInfo( pDirectDraw->Global.dhpdev, 
                                                     &HalInfo,
                                                     &pDirectDraw->dwNumHeaps,
                                                     pDirectDraw->pvmList,
                                                     &pDirectDraw->dwNumFourCC,
                                                     pDirectDraw->pdwFourCC);
        if (!success)
        {
            DPRINT1("DrvGetDirectDrawInfo  second call fail\n");
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }


        /* We need now convert the DD_HALINFO we got, it can be NT4 driver we 
         * loading ReactOS supporting NT4 and higher to be loading.so we make
         * the HALInfo compatible here so we can easy pass it to gdi32.dll 
         * without converting it later 
        */

        if ((HalInfo.dwSize != sizeof(DD_HALINFO)) && 
            (HalInfo.dwSize != sizeof(DD_HALINFO_V4)))
        {
            DPRINT1(" Fail not vaild driver DD_HALINFO struct found\n");
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }

        if (HalInfo.dwSize != sizeof(DD_HALINFO))
        {
            if (HalInfo.dwSize == sizeof(DD_HALINFO_V4))
            {
                /* NT4 Compatible */
                DPRINT1("Got DD_HALINFO_V4 sturct we convert it to DD_HALINFO \n");
                HalInfo.dwSize = sizeof(DD_HALINFO);
                HalInfo.lpD3DGlobalDriverData = NULL;
                HalInfo.lpD3DHALCallbacks = NULL;
                HalInfo.lpD3DBufCallbacks = NULL;
            }
            else
            {
                /* Unknown version found */
                DPRINT1(" Fail : did not get DD_HALINFO size \n");
                GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
                return FALSE;
            }
        }
        /* Copy it to user mode pointer the data */
        RtlCopyMemory(&pDirectDraw->Hal, &HalInfo, sizeof(DD_HALINFO));
    }

    DPRINT1("Trying EnableDirectDraw the driver\n");

    success = pDirectDraw->EnableDirectDraw( pDirectDraw->Global.dhpdev, 
                                             &pDirectDraw->DD, 
                                             &pDirectDraw->Surf, 
                                             &pDirectDraw->Pal);

    if (!success)
    {
        DPRINT1("EnableDirectDraw call fail\n");
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    return TRUE;
}


/* NtGdiDdCreateDirectDrawObject is finish and works as it should
 * it maybe have some memory leack or handler leack in this code
 * if you found any case you maybe think it leacks the handler 
 * or memory please tell me, before you start fixing the code
 * Magnus Olsen
 */
HANDLE STDCALL 
NtGdiDdCreateDirectDrawObject(HDC hdc)
{
    DC *pDC;
    HANDLE hDirectDraw;
    PDD_DIRECTDRAW pDirectDraw;

    /* Create a hdc if we do not have one */
    if (hdc == NULL)
    {
       return NULL;
    }
    
    /* Look the hdc to gain the internal struct */
    pDC = DC_LockDc(hdc);
    if (!pDC)
    {
        return NULL;
    }

    /* test see if drv got a dx interface or not */
    if  ( ( pDC->DriverFunctions.DisableDirectDraw == NULL) ||
          ( pDC->DriverFunctions.EnableDirectDraw == NULL))
    {
        DC_UnlockDc(pDC);
        return NULL;
    }

    /* alloc and lock  the stucrt */
    hDirectDraw = GDIOBJ_AllocObj(DdHandleTable, GDI_OBJECT_TYPE_DIRECTDRAW);
    if (!hDirectDraw)
    {
        /* No more memmory */
        DC_UnlockDc(pDC);
        return NULL;
    }

    pDirectDraw = GDIOBJ_LockObj(DdHandleTable, hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW);
    if (!pDirectDraw)
    {
        /* invalid handle */
        DC_UnlockDc(pDC);
        return NULL;
    }

    /* setup the internal stuff */
    pDirectDraw->Global.dhpdev = pDC->PDev;
    pDirectDraw->Local.lpGbl = &pDirectDraw->Global;

    pDirectDraw->DrvGetDirectDrawInfo = pDC->DriverFunctions.GetDirectDrawInfo;
    pDirectDraw->DrvDisableDirectDraw = pDC->DriverFunctions.DisableDirectDraw;
    pDirectDraw->EnableDirectDraw = pDC->DriverFunctions.EnableDirectDraw;

    if (intEnableDriver(pDirectDraw) == FALSE)
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        DC_UnlockDc(pDC);
        return NULL;
    }

    GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
    DC_UnlockDc(pDC);
    return hDirectDraw;
}


/* NtGdiDdCreateDirectDrawObject is finish and works as it should
 * it maybe have some memory leack or handler leack in this code
 * if you found any case you maybe think it leacks the handler 
 * or memory please tell me, before you start fixing the code
 * Magnus Olsen
 */

BOOL STDCALL 
NtGdiDdQueryDirectDrawObject(
    HANDLE hDirectDrawLocal,
    DD_HALINFO  *pHalInfo,
    DWORD *pCallBackFlags,
    LPD3DNTHAL_CALLBACKS puD3dCallbacks,
    LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData,
    PDD_D3DBUFCALLBACKS puD3dBufferCallbacks,
    LPDDSURFACEDESC puD3dTextureFormats,
    DWORD *puNumHeaps,
    VIDEOMEMORY *puvmList,
    DWORD *puNumFourCC,
    DWORD *puFourCC
)
{
    PDD_DIRECTDRAW pDirectDraw;
    NTSTATUS Status = FALSE;
    BOOL Ret=FALSE;
    LPD3DNTHAL_GLOBALDRIVERDATA pD3dDriverData;

    if (hDirectDrawLocal == NULL)
    {
       return FALSE;
    }

    pDirectDraw = GDIOBJ_LockObj(DdHandleTable, hDirectDrawLocal,
                                 GDI_OBJECT_TYPE_DIRECTDRAW);
    if (!pDirectDraw)
    {
        return FALSE;
    }

    /*
     * Get pHalInfo 
     */
    if (pHalInfo != NULL)
    {
        _SEH_TRY
        {
            ProbeForWrite(pHalInfo,  sizeof(DD_HALINFO), 1);
            RtlCopyMemory(pHalInfo,&pDirectDraw->Hal, sizeof(DD_HALINFO));
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }
    }
    else
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    /*
     * Get pCallBackFlags
     */
    if (pCallBackFlags != NULL)
    {
        _SEH_TRY
        {
            ProbeForWrite(pCallBackFlags,  sizeof(DWORD)*3, 1);
            pCallBackFlags[0]=pDirectDraw->DD.dwFlags;
            pCallBackFlags[1]=pDirectDraw->Surf.dwFlags;
            pCallBackFlags[2]=pDirectDraw->Pal.dwFlags;
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }
    }
    else
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    /*
     * Get puD3dCallbacks
     */
    if ((puD3dCallbacks) && 
        (pDirectDraw->Hal.lpD3DHALCallbacks))
    {
        _SEH_TRY
        {
            ProbeForWrite(puD3dCallbacks,  sizeof(D3DNTHAL_CALLBACKS), 1);
            RtlCopyMemory( puD3dCallbacks, pDirectDraw->Hal.lpD3DHALCallbacks, sizeof( D3DNTHAL_CALLBACKS ) );
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }
    }
    else
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    /*
     * Get lpD3DGlobalDriverData
     */
    if ((puD3dDriverData) && 
        (pDirectDraw->Hal.lpD3DGlobalDriverData != NULL))
    {
        /* Get D3dDriverData */
        _SEH_TRY
        {
            ProbeForWrite(puD3dDriverData,  sizeof(D3DNTHAL_GLOBALDRIVERDATA), 1);
            RtlCopyMemory( puD3dDriverData, pDirectDraw->Hal.lpD3DGlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }

        /* Get TextureFormats */
        pD3dDriverData =pDirectDraw->Hal.lpD3DGlobalDriverData;
        if ((puD3dTextureFormats) && 
            (pD3dDriverData->dwNumTextureFormats>0) && 
            (pD3dDriverData->lpTextureFormats))
        {
            DWORD Size = sizeof(DDSURFACEDESC) * pD3dDriverData->dwNumTextureFormats;
            _SEH_TRY
            {
                ProbeForWrite(puD3dTextureFormats, Size, 1);
                RtlCopyMemory( puD3dTextureFormats, pD3dDriverData->lpTextureFormats, Size);
            }
            _SEH_HANDLE
            {
                Status = _SEH_GetExceptionCode();
            }
            _SEH_END;

            if(!NT_SUCCESS(Status))
            {
                SetLastNtError(Status);
                GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
                return FALSE;
            }
        }
    }
    else
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    /*Get D3dBufferCallbacks */
    if ( (puD3dBufferCallbacks) && 
         (pDirectDraw->Hal.lpD3DBufCallbacks))
    {
        _SEH_TRY
        {
            ProbeForWrite(puD3dBufferCallbacks,  sizeof(DD_D3DBUFCALLBACKS), 1);
            RtlCopyMemory( puD3dBufferCallbacks, pDirectDraw->Hal.lpD3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }
    }
    else
    {
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    /* Get puNumFourCC and dwNumFourCC */
    _SEH_TRY
    {
        ProbeForWrite(puNumFourCC, sizeof(DWORD), 1);
        *puNumFourCC = pDirectDraw->dwNumFourCC;

        if ((pDirectDraw->pdwFourCC) && 
            (puFourCC))
        {
            ProbeForWrite(puFourCC, sizeof(DWORD) * pDirectDraw->dwNumFourCC, 1);
            RtlCopyMemory( puFourCC, pDirectDraw->pdwFourCC, sizeof(DWORD) * pDirectDraw->dwNumFourCC);
        }
    }
    _SEH_HANDLE
    {
        Status = _SEH_GetExceptionCode();
    }
    _SEH_END;

    GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
    if(!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
    }
    else
    {
        Ret = TRUE;
    }
    return Ret;
}


BOOL STDCALL 
NtGdiDdDeleteDirectDrawObject( HANDLE hDirectDrawLocal)
{
    DPRINT1("NtGdiDdDeleteDirectDrawObject\n");
    if (hDirectDrawLocal == NULL)
    {
        return FALSE;
    }

    return GDIOBJ_FreeObj(DdHandleTable, hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
}


BOOL STDCALL NtGdiDdReenableDirectDrawObject(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -