HRESULT CSurfaceQueueDeviceD3D10::CreateSharedSurface(
                                UINT Width, UINT Height, 
                                DXGI_FORMAT format, 
                                IUnknown** ppUnknown,
                                HANDLE* pHandle)
{
    ASSERT(m_pDevice);
    ASSERT(ppUnknown);
    ASSERT(pHandle);

	if (NULL == m_pDevice || NULL == ppUnknown || NULL == pHandle)
	{
		return E_FAIL;
	}

    HRESULT hr;

    ID3D10Texture2D** ppTexture = (ID3D10Texture2D**)ppUnknown;

    D3D10_TEXTURE2D_DESC Desc;
    Desc.Width              = Width;
    Desc.Height             = Height;
    Desc.MipLevels          = 1;
    Desc.ArraySize          = 1;
    Desc.Format             = format;
    Desc.SampleDesc.Count   = 1;
    Desc.SampleDesc.Quality = 0;
    Desc.Usage              = D3D10_USAGE_DEFAULT;
    Desc.BindFlags          = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
    Desc.CPUAccessFlags     = 0;
    Desc.MiscFlags          = D3D10_RESOURCE_MISC_SHARED;

    hr = m_pDevice->CreateTexture2D(&Desc, NULL, ppTexture);

    if (SUCCEEDED(hr))
    {
        if (FAILED( GetSharedHandle(*ppUnknown, pHandle)))
        {
            (*ppTexture)->Release();
            (*ppTexture) = NULL;
        }
    }

    return hr;
}
void D3DImageEx::SetBackBufferEx(D3DResourceTypeEx resourceType, IntPtr pResource)
{
    /* Check if the user just wants to clear the D3DImage backbuffer */
    if(pResource == IntPtr::Zero)
    {
        SetBackBuffer(D3DResourceType::IDirect3DSurface9, IntPtr::Zero);
        return;
    }

    IUnknown *pUnk = (IUnknown*)pResource.ToPointer();
    IUnknown *pUnkResource = NULL;

    UINT width = 0;
    UINT height = 0;
    DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;

    /* D3D version specific stuffs */
    switch(resourceType)
    {
    case D3DResourceTypeEx::ID3D10Texture2D:
    {
        ::ID3D10Texture2D *pTexture2D = NULL;
        /* Query for IUNKNOWN for ID3D10Texture2D */
        if(FAILED(pUnk->QueryInterface(__uuidof(::ID3D10Texture2D), (void**)&pTexture2D)))
            throw gcnew ArgumentException("Must pass a valid resource","pResource");

        /* Get the texture description.  This is needed to recreate
         * the surface in the 9Ex device */
        D3D10_TEXTURE2D_DESC textureDesc;
        pTexture2D->GetDesc(&textureDesc);

        width = textureDesc.Width;
        height = textureDesc.Height;
        format = textureDesc.Format;

        pUnkResource = pTexture2D;
        pTexture2D->Release();
    }
    break;
    case D3DResourceTypeEx::ID3D11Texture2D:
    {
        ::ID3D11Texture2D *pTexture2D = NULL;

        /* Query for IUNKNOWN for ID3D11Texture2D */
        if(FAILED(pUnk->QueryInterface(__uuidof(::ID3D11Texture2D), (void**)&pTexture2D)))
            throw gcnew ArgumentException("Must pass a valid resource","pResource");

        /* Get the texture description.  This is needed to recreate
         * the surface in the 9Ex device */
        D3D11_TEXTURE2D_DESC textureDesc;
        pTexture2D->GetDesc(&textureDesc);

        width = textureDesc.Width;
        height = textureDesc.Height;
        format = textureDesc.Format;

        pUnkResource = pTexture2D;
        pTexture2D->Release();
    }
    break;
    default:
        throw gcnew ArgumentOutOfRangeException("resourceType");
        break;
    }

    /* The shared handle of the D3D resource */
    HANDLE hSharedHandle = NULL;

    /* Shared texture pulled through the 9Ex device */
    IDirect3DTexture9* pTexture = NULL;

    /* Shared surface, pulled through the shared texture */
    IDirect3DSurface9* pSurface;

    /* Get the shared handle for the given resource */
    if(FAILED(GetSharedHandle(pUnkResource, &hSharedHandle)))
        throw gcnew Exception("Could not aquire shared resource handle");

    /* Get the shared surface.  In this case its really a texture =X */
    if(FAILED(GetSharedSurface(hSharedHandle, (void**)&pTexture, width, height, format)))
        throw gcnew Exception("Could not create shared resource");

    /* Get surface level 0, which we need for the D3DImage */
    if (FAILED(pTexture->GetSurfaceLevel(0, &pSurface)))
        throw gcnew Exception("Could not get surface level");

    /* Done with the texture */
    pTexture->Release();

    Lock();
    /* Set the backbuffer of the D3DImage */
    SetBackBuffer(D3DResourceType::IDirect3DSurface9, IntPtr(pSurface));
    Unlock();

    pSurface->Release();
}