Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a hosted CLR AppDomain with full trust permissions including network rights

I need to host the .NET runtime in an unmanaged process. I have code that works to load the runtime via COM and I can load assemblies into the AppDomain and execute code just fine.

However, I run into problems with applications that are hosted on a network share and have to change the application policy in order to get them to execute which is not an option. So what I'd like to do is set the permission level for the runtime's main AppDomain to unrestricted.

Can somebody provide an example on how to set the AppDomain policy level? I can't quite figure out how to instantiate the required classes from un-managed code to create the PolicyLevel and related objects and set the policy. Basically I don't know what includes/namespace references I need to get this to work from the C++ code I use.

Here's the code I have at this point:

/// Starts up the CLR and creates a Default AppDomain
DWORD WINAPI ClrLoad(char *ErrorMessage, DWORD *dwErrorSize)
{
    if (spDefAppDomain)
        return 1;


    //Retrieve a pointer to the ICorRuntimeHost interface
    HRESULT hr = CorBindToRuntimeEx(
                    ClrVersion, //Retrieve latest version by default
                    L"wks", //Request a WorkStation build of the CLR
                    STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | STARTUP_CONCURRENT_GC, 
                    CLSID_CorRuntimeHost,
                    IID_ICorRuntimeHost,
                    (void**)&spRuntimeHost
                    );

    if (FAILED(hr)) 
    {
        *dwErrorSize = SetError(hr,ErrorMessage);   
        return hr;
    }

    //Start the CLR
    hr = spRuntimeHost->Start();

    if (FAILED(hr))
        return hr;

    CComPtr<IUnknown> pUnk;

    //Retrieve the IUnknown default AppDomain
    //hr = spRuntimeHost->GetDefaultDomain(&pUnk);
    //if (FAILED(hr)) 
    //  return hr;


    WCHAR domainId[50];
    swprintf(domainId,L"%s_%i",L"wwDotNetBridge",GetTickCount());
    hr = spRuntimeHost->CreateDomain(domainId,NULL,&pUnk);  

    hr = pUnk->QueryInterface(&spDefAppDomain.p);
    if (FAILED(hr)) 
        return hr;

      // // Create a new AppDomain PolicyLevel.
   //PolicyLevel polLevel = PolicyLevel:: CreateAppDomainLevel();

   //// Create a new, empty permission set.
   // PermissionSet permSet = gcnew PermissionSet( PermissionState::Unrestricted);

   //// Add permission to execute code to the permission set.
   //permSet->AddPermission( gcnew SecurityPermission( SecurityPermissionFlag::Execution ) );

   ////// Give the policy level's root code group a new policy statement based
   ////// on the new permission set.
   ////polLevel->RootCodeGroup->PolicyStatement = gcnew PolicyStatement( permSet );

   //// Give the new policy level to the application domain.
   //spDefAppdomain->SetAppDomainPolicy( polLevel );



    return 1;
}

I picked up some sample code (commented) that appears to do what I need it to, but I can't figure out what lib/include references I need to make the type references for PermissionSet and PolicyLevel work.

Any ideas much appreciated...

like image 202
Rick Strahl Avatar asked Feb 02 '11 16:02

Rick Strahl


1 Answers

I think you need to use the "non-trivial" method of creating an AppDomain in order to get to any of that goodness:

  • CreateDomainSetup(IUnknown** pAppDomainSetup), that'll get you back an IAppDomainSetup instance.
  • Fill that in appropriately (I think all the policy stuff is available in there)
  • Use CreateDomainEx, passing in your initialized setup instance as the second parameter
  • Profit?

References:

  • ICorRuntimeHost::CreateDomainSetup
  • AppDomainSetup definition
  • ICorRuntimeHost::CreateDomainEx
like image 102
JerKimball Avatar answered Nov 16 '22 21:11

JerKimball