📄 ddraw.c
字号:
/*
* 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 + -