UnclePooh
UnclePooh

Reputation: 78

Shared DirectX texture2D between UWP and win32 app

I am trying to set up a shared 2D texture between an uwp application and a win32 application. The minimal reproducible example uses the CoreApp project template (C++/WinRT), in which all functions from the App class (except the Run method) are empty (the Run method remains unchanged). Inside wWinMain, creation of shared texture and starting app occurs.

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
// Create D3D11 Device and Context
ID3D11Device1* d3d11Device;
ID3D11DeviceContext1* d3d11DeviceContext;
{
    ID3D11Device* baseDevice;
    ID3D11DeviceContext* baseDeviceContext;
    D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 };
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

    D3D11CreateDevice(
        0,
        D3D_DRIVER_TYPE_HARDWARE,
        0,
        creationFlags,
        featureLevels,
        ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION,
        &baseDevice,
        0,
        &baseDeviceContext);

    baseDevice->QueryInterface(__uuidof(ID3D11Device1), (void**)&d3d11Device);
    baseDevice->Release();

    baseDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void**)&d3d11DeviceContext);
    baseDeviceContext->Release();
}

HRESULT result;
D3D11_TEXTURE2D_DESC texDesc;
texDesc.Width = 360;
texDesc.Height = 360;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_RENDER_TARGET;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

result = d3d11Device->CreateTexture2D(&texDesc, nullptr, &texture2D);

IDXGIResource1* pResource;
texture2D->QueryInterface(__uuidof(IDXGIResource1), (void**)&pResource);
result = pResource->CreateSharedHandle(
             nullptr,
             DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
             L"SharedTexture2D",
             &textureHandle);

CoreApplication::Run(make<App>());
}

Win32 app is based on empty project with added main.cpp file.

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX

#include <string>
#include <Userenv.h>
#include <windows.h>
#include <d3d11_1.h>
#include <windows.h>
#include <d3d11_1.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "Userenv.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/)
{
// Create D3D11 Device and Context as for uwp

// Try to open shared resource by name

// from Package.appmanifest of uwp project
constexpr auto packageFamilyName= L"b0660272-d6e8-493b-8da6-7e324d3652f3_6jxptbrcxhds4";

PSID psid{};
DeriveAppContainerSidFromAppContainerName(packageFamilyName, &psid);

auto path = std::wstring();
path.resize(256u);

ULONG returnedPathSize = 0u;

auto status = GetAppContainerNamedObjectPath(
    nullptr,
    psid,
    path.size(),
    (LPWSTR)(path.data()),
    &returnedPathSize);

path.insert(returnedPathSize - 1u, L"\\SharedTexture2D");

ID3D11Texture2D* texture;
auto result = d3d11Device->OpenSharedResourceByName(
    path.c_str(),
    DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
    __uuidof(ID3D11Texture2D),
    (void**)&texture);

return result;
}

UWP creates the shared handle and returns S_OK. Then, I try to open the resource from the win32 app and there is E_INVALIDARG One or more arguments are invalid error code.

When, I have two win32 apps, the solution above works. What is the problem and how can I deal with it?

I guess it is related to the UWP sandbox and maybe there is a need to set some security attributes or modify the name of the shared resource, but I cannot find any information.

Thanks in advance!

Update:

  1. As suggested by user Chuck Walbourn, I modified the code by adding DeriveAppContainerSidFromAppContainerName.

  2. A more precise description to easier reproduce of problem.

  3. As suggested by user @Simon Mourier - I have changed the package family to the package family name as argument of DeriveAppContainerSidFromAppContainerName and it works now :)

Upvotes: 0

Views: 227

Answers (2)

YangXiaoPo-MSFT
YangXiaoPo-MSFT

Reputation: 2130

As @ChuckWalbourn and @SimonMourier said, Use GetAppContainerNamedObjectPath and DeriveAppContainerSidFromAppContainerName with insuring the pszAppContainerName is right.

We can also learn from the document Sharing named objects @ChuckWalbourn attached,

GetAppContainerNamedObjectPath will return the named object path for a packaged application based on its SID. You can generate the SID for a packaged application by passing its package family name to DeriveAppContainerSidFromAppContainerName.

  • Note
    The package family name can be found via the package manifest editor in Visual Studio during development time, via Partner Center for applications published through the Microsoft Store, or via the Get-AppxPackage PowerShell command for applications that are already
    installed.

When opening named objects created by a packaged application, use the format <PATH>\<NAME>:

Replace <PATH> with the creating application's named object path.
Replace <NAME> with the object name.

  • Note
    Prefixing object names with is only required if a packaged application created the object. Named objects created by Win32 applications do not need to be qualified, though access must still be granted when the objects are created.

Upvotes: 1

Chuck Walbourn
Chuck Walbourn

Reputation: 41127

The issue is that SharedTexture2D is not a fully qualified object name, so it doesn't exist when you use it from the Win32 application.

I believe you need to use GetAppContainerNamedObjectPath from the Win32 app.

There are some specific instructions on how to get a shared handle to have the right permissions to be visible to a particular UWP SI. See Microsoft Learn. You may be able to get it to work by providing a non-null SECURITY_ATTRIBUTES, but this is mostly an issue for UWPs trying to open handles created by Win32 apps which is the opposite of your scenario.

Upvotes: 3

Related Questions