示例#1
0
/*
 * DD_SurfaceComposition_GetCompositionOrder
 */
HRESULT DDAPI DD_SurfaceComposition_GetCompositionOrder(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface,
    LPDWORD lpdwCompositionOrder )
{
    LPDDRAWI_DDRAWSURFACE_LCL		thisx;
    LPDDRAWI_DDRAWSURFACE_GBL		this;

    thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface;
    if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    if( !VALID_DWORD_PTR( lpdwCompositionOrder ) )
    {
        return DDERR_INVALIDPARAMS;
    }
    this = thisx->lpGbl;
    ENTER_DDRAW();
    if( SURFACE_LOST( thisx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }

//    *lpdwCompositionOrder = this->dwCompositionOrder;

    LEAVE_DDRAW();
    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_GetCompositionOrder */
示例#2
0
/*
 * DD_SurfaceComposition_EnumSurfaceDependencies
 */
HRESULT DDAPI DD_SurfaceComposition_EnumSurfaceDependencies(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface,
    LPVOID lpContext,
    LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback )
{
    LPDDRAWI_DDRAWSURFACE_LCL	thisx;
    LPDDRAWI_DDRAWSURFACE_GBL	this;

    thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface;
    if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    if( !VALID_CODE_PTR( lpEnumSurfacesCallback ) )
    {
        return DDERR_INVALIDPARAMS;
    }
    this = thisx->lpGbl;
    ENTER_DDRAW();
    if( SURFACE_LOST( thisx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }
    LEAVE_DDRAW();
    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_EnumSurfaceDependencies */
示例#3
0
/*
 * DD_SurfaceComposition_DeleteSurfaceDependency
 */
HRESULT DDAPI DD_SurfaceComposition_DeleteSurfaceDependency(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface,
    DWORD dwFlagsForNoGoodFuckingReason,
    LPDIRECTDRAWSURFACE lpDDSurface2 )
{
    LPDDRAWI_DDRAWSURFACE_LCL	thisx;
    LPDDRAWI_DDRAWSURFACE_GBL	this;
    LPDDRAWI_DDRAWSURFACE_LCL	this2x;
    LPDDRAWI_DDRAWSURFACE_GBL	this2;

    thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface;
    if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) )
    {
        return DDERR_INVALIDOBJECT;
    }

    this2x = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface2;
    if( !VALID_DIRECTDRAWSURFACE_PTR( this2x ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    this = thisx->lpGbl;
    this2 = this2x->lpGbl;
    ENTER_DDRAW();
    if( SURFACE_LOST( thisx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }
    if( SURFACE_LOST( this2x ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }

    LEAVE_DDRAW();
    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_DeleteSurfaceDependency */
示例#4
0
/*
 * DD_SurfaceComposition_AddSurfaceDependency
 */
HRESULT DDAPI DD_SurfaceComposition_AddSurfaceDependency(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface,
    LPDIRECTDRAWSURFACE lpDDSurfaceDep )
{
    LPDDRAWI_DDRAWSURFACE_LCL	thisx;
    LPDDRAWI_DDRAWSURFACE_LCL	this_depx;
    LPDDRAWI_DDRAWSURFACE_GBL	this;
    LPDDRAWI_DDRAWSURFACE_GBL	this_dep;

    thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface;
    this_depx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurfaceDep;
    if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    if( !VALID_DIRECTDRAWSURFACE_PTR( this_depx ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    this = thisx->lpGbl;
    this_dep = this_depx->lpGbl;
    ENTER_DDRAW();

    if( SURFACE_LOST( thisx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }
    if( SURFACE_LOST( this_depx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }
    LEAVE_DDRAW();
    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_AddSurfaceDependency */
示例#5
0
/*
 * DD_SurfaceComposition_Compose
 */
HRESULT DDAPI DD_SurfaceComposition_Compose(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDDestSurface,
    LPRECT lpDestRect,
    LPDIRECTDRAWSURFACE lpDDSrcSurface,
    LPRECT lpSrcRect,
    DWORD dwFlags,
    LPDDCOMPOSEFX lpDDComposeFX )
{
    LPDDRAWI_DIRECTDRAW		pdrv;
    LPDDRAWI_DDRAWSURFACE_LCL	this_srcx;
    LPDDRAWI_DDRAWSURFACE_LCL	this_destx;
    LPDDRAWI_DDRAWSURFACE_GBL	this_src;
    LPDDRAWI_DDRAWSURFACE_GBL	this_dest;

    this_destx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDDestSurface;
    this_srcx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSrcSurface;
    if( !VALID_DIRECTDRAWSURFACE_PTR( this_destx ) )
    {
        DPF_ERR( "invalid dest specified") ;
        return DDERR_INVALIDOBJECT;
    }
    this_dest = this_destx->lpGbl;
    pdrv = this_dest->lpDD;
    ENTER_DDRAW();
    if( this_srcx != NULL )
    {
        if( !VALID_DIRECTDRAWSURFACE_PTR( this_srcx ) )
        {
            DPF_ERR( "Invalid source specified" );
            LEAVE_DDRAW();
            return DDERR_INVALIDOBJECT;
        }
        this_src = this_srcx->lpGbl;
        if( SURFACE_LOST( this_srcx ) )
        {
            LEAVE_DDRAW();
            return DDERR_SURFACELOST;
        }
    }
    else
    {
        this_src = NULL;
    }

    LEAVE_DDRAW();

    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_Compose */
示例#6
0
/*
 * DD_SurfaceComposition_DestUnlock
 */
HRESULT DDAPI DD_SurfaceComposition_DestUnlock(
    LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface )
{
    LPDDRAWI_DDRAWSURFACE_LCL	thisx;
    LPDDRAWI_DDRAWSURFACE_GBL	this;

    thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface;
    if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) )
    {
        return DDERR_INVALIDOBJECT;
    }
    this = thisx->lpGbl;
    ENTER_DDRAW();
    if( SURFACE_LOST( thisx ) )
    {
        LEAVE_DDRAW();
        return DDERR_SURFACELOST;
    }
    LEAVE_DDRAW();
    return DDERR_UNSUPPORTED;

} /* DD_SurfaceComposition_DestUnlock */
示例#7
0
/*
 * InternalSurfaceRelease
 *
 * Done with a surface.	  if no one else is using it, then we can free it.
 * Also called by ProcessSurfaceCleanup, EnumSurfaces and DD_Release.
 *
 * Assumes the lock is taken on the driver.
 */
DWORD InternalSurfaceRelease( LPDDRAWI_DDRAWSURFACE_INT this_int )
{
    LPDDRAWI_DDRAWSURFACE_LCL	this_lcl;
    LPDDRAWI_DDRAWSURFACE_GBL	this;
    LPATTACHLIST		pattachlist;
    DWORD			intrefcnt;
    DWORD			lclrefcnt;
    DWORD			gblrefcnt;
    DWORD			pid;
    LPDDRAWI_DIRECTDRAW_LCL	pdrv_lcl;
    LPDDRAWI_DIRECTDRAW_GBL 	pdrv;
    BOOL			root_object_deleted;
    BOOL			do_free;
    DWORD                       caps;

    this_lcl = this_int->lpLcl;
    this = this_lcl->lpGbl;

    /*
     * check owner of surface
     */
    pid = GETCURRPID();
    /*
     * don't allow someone to free an implicitly created surface
     */
    if( (this->dwRefCnt == 1) && (this_lcl->dwFlags & DDRAWISURF_IMPLICITCREATE) )
    {
	DPF_ERR( "Cannot free an implicitly created surface" );
	return 0;
    }

    /*
     * remove locks taken on this surface by the current process
     */
    pdrv_lcl = this_lcl->lpSurfMore->lpDD_lcl;
    pdrv = pdrv_lcl->lpGbl;
    if( (this_lcl->dwLocalRefCnt & ~OBJECT_ISROOT) == 1 )
    {
	RemoveProcessLocks( pdrv_lcl, this, pid );
    }

    /*
     * decrement the reference count.  if it hits zero, free the surface
     */
    this->dwRefCnt--;
    gblrefcnt = this->dwRefCnt;
    this_lcl->dwLocalRefCnt--;
    lclrefcnt = this_lcl->dwLocalRefCnt & ~OBJECT_ISROOT;
    this_int->dwIntRefCnt--;
    intrefcnt = this_int->dwIntRefCnt;

    DPF( 4, "DD_Surface_Release, Reference Count: Global = %ld Local = %ld Int = %ld",
         gblrefcnt, lclrefcnt, intrefcnt );

    /*
     * local object at zero?
     */
    root_object_deleted = FALSE;
    if( lclrefcnt == 0 )
    {
	LPDDRAWI_DDRAWSURFACE_INT	curr_int;
	LPDDRAWI_DDRAWSURFACE_LCL	curr_lcl;
	LPDDRAWI_DDRAWSURFACE_GBL	curr;
	DWORD				refcnt;

	/*
	 * see if we are deleting the root object
	 */
	if( this_lcl->dwLocalRefCnt & OBJECT_ISROOT )
	{
	    root_object_deleted = TRUE;
	}


	/*
	 * reset if primary surface is the one being released
	 */
	if( this_lcl->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE )
	{

	    /*
	     * restore GDI stuff if this is the GDI driver
	     */
	    if( pdrv->dwFlags & DDRAWI_DISPLAYDRV )
	    {
		if( !SURFACE_LOST( this_lcl ) )
		{
		    DPF( 2, "Resetting primary surface");
	
		    /*
		     * flip to the original primary surface if not emulated
		     */
		    if( !(this_lcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
			!(this->dwGlobalFlags & DDRAWISURFGBL_ISGDISURFACE)) //pdrv->fpPrimaryOrig != this->fpVidMem) )
		    {
			FlipToGDISurface( pdrv_lcl, this_int ); //, pdrv->fpPrimaryOrig );
		    }
		}
    
		/*
		 * Cause the GDI surface to be redrawn if the mode was ever changed.
		 */
                if (pdrv_lcl->dwLocalFlags & DDRAWILCL_MODEHASBEENCHANGED)
         		RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
				 RDW_ALLCHILDREN );
	    }
	}

	/*
	 * if an overlay, remove surface from the overlay Z order list
	 */
	if( this_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY )
	{
	    // Remove surface from doubly linked list
	    this_lcl->dbnOverlayNode.prev->next = this_lcl->dbnOverlayNode.next;
	    this_lcl->dbnOverlayNode.next->prev = this_lcl->dbnOverlayNode.prev;

            // If this surface is overlaying an emulated surface, we must notify
            // the HEL that it needs to eventually update the part of the surface
            // touched by this overlay.
            if( this_lcl->lpSurfaceOverlaying != NULL )
            {
        	// We have a pointer to the surface being overlayed, check to 
        	// see if it is being emulated.
        	if( this_lcl->lpSurfaceOverlaying->lpLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY )
        	{
        	    // Mark the destination region of this overlay as dirty.
        	    DD_Surface_AddOverlayDirtyRect(
        		(LPDIRECTDRAWSURFACE)(this_lcl->lpSurfaceOverlaying),
			&(this_lcl->rcOverlayDest) );
        	}
		DD_Surface_Release( 
		    (LPDIRECTDRAWSURFACE)(this_lcl->lpSurfaceOverlaying) );
            }
	}

	/*
	 * hide a hardware overlay...
	 */
	if( (this_lcl->ddsCaps.dwCaps & DDSCAPS_OVERLAY) &&
	    (this_lcl->ddsCaps.dwCaps & DDSCAPS_VISIBLE) &&
	    (this_lcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) )
	{
	    LPDDHALSURFCB_UPDATEOVERLAY	uohalfn;
	    LPDDHALSURFCB_UPDATEOVERLAY	uofn;
	    DWORD			rc;
	    DDHAL_UPDATEOVERLAYDATA	uod;

	    uofn = pdrv_lcl->lpDDCB->HALDDSurface.UpdateOverlay;
	    uohalfn = pdrv_lcl->lpDDCB->cbDDSurfaceCallbacks.UpdateOverlay;
	    if( (uohalfn != NULL) && (NULL != this_lcl->lpSurfaceOverlaying) )
	    {
		DPF( 2, "Turning off hardware overlay" );
		uod.UpdateOverlay = uohalfn;
		uod.lpDD = pdrv;
		uod.lpDDSrcSurface = this_lcl;
		uod.lpDDDestSurface = this_lcl->lpSurfaceOverlaying->lpLcl;
		uod.dwFlags = DDOVER_HIDE;
		DOHALCALL( UpdateOverlay, uofn, uod, rc, FALSE );
	    }
	}

	/*
	 * release all implicitly created attached surfaces
	 */
	pattachlist = GetAttachList( this_lcl );
	this_lcl->dwFlags |= DDRAWISURF_ISFREE;
	while( pattachlist != NULL )
	{
	    BOOL    was_implicit;
	    /*
	     * break all attachments
	     */
	    curr_int = pattachlist->lpIAttached;
	    if( pattachlist->dwFlags & DDAL_IMPLICIT )
		was_implicit = TRUE;
	    else
		was_implicit = FALSE;

	    DPF(3, "Deleting attachment from %08lx to %08lx (implicit = %d)", 
		curr_int, this_int, was_implicit);
       	    DeleteOneAttachment( this_int, curr_int, TRUE, DOA_DELETEIMPLICIT );
	    // If the attachment was not implicit then curr_int may possibly have 
	    // been destroyed as a result of DeleteOneAttachment.
	    if( was_implicit )
	    {
		curr_lcl = curr_int->lpLcl;
		curr = curr_lcl->lpGbl;

		/*
		 * release an implicitly created surface
		 */
		if( !(curr_lcl->dwFlags & DDRAWISURF_ISFREE) )
		{
		    if( curr_lcl->dwFlags & DDRAWISURF_IMPLICITCREATE )
		    {
			refcnt = curr_int->dwIntRefCnt;
			curr_lcl->dwFlags &= ~DDRAWISURF_IMPLICITCREATE;
			while( refcnt > 0 )
			{
			    InternalSurfaceRelease( curr_int );
			    refcnt--;
			}
		    }
		}
	    }
	    /*
	     * start again at the beginning of the list because
	     * DeleteOneAttachment may have modified the attachment list.
	     * HACKHACK:  this fn call is needed to get around a compiler bug
	     */
	    pattachlist = GetAttachList( this_lcl );
	}

        /*
         * Free the nodes in the IUnknown list and release all the interfaces.
         */
	FreeIUnknowns( this_lcl, TRUE );

        /*
	 * If a palette is attached to this surface remove it (and, as a
	 * side effect, release it).
	 */
	if( this_lcl->lpDDPalette )
	    DD_Surface_SetPalette( (LPDIRECTDRAWSURFACE) this_int, NULL );

        /*
         * Release the attached clipper (if any).
         */
        if( this_lcl->lpSurfMore->lpDDIClipper )
            DD_Clipper_Release( (LPDIRECTDRAWCLIPPER)this_lcl->lpSurfMore->lpDDIClipper );

	/*
	 * remove all attachments to us from other surfaces
	 */
	pattachlist = this_lcl->lpAttachListFrom;
	while( pattachlist != NULL )
	{
	    curr_int = pattachlist->lpIAttached;
	    DPF( 3, "Deleting attachment from %08lx", curr_int );
	    DeleteOneAttachment( curr_int, this_int, TRUE, DOA_DELETEIMPLICIT );
	    /*
	     * start again at the beginning of the list because
	     * DeleteOneAttachment may have modified the attachment list.
	     * HACKHACK:  this fn call is needed to get around a compiler bug
	     */
	    pattachlist = GetAttachListFrom( this_lcl );
	}
	this_lcl->dwFlags &= ~DDRAWISURF_ISFREE;
    }

    /*
     * root object at zero?
     */
    do_free = FALSE;
    if( gblrefcnt == 0 )
    {
	/*
	 * get rid of all memory associated with this surface
	 */
	DestroySurface( this_lcl );

	this_lcl->dwFlags |= DDRAWISURF_INVALID;
	do_free = TRUE;

	/*
	 * if this was the final delete, but this wasn't the root object,
	 * then we need to delete the dangling object
	 */
	if( !root_object_deleted )
	{
	    LPDDRAWI_DDRAWSURFACE_LCL	root_lcl;

	    /*
	     * Get the start of the root global data object.  Since the
	     * global data always follows the local data, we just need
	     * to back up the size of the local data to get the start of
	     * the allocated block.
	     *
	     * NOTE: The local surface allocation now includes the
	     * additional local surface structure (DDRAWI_DDRAWSURFACE_MORE).
	     * So we need to back up by the size of that structure also.
	     *
	     * Since all duplicated surfaces have the same local data,
	     * we just need to test this surface for overlay data to determine
	     * if the root object had overlay data.
	     */
	    if( this_lcl->dwFlags & DDRAWISURF_HASOVERLAYDATA )
	    {
		root_lcl = (LPVOID) (((LPSTR) this) - ( sizeof( DDRAWI_DDRAWSURFACE_LCL ) +
		                                        sizeof( DDRAWI_DDRAWSURFACE_MORE ) ) );
	    }
	    else
	    {
		root_lcl = (LPVOID) (((LPSTR) this) - ( offsetof( DDRAWI_DDRAWSURFACE_LCL, ddckCKSrcOverlay ) +
							sizeof( DDRAWI_DDRAWSURFACE_MORE ) ) );
	    }
	    MemFree( root_lcl );
	}
    }
    else if( lclrefcnt == 0 )
    {
	/*
	 * only remove the object if it wasn't the root.   if it
	 * was the root, we must leave it dangling until the last
	 * object referencing it goes away.
	 */
	if( !root_object_deleted )
	{
	    do_free = TRUE;
	}
    }

    caps = this_lcl->ddsCaps.dwCaps;
    /*
     * If we are releasing an interface to a primary surface, update the pointer to the primary 
     * surface stored in the local driver object.  If another interface to the primary surface exists, 
     * store that one.  Otherwise, set the pointer to NULL.
     */
    if( intrefcnt == 0 )
    {
	if( caps & DDSCAPS_PRIMARYSURFACE )
	{
	    if( this_lcl->lpSurfMore->lpDD_lcl )
	    {
		this_lcl->lpSurfMore->lpDD_lcl->lpPrimary = findOtherInterface(this_int, this_lcl, pdrv);
	    }
	}
#ifdef SHAREDZ
	if( caps & DDSCAPS_SHAREDBACKBUFFER )
	{
	    if( this_lcl->lpSurfMore->lpDD_lcl )
	    {
		this_lcl->lpSurfMore->lpDD_lcl->lpSharedBack = findOtherInterface(this_int, this_lcl, pdrv);
	    }
	}
	if( caps & DDSCAPS_SHAREDZBUFFER )
	{
	    if( this_lcl->lpSurfMore->lpDD_lcl )
	    {
		this_lcl->lpSurfMore->lpDD_lcl->lpSharedZ = findOtherInterface(this_int, this_lcl, pdrv);
	    }
	}
#endif
    }

    /*
     * free the object if needed
     */
    if( do_free )
    {
	this_lcl->lpGbl = NULL;

        #ifdef WINNT
        /*
         * Free the associated NT kernel-mode object only if it is a vram surface, it is not
	 * an execute buffer, and it has not yet been freed in the kernel
         */
        if (!(caps & (DDSCAPS_EXECUTEBUFFER|DDSCAPS_SYSTEMMEMORY) ) && this_lcl->hDDSurface )
        {
            DPF(9,"Deleting NT kernel-mode object handle %08x",this_lcl->hDDSurface);
            if (!DdDeleteSurfaceObject(this_lcl))
                DPF(9,"DdDeleteSurfaceObject failed");
        }
        #endif
	MemFree( this_lcl );
    }

    /*
     * interface at zero?
     */
    if( intrefcnt == 0)
    {
	LPDDRAWI_DDRAWSURFACE_INT	curr_int;
	LPDDRAWI_DDRAWSURFACE_INT	last_int;
	/*
	 * remove surface from list of all surfaces
	 */
	curr_int = pdrv->dsList;
	last_int = NULL;
	while( curr_int != this_int )
	{
	    last_int = curr_int;
	    curr_int = curr_int->lpLink;
	    if( curr_int == NULL )
	    {
		DPF_ERR( "Surface not in list!" );
		return 0;
	    }
	}
	if( last_int == NULL )
	{
	    pdrv->dsList = pdrv->dsList->lpLink;
	}
	else
	{
	    last_int->lpLink = curr_int->lpLink;
	}

	/*
	 * just in case someone comes back in with this pointer, set
	 * an invalid vtbl & data ptr.
	 */
	this_int->lpVtbl = NULL;
	this_int->lpLcl = NULL;
	MemFree( this_int );
    }
    return intrefcnt;

} /* InternalSurfaceRelease */
示例#8
0
/*
 * DD_Surface_AddRef
 */
ULONG DDAPI DD_Surface_AddRef( LPDIRECTDRAWSURFACE lpDDSurface )
{
    LPDDRAWI_DIRECTDRAW_GBL	pdrv;
    LPDDRAWI_DDRAWSURFACE_INT	this_int;
    LPDDRAWI_DDRAWSURFACE_LCL	this_lcl;
    LPDDRAWI_DDRAWSURFACE_GBL	this;
    DWORD			rcnt;

    ENTER_DDRAW();

    TRY
    {
	/*
	 * validate parms
	 */
	this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
	if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) )
	{
	    DPF_ERR( "Invalid surface pointer" );
	    LEAVE_DDRAW();
	    return 0;
	}
	this_lcl = this_int->lpLcl;
	this = this_lcl->lpGbl;
	pdrv = this->lpDD;
    
   	// need to allow lost surfaces
   	#if 0
	    if( SURFACE_LOST( this_lcl ) )
	    {
		LEAVE_DDRAW();
		return 0;
	    }
	#endif

    }
    EXCEPT( EXCEPTION_EXECUTE_HANDLER )
    {
	DPF_ERR( "Exception encountered validating parameters" );
	LEAVE_DDRAW();
	return 0;
    }
    /*
     * If this surface is already being freed, immediately return to
     * prevent recursion.
     */

    if( this_lcl->dwFlags & DDRAWISURF_ISFREE )
    {
	DPF(3, "Leaving AddRef early to prevent recursion" );
	LEAVE_DDRAW();
	return 0;
    }


    /*
     * update surface reference count
     */
    this->dwRefCnt++;
    this_lcl->dwLocalRefCnt++;
    this_int->dwIntRefCnt++;
    rcnt = this_lcl->dwLocalRefCnt & ~OBJECT_ISROOT;

    DPF( 4, "DD_Surface_AddRef, Reference Count: Global = %ld Local = %ld Int = %ld",
         this->dwRefCnt, rcnt, this_int->dwIntRefCnt );

    LEAVE_DDRAW();
    return this_int->dwIntRefCnt;

} /* DD_Surface_AddRef */