Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

842 lines
23 KiB

/*========================================================================== *
*
* Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
*
* File: ddalias.c
* Content: DirectDraw support for allocating and mapping linear virtual
* memory aliased for video memory.
* History:
* Date By Reason
* ==== == ======
* 05-jul-96 colinmc initial implementation
* 10-oct-96 colinmc Refinements of the Win16 locking stuff
* 12-oct-96 colinmc Improvements to Win16 locking code to reduce virtual
* memory usage
* 25-jan-97 colinmc AGP work
* 01-jun-97 colinmc Bug xxxx: Defensive video memory checking to catch
* based video memory pointers passed by drivers
*
***************************************************************************/
#include "ddrawpr.h"
#ifdef USE_ALIAS
#ifdef WINNT
#include "ddrawgdi.h"
#endif
#pragma optimize("gle", off)
#define Not_VxD
#include <vmm.h>
#include <configmg.h>
#pragma optimize("", on)
/*
* We define the page lock IOCTLs here so that we don't have to include ddvxd.h.
* These must match the corresponding entries in ddvxd.h
*/
#define DDVXD_IOCTL_MEMRESERVEALIAS 23
#define DDVXD_IOCTL_MEMCOMMITALIAS 24
#define DDVXD_IOCTL_MEMREDIRECTALIAS 25
#define DDVXD_IOCTL_MEMDECOMMITALIAS 26
#define DDVXD_IOCTL_MEMFREEALIAS 27
#define DDVXD_IOCTL_MEMCOMMITPHYSALIAS 55
#define DDVXD_IOCTL_MEMREDIRECTPHYSALIAS 56
#define DDVXD_IOCTL_LINTOPHYS 69
#define GET_PIXELFORMAT( pdrv, psurf_lcl ) \
( ( ( psurf_lcl )->dwFlags & DDRAWISURF_HASPIXELFORMAT ) ? \
&( ( psurf_lcl )->lpGbl->ddpfSurface ) : \
&( ( pdrv )->vmiData.ddpfDisplay ) )
#define WIDTH_TO_BYTES( bpp, w ) ( ( ( ( w ) * ( bpp ) ) + 7 ) >> 3 )
BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo );
/*
* Are the heaps mapped at all?
*/
#define HEAPALIASINFO_MAPPED ( HEAPALIASINFO_MAPPEDREAL | HEAPALIASINFO_MAPPEDDUMMY )
#define MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, lpHeapAlias ) \
vxdMapVMAliasToVidMem( (hvxd), \
(lpHeapAlias)->lpAlias, \
(lpHeapAlias)->dwAliasSize, \
(LPVOID)(lpHeapAlias)->fpVidMem )
#define MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, lpHeapAlias ) \
vxdMapVMAliasToDummyMem( (hvxd), \
(lpHeapAlias)->lpAlias, \
(lpHeapAlias)->dwAliasSize )
#define UNMAP_HEAP_ALIAS( hvxd, lpHeapAlias ) \
vxdUnmapVMAlias( (hvxd), \
(lpHeapAlias)->lpAlias, \
(lpHeapAlias)->dwAliasSize )
#undef DPF_MODNAME
#define DPF_MODNAME "vxdAllocVMAlias"
/*
* vxdAllocVMAlias
*
* Allocate a virtual memory alias for a portion of video memory
* starting with the given start address and size.
*/
static BOOL vxdAllocVMAlias( HANDLE hvxd, LPVOID lpVidMem, DWORD dwSize, LPVOID *lplpAlias )
{
LPVOID lpAlias;
DWORD cbReturned;
BOOL rc;
struct RAInput
{
LPBYTE lpVidMem;
DWORD dwSize;
} raInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpVidMem );
DDASSERT( 0UL != dwSize );
DDASSERT( NULL != lplpAlias );
raInput.lpVidMem = (LPBYTE) lpVidMem;
raInput.dwSize = dwSize;
DPF( 5, "Trying to allocate alias starting at 0x%08x of size 0x%04x", lpVidMem, dwSize );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_MEMRESERVEALIAS,
&raInput,
sizeof( raInput ),
&lpAlias,
sizeof( lpAlias ),
&cbReturned,
NULL);
if( rc )
{
DDASSERT( cbReturned == sizeof(lpAlias) );
*lplpAlias = lpAlias;
}
else
{
DPF( 0, "Could not allocate an alias for video memory starting at 0x%08x", lpVidMem );
*lplpAlias = NULL;
}
return rc;
} /* vxdAllocVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdFreeVMAlias"
/*
* vxdFreeVMAlias
*
* Free the virtual memory alias with the given start address and size.
*/
static BOOL vxdFreeVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
{
BOOL rc;
BOOL fSuccess;
DWORD cbReturned;
struct FAInput
{
LPBYTE pAlias;
DWORD cbBuffer;
} faInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpAlias);
DDASSERT( 0UL != dwSize );
faInput.pAlias = (LPBYTE) lpAlias;
faInput.cbBuffer = dwSize;
DPF( 5, "Trying to free an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_MEMFREEALIAS,
&faInput,
sizeof( faInput ),
&fSuccess,
sizeof( fSuccess ),
&cbReturned,
NULL);
if( !rc || !fSuccess )
{
DPF( 0, "Could not free an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
return FALSE;
}
return TRUE;
} /* vxdFreeVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdMapVMAliasToVidMem"
/*
* vxdMapVMAliasToVidMem
*
* Map the the virtual memory alias with the given start address and size
* to the porition of video memory with the given start address.
*/
static BOOL vxdMapVMAliasToVidMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize, LPVOID lpVidMem )
{
BOOL rc;
BOOL fSuccess;
DWORD cbReturned;
struct CAInput
{
LPBYTE pAlias;
LPBYTE pVidMem;
DWORD cbBuffer;
} caInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpAlias );
DDASSERT( 0UL != dwSize );
DDASSERT( NULL != lpVidMem );
caInput.pAlias = (LPBYTE) lpAlias;
caInput.pVidMem = (LPBYTE) lpVidMem;
caInput.cbBuffer = dwSize;
DPF( 5, "Trying to map an alias starting at 0x%08x of size 0x%04x to video memory starting at 0x%08x", lpAlias, dwSize, lpVidMem );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_MEMCOMMITPHYSALIAS,
&caInput,
sizeof( caInput ),
&fSuccess,
sizeof( fSuccess ),
&cbReturned,
NULL);
if( !rc || !fSuccess )
{
DPF( 0, "Could not map an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
return FALSE;
}
return TRUE;
} /* vxdMapVMAliasToVidMem */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdMapVMAliasToDummyMem"
/*
* vxdMapVMAliasToDummyMem
*
* Map the the virtual memory alias with the given start address and size
* to a read / write dummy page.
*/
static BOOL vxdMapVMAliasToDummyMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
{
BOOL rc;
BOOL fSuccess;
DWORD cbReturned;
struct RAInput
{
LPBYTE pAlias;
DWORD cbBuffer;
} raInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpAlias);
DDASSERT( 0UL != dwSize );
raInput.pAlias = (LPBYTE) lpAlias;
raInput.cbBuffer = dwSize;
DPF( 5, "Trying to map an alias starting at 0x%08x of size 0x%04x to dummy memory" , lpAlias, dwSize );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_MEMREDIRECTPHYSALIAS,
&raInput,
sizeof( raInput ),
&fSuccess,
sizeof( fSuccess ),
&cbReturned,
NULL);
if( !rc || !fSuccess )
{
DPF( 0, "Could not map an alias starting at 0x%08x to dummy memory (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
return FALSE;
}
return TRUE;
} /* vxdMapVMAliasToDummyMem */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdUnmapVMAlias"
/*
* vxdUnmapVMAlias
*
* Unmap the the virtual memory alias with the given start address and size.
*/
static BOOL vxdUnmapVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
{
BOOL rc;
BOOL fSuccess;
DWORD cbReturned;
struct DAInput
{
LPBYTE pAlias;
DWORD cbBuffer;
} daInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpAlias);
DDASSERT( 0UL != dwSize );
daInput.pAlias = (LPBYTE) lpAlias;
daInput.cbBuffer = dwSize;
DPF( 5, "Trying to unmap an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_MEMDECOMMITALIAS,
&daInput,
sizeof( daInput ),
&fSuccess,
sizeof( fSuccess ),
&cbReturned,
NULL );
if( !rc || !fSuccess )
{
DPF( 0, "Could not unmap an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
return FALSE;
}
return TRUE;
} /* vxdUnmapVMAlias */
static BOOL vxdLinToPhys( HANDLE hvxd, LPVOID lpLin, DWORD dwSize, LPVOID* lplpPhys )
{
BOOL rc;
LPBYTE lpPhys;
DWORD cbReturned;
struct DAInput
{
LPBYTE pLin;
DWORD cbBuffer;
} daInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpLin);
// There really is a bug here: 27001. But since it's MOSTLY inoccuous, I'll turn the spew off.
// DDASSERT( 0UL != dwSize );
daInput.pLin = (LPBYTE) lpLin;
daInput.cbBuffer = dwSize;
DPF( 5, "Trying to map an linear address at 0x%08x of size 0x%04x to physical address", lpLin, dwSize );
rc = DeviceIoControl( hvxd,
DDVXD_IOCTL_LINTOPHYS,
&daInput,
sizeof( daInput ),
&lpPhys,
sizeof( lpPhys ),
&cbReturned,
NULL );
if( rc )
{
DDASSERT( cbReturned == sizeof(lpPhys) );
*lplpPhys = lpPhys;
}
else
{
DPF( 0, "Could not map linear address at 0x%08x to physical address", lpLin );
*lplpPhys = NULL;
}
return rc;
} /* vxdUnmapVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "AllocHeapAlias"
/*
* AllocHeapAlias
*
* Allocate a virtual memory alias for the given heap
*/
static BOOL AllocHeapAlias( HANDLE hvxd, FLATPTR fpStart, DWORD dwSize, LPHEAPALIAS lpHeapAlias )
{
LPVOID lpAlias;
BOOL fSuccess;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( 0UL != fpStart ); /* This is a physical address pointer */
DDASSERT( 0UL != dwSize );
DDASSERT( NULL != lpHeapAlias );
/*
* Attempt to allocate an alias for this heap.
*/
fSuccess = vxdAllocVMAlias( hvxd, (LPVOID) fpStart, dwSize, &lpAlias );
if( fSuccess )
{
lpHeapAlias->fpVidMem = fpStart;
lpHeapAlias->lpAlias = lpAlias;
lpHeapAlias->dwAliasSize = dwSize;
}
else
{
lpHeapAlias->fpVidMem = 0UL;
lpHeapAlias->lpAlias = NULL;
lpHeapAlias->dwAliasSize = 0UL;
}
return fSuccess;
} /* AllocHeapAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "FreeHeapAlias"
/*
* FreeHeapAlias
*
* Free the given virtual memory heap alias
*/
static BOOL FreeHeapAlias( HANDLE hvxd, LPHEAPALIAS lpHeapAlias )
{
BOOL fSuccess;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != lpHeapAlias );
if( NULL != lpHeapAlias->lpAlias )
{
fSuccess = vxdFreeVMAlias( hvxd, lpHeapAlias->lpAlias, lpHeapAlias->dwAliasSize );
lpHeapAlias->fpVidMem = 0UL;
lpHeapAlias->lpAlias = NULL;
lpHeapAlias->dwAliasSize = 0UL;
}
return fSuccess;
} /* FreeHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "CreateHeapAliases"
/*
* CreateHeapAliases
*
* Create a new set of virtual memory heap aliases for the given global
* object
*/
HRESULT CreateHeapAliases( HANDLE hvxd, LPDDRAWI_DIRECTDRAW_GBL pdrv )
{
LPHEAPALIASINFO phaiInfo;
DWORD dwNumHeaps;
DWORD dwSize;
DWORD dwHeapNo;
int i;
int n;
HRESULT hres;
CMCONFIG config;
LPVIDMEM pvm;
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DDASSERT( NULL != pdrv );
DDASSERT( NULL == pdrv->phaiHeapAliases );
DDASSERT( !( pdrv->dwFlags & DDRAWI_NOHARDWARE ) );
DDASSERT( !( pdrv->dwFlags & DDRAWI_MODEX ) );
DDASSERT( 0UL != pdrv->vmiData.fpPrimary );
if (DD16_GetDeviceConfig(pdrv->cDriverName, &config, sizeof(config)) == 0)
{
DPF_ERR("Could not get display devices's address space ranges");
return DDERR_GENERIC;
}
// First we count the cards local vid mem windows in the config space
dwNumHeaps = config.wNumMemWindows;
DPF(5, "Config Space windows = %d", dwNumHeaps);
// Then we cycle through the AGP heaps that we need to alias
for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ )
{
if( ( pdrv->vmiData.pvmList[i].dwFlags & VIDMEM_ISNONLOCAL ) )
{
// Found AGP heap
++dwNumHeaps;
}
}
DPF(5, "dwNumHeaps = %d", dwNumHeaps);
/*
* Allocate the heap alias info.
*/
phaiInfo = MemAlloc( sizeof( HEAPALIASINFO ) );
if( NULL == phaiInfo )
{
DPF_ERR( "Insufficient memory to map the heap alias info" );
return DDERR_OUTOFMEMORY;
}
/*
* Heaps are not yet mapped.
*/
phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
/*
* Allocate the array of heap aliases.
*/
phaiInfo->lpAliases = MemAlloc( dwNumHeaps * sizeof( HEAPALIAS ) );
if( NULL == phaiInfo->lpAliases )
{
DPF_ERR( "Insufficient memory to allocate heap alias array" );
MemFree( phaiInfo );
return DDERR_OUTOFMEMORY;
}
phaiInfo->dwNumHeaps = dwNumHeaps;
/*
* Allocate the aliases for each vid mem config space window.
*/
for( i = 0; i < (int) config.wNumMemWindows; i++ )
{
DPF(5, "Window %d: wMemAttrib = %d", i, config.wMemAttrib[i]);
DPF(5, "Window %d: dMemBase = 0x%08x", i, config.dMemBase[i]);
DPF(5, "Window %d: dMemLength = 0x%08x", i, config.dMemLength[i]);
if ((config.wMemAttrib[i] & fMD_MemoryType) == fMD_ROM)
{
DPF(5, "fMD_MemoryType == fMD_ROM, skipping...");
continue;
}
if( !AllocHeapAlias( hvxd, config.dMemBase[i], config.dMemLength[i], &phaiInfo->lpAliases[i] ) )
{
DPF_ERR( "Insufficient memory to allocate virtual memory alias" );
/*
* Discard any aliases already allocated.
*/
for( n = 0; n < i; n++)
FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] );
MemFree( phaiInfo->lpAliases );
MemFree( phaiInfo );
return DDERR_OUTOFMEMORY;
}
}
/*
* Allocate the aliases for each AGP heap.
*/
dwHeapNo = config.wNumMemWindows;
for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ )
{
pvm = &(pdrv->vmiData.pvmList[i]);
if( ( pvm->dwFlags & VIDMEM_ISNONLOCAL ) )
{
DPF(5, "AGP Heap %d: fpGARTLin = 0x%08x", i, pvm->lpHeap->fpGARTLin);
DPF(5, "AGP Heap %d: fpGARTDev = 0x%08x", i, pvm->lpHeap->fpGARTDev);
DPF(5, "AGP Heap %d: dwTotalSize = 0x%08x", i, pvm->lpHeap->dwTotalSize);
if( !AllocHeapAlias( hvxd, pvm->lpHeap->fpGARTDev, pvm->lpHeap->dwTotalSize, &phaiInfo->lpAliases[dwHeapNo] ) )
{
DPF_ERR( "Insufficient memory to allocate virtual memory alias" );
/*
* Discard any aliases already allocated.
*/
for( n = 0; n < (int)dwHeapNo; n++)
FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] );
MemFree( phaiInfo->lpAliases );
MemFree( phaiInfo );
return DDERR_OUTOFMEMORY;
}
dwHeapNo++;
}
}
/*
* Now map all the aliases to video memory.
*/
hres = MapHeapAliasesToVidMem( hvxd, phaiInfo );
if( FAILED( hres ) )
{
for( i = 0; i < (int) dwNumHeaps; i++)
FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
MemFree( phaiInfo->lpAliases );
MemFree( phaiInfo );
return hres;
}
/*
* The global object holds a single reference to the aliases
*/
phaiInfo->dwRefCnt = 1UL;
pdrv->phaiHeapAliases = phaiInfo;
return DD_OK;
} /* CreateHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "ReleaseHeapAliases"
/*
* ReleaseHeapAliases
*
* Release the given heap aliases.
*/
BOOL ReleaseHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
{
int i;
DDASSERT( NULL != phaiInfo );
DDASSERT( 0UL != phaiInfo->dwRefCnt );
phaiInfo->dwRefCnt--;
if( 0UL == phaiInfo->dwRefCnt )
{
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DPF( 4, "Heap aliases reference count is zero: discarding aliases" );
/*
* If the heaps are currently mapped then unmap them before
* freeing them.
*/
DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED );
UnmapHeapAliases( hvxd, phaiInfo );
/*
* Release all the virtual memory aliases.
*/
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
{
if( NULL != phaiInfo->lpAliases[i].lpAlias )
FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
}
MemFree( phaiInfo->lpAliases );
MemFree( phaiInfo );
}
return TRUE;
} /* ReleaseHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "MapHeapAliasesToVidMem"
/*
* MapHeapAliasesToVidMem
*
* Map all the heap aliases to video memory.
*/
HRESULT MapHeapAliasesToVidMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
{
int i;
DDASSERT( NULL != phaiInfo );
if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL )
{
DPF( 4, "Heap aliases already mapped to real video memory" );
return DD_OK;
}
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
{
/*
* NOTE: If any of the maps fail then we just discard the
* alias and continue. Memory allocated out of the failed
* heap will need the Win16 lock taken.
*/
if( NULL != phaiInfo->lpAliases[i].lpAlias )
{
if( !MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, &phaiInfo->lpAliases[i] ) )
{
DPF( 0, "Heap %d failed to map. Discarding that alias", i );
FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
}
}
}
phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDDUMMY) | HEAPALIASINFO_MAPPEDREAL);
return DD_OK;
} /* MapHeapAliasesToVidMem */
#undef DPF_MODNAME
#define DPF_MODNAME "MapHeapAliasesToDummyMem"
/*
* MapHeapAliasesToDummyMem
*
* Map all the heap aliases to the dummy read / write page.
*
* NOTE: The heap aliases must be mapped to real video memory before
* calling this function.
*/
HRESULT MapHeapAliasesToDummyMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
{
int i;
HRESULT hres;
DDASSERT( NULL != phaiInfo );
if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDDUMMY )
{
DPF( 4, "Heap aliases already mapped to dummy memory" );
return DD_OK;
}
DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL );
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
hres = DD_OK;
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
{
if( NULL != phaiInfo->lpAliases[i].lpAlias )
{
if( !MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, &phaiInfo->lpAliases[i] ) )
{
/*
* Keep going but flag the failure.
*/
DPF( 0, "Could not map the heap alias to dummy memory" );
hres = DDERR_GENERIC;
}
}
}
phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDREAL) | HEAPALIASINFO_MAPPEDDUMMY);
return hres;
} /* MapHeapAliasesToDummyMem */
#undef DPF_MODNAME
#define DPF_MODNAME "UnmapHeapAliases"
/*
* UnmapHeapAliases
*
* Unmap all the heap aliases.
*/
BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
{
int i;
DDASSERT( NULL != phaiInfo );
if( 0UL == ( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED ) )
{
DPF( 4, "Heap aliases already unmapped" );
return TRUE;
}
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
{
if( NULL != phaiInfo->lpAliases[i].lpAlias )
{
/*
* Nothing we can do if the unmap fails.
*/
UNMAP_HEAP_ALIAS( hvxd, &phaiInfo->lpAliases[i] );
}
}
phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
return TRUE;
} /* UnmapHeapAliases */
/*
* GetAliasedVidMem
*
* Get an alias for the given surface with the given video
* memory pointer.
*/
FLATPTR GetAliasedVidMem( LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl,
LPDDRAWI_DDRAWSURFACE_LCL surf_lcl,
FLATPTR fpVidMem )
{
LPDDRAWI_DDRAWSURFACE_GBL surf;
LPDDRAWI_DIRECTDRAW_GBL pdrv;
LPDDPIXELFORMAT lpddpf;
DWORD dwVidMemSize;
int n;
LPHEAPALIAS phaAlias;
DWORD dwHeapOffset;
FLATPTR fpAliasedVidMem;
FLATPTR fpPhysVidMem;
BOOL fSuccess;
DDASSERT( NULL != pdrv_lcl );
DDASSERT( NULL != surf_lcl );
DDASSERT( 0UL != fpVidMem );
surf = surf_lcl->lpGbl;
pdrv = pdrv_lcl->lpGbl;
/*
* If there are not heap aliases we can't really return one.
*/
if( NULL == pdrv->phaiHeapAliases )
{
DPF( 3, "Driver has no heap aliases. Returning a NULL alias pointer" );
return (FLATPTR)NULL;
}
/*
* Compute the (inclusive) last byte in the surface. We need this
* to ensure that a surface pointers lies exactly in an aliased
* heap.
*/
if (surf_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
dwVidMemSize = surf->dwLinearSize;
else
{
GET_PIXEL_FORMAT( surf_lcl, surf, lpddpf );
dwVidMemSize = ( ( ( surf->wHeight - 1 ) * labs( surf->lPitch ) ) +
WIDTH_TO_BYTES( lpddpf->dwRGBBitCount, surf->wWidth ) );
}
DPF(5, "dwVidMemSize = 0x%08x", dwVidMemSize);
fpAliasedVidMem = 0UL;
fSuccess = vxdLinToPhys((HANDLE) pdrv_lcl->hDDVxd, (LPVOID)fpVidMem, dwVidMemSize, (LPVOID*)&fpPhysVidMem);
if (fSuccess && (fpPhysVidMem != 0))
{
phaAlias = &pdrv->phaiHeapAliases->lpAliases[0];
n = (int) pdrv->phaiHeapAliases->dwNumHeaps;
while( n-- )
{
DPF( 5, "Checking heap %d Heap start = 0x%08x Heap size = 0x%08x VidMem = 0x%08x",
n, phaAlias->fpVidMem, phaAlias->dwAliasSize , fpPhysVidMem );
if( ( NULL != phaAlias->lpAlias ) &&
( fpPhysVidMem >= phaAlias->fpVidMem ) &&
( fpPhysVidMem + dwVidMemSize <= ( phaAlias->fpVidMem + phaAlias->dwAliasSize ) ) )
{
/*
* Compute the aliased pointer we are going to return.
*/
dwHeapOffset = (DWORD) fpPhysVidMem - phaAlias->fpVidMem;
fpAliasedVidMem = (FLATPTR) ( ( (LPBYTE) phaAlias->lpAlias ) + dwHeapOffset );
DPF( 5, "Aliased pointer: 0x%08x - Offset: 0x%08x - Aliased heap: 0x%08x - VidMem heap: 0x%08x",
fpAliasedVidMem, dwHeapOffset, phaAlias->lpAlias, phaAlias->fpVidMem );
break;
}
phaAlias++;
}
}
else
DPF(4, "Could not find contiguous physical memory for linear mem pointer.");
return fpAliasedVidMem;
}
#endif /* USE_ALIAS */