public void Marshaler_creates_factory_and_session()
 {
     //configure NHibernate
     var config = new Configuration();
     //initialize context
     var session = new Marshaler(config).CurrentSession;
     Assert.IsNotNull(session);
     session.Dispose();
 }
 public When_using_session_auditor()
 {
     //configure NHibernate
     var config = new Configuration();
     config.AddClass(typeof(Cat));
     //create the database
     var tool = new SchemaExport(config);
     tool.Execute(false, true, false);
     //initialize context
     _currentScope = new Marshaler(config, typeof(ValidationInterceptor));
 }
 public void Marshaler_returns_same_session_in_thread_static_context()
 {
     //configure NHibernate
     var config = new Configuration();
     //initialize context
     var session1 = new Marshaler(config).CurrentSession;
     Assert.IsNotNull(session1);
     var session2 = new Marshaler(config).CurrentSession;
     Assert.AreSame(session1, session2);
     session1.Dispose();
     session2.Dispose();
 }
 public void Marshaler_returns_new_stateless_sessions()
 {
     //configure NHibernate
     var config = new Configuration();
     //initialize context
     var session1 = new Marshaler(config).GetStatelessSession();
     Assert.IsNotNull(session1);
     var session2 = new Marshaler(config).GetStatelessSession();
     Assert.IsNotNull(session2);
     Assert.AreNotSame(session1, session2);
     session1.Dispose();
     session2.Dispose();
 }
 public void Marshaler_can_access_stateful_session_before_stateless_session()
 {
     //configure NHibernate
     var config = new Configuration();
     //initialize context
     var session1 = new Marshaler(config).CurrentSession;
     Assert.IsNotNull(session1);
     var session2 = new Marshaler(config).GetStatelessSession();
     Assert.IsNotNull(session2);
     Assert.AreNotSame(session1, session2);
     session1.Dispose();
     session2.Dispose();
 }
            internal void AllocateMemoryRegion(Marshaler marshaler, object value)
            {
                if (marshallingRegion != null)
                {
                    marshaler.MarkMemoryForDispose(this.marshallingRegion.NativeMemory);
                    this.marshallingRegion = null;
                }

                if (context.Type != typeof(void))
                {
                    int s = marshaler.GetSize(context, value);
                    IntPtr p = Marshal.AllocHGlobal(s);
                    this.marshallingRegion = marshaler.MakeRegion(p, s);
                }
                else
                    this.marshallingRegion = null;
            }
        void Initialize()
        {
            lock (initializeLock)
            {
                if (initialized)
                    return;
                initialized = true;

                if (handleImplicit && handle == null)
                {
                    // retrieve handle default value
                    string handlePropertyName = proxiedType.Name + ".handle";
                    handle = TestSite.Properties[handlePropertyName];
                    if (handle == null)
                        throw new InvalidOperationException(
                            String.Format("RPC adapter with implicit handle passing has undefined handle. Set property '{0}' in the configuration.",
                                            handlePropertyName));
                }

                string dllPropertyName = proxiedType.Name + ".dllimport";
                string stubDllName = TestSite.Properties[dllPropertyName];
                if (stubDllName == null)
                    stubDllName = proxiedType.Name.ToLower() + "_rpcstubs.dll";

                string stubDllNameWithoutExtension =
                    System.IO.Path.GetFileNameWithoutExtension(stubDllName)
                    + "_" + Guid.NewGuid();

                string dllName = stubDllNameWithoutExtension + ".dll";

                msr = new Marshaler(site, NativeMarshalingConfiguration.Configuration);

                AppDomain currentDomain = AppDomain.CurrentDomain;
                string assName = "pinvoke_" + stubDllNameWithoutExtension;
                string fileName = string.Empty;
                string tempFileName = TryGetTempFileName();
                bool useTempFile = false;
                if (!string.IsNullOrEmpty(tempFileName))
                {
                    useTempFile = true;
                    fileName = Path.GetFileName(tempFileName);
                }
                else
                {
                    fileName = assName + ".dll";
                    tempFileName = fileName;
                }

                //Copy the stub dll into the same directory as the pinvoke assembly.
                string tempDir = Path.GetDirectoryName(tempFileName);
                CopyStub(stubDllName, tempDir, dllName);

                AssemblyName assemblyName = new AssemblyName(assName);
                AssemblyBuilder assemblyBuilder = null;
                if (useTempFile)
                {
                    assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, Path.GetTempPath());
                }
                else
                {
                    assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
                }
                ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assName, fileName);
                TypeBuilder typeBuilder = moduleBuilder.DefineType(assName);

                foreach (MethodInfo method in proxiedType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                {
                    ParameterInfo[] paramInfos = method.GetParameters();
                    RpcStub stub = new RpcStub();
                    Type[] stubParameterTypes = new Type[paramInfos.Length];
                    stub.parameters = new RpcParameter[paramInfos.Length];
                    stub.proxyMethod = method;
                    for (int i = 0; i < paramInfos.Length; i++)
                    {
                        ParameterInfo paramInfo = paramInfos[i];
                        Type proxyType = paramInfo.ParameterType;
                        Type nativeType;
                        if (proxyType.IsByRef)
                        {
                            proxyType = proxyType.GetElementType();
                            nativeType = typeof(IntPtr);
                        }
                        else
                        {
                            nativeType = GetNativeType(paramInfo, proxyType);
                        }
                        stubParameterTypes[i] = nativeType;
                        stub.parameters[i] = new RpcParameter(paramInfo, proxyType, nativeType);
                    }
                    stub.returnParameter =
                        new RpcParameter(method.ReturnParameter, method.ReturnType,
                                         GetNativeType(method.ReturnParameter, method.ReturnType));

                    if (handleImplicit)
                    {
                        List<Type> stubParametersTypeList = new List<Type>(stubParameterTypes);
                        stubParametersTypeList.Insert(0, typeof(IntPtr));
                        stubParameterTypes = stubParametersTypeList.ToArray();
                    }
                    stub.stubBuilder =
                        typeBuilder.DefinePInvokeMethod(
                            method.Name, dllName,
                            MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
                            CallingConventions.Standard,
                            stub.returnParameter.nativeType, stubParameterTypes,
                            callingConvention, charset);
                    stub.stubBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig);
                    stubs[method] = stub;

                }

                typeBuilder.CreateType();

                // Build types for memory management types.
                string UserRpcMemMgmtTypeName = "UserRpcMemMgmt";
                string userFreeMethodName = "MIDL_user_free";

                TypeBuilder UserRpcMemMgmtBuilder =
                    moduleBuilder.DefineType(UserRpcMemMgmtTypeName);
                BuildMemoryManagementType(UserRpcMemMgmtBuilder, typeof(UserRpcMemoryManagement), dllName);

                // Save and reload the pinvoke assembly
                try
                {
                    assemblyBuilder.Save(fileName);
                }
                catch (IOException e)
                {
                    throw new InvalidOperationException(
                            String.Format("cannot create P/Invoke stub assembly {0}: {1}", fileName, e.Message));
                }
                Assembly reloaded = null;
                if (useTempFile)
                {
                    reloaded = Assembly.LoadFrom(tempFileName);
                }
                else
                {
                    reloaded = Assembly.LoadFrom(fileName);
                }
                Type stubType = reloaded.GetType(assName);
                foreach (RpcStub stub in stubs.Values)
                {
                    stub.stubMethod = stubType.GetMethod(stub.proxyMethod.Name);
                }

                string fullDllName = dllName;
                if (useTempFile)
                {
                    fullDllName = Path.Combine(tempDir, dllName);
                }
                if (NativeMethods.HasMethod(fullDllName, userFreeMethodName))
                {
                    Type userRpcMemMgmtType = reloaded.GetType(UserRpcMemMgmtTypeName);
                    rpcFreeMethod = userRpcMemMgmtType.GetMethod(userFreeMethodName);
                }
            }
        }
        protected override IMessage Invoke(IMethodCallMessage mcall)
        {
            Marshaler marshaler = new Marshaler(site, NativeMarshalingConfiguration.Configuration);

            foreach (Type type in proxiedType.Assembly.GetTypes())
            {
                marshaler.DefineCustomType(type.Name, type);
            }

            if (mcall.MethodBase == getHandleMethod)
                return GetHandle(mcall);
            if (mcall.MethodBase == setHandleMethod)
                return SetHandle(mcall);

            Initialize();

            RpcStub stub;
            if (!stubs.TryGetValue(mcall.MethodBase, out stub))
                throw new InvalidOperationException(String.Format("cannot find stub for method '{0}'", mcall.MethodBase));

            // marshal parameters
            int n = stub.parameters.Length;
            int actualsOffs = handleImplicit ? 1 : 0;
            object[] actuals = new object[n + actualsOffs];
            if (handleImplicit)
            {
                if (handle == null)
                    marshaler.TestAssumeFail(
                        "handle undefined for rpc interface '{0}' with implicit handle passing",
                        proxiedType);
                IntPtr ptr = Marshal.StringToHGlobalUni(handle);
                marshaler.MarkMemoryForDispose(ptr);
                actuals[0] = ptr;
            }
            marshaler.EnterContext();
            for (int i = 0; i < n; i++)
            {
                if (!stub.parameters[i].IsOut)
                {
                    marshaler.DefineSymbol(mcall.GetArgName(i), mcall.Args[i]);
                }
            }

            ParameterInfo[] parameterInfos = mcall.MethodBase.GetParameters();
            for (int pass = 0; pass < 2; pass++)
            {
                for (int i = 0; i < n; i++)
                {
                    if (pass == 0 && stub.parameters[i].HasDynamicExpression)
                    {
                        continue;
                    }

                    if (pass == 1
                        && !stub.parameters[i].HasDynamicExpression)
                    {
                        continue;
                    }

                    stub.parameters[i].AllocateMemoryRegion(marshaler, mcall.Args[i]);

                    RpcParameter rp = stub.parameters[i];
                    if (rp.marshallingRegion != null)
                        rp.marshallingRegion.TryReset();
                    if (!rp.IsOut
                        && mcall.Args[i] != null)
                    {
                        object value = mcall.Args[i];

                        // Validate the value of the parameter.
                        if (this.needAutoValidate)
                            CheckParameter(parameterInfos[i], value, mcall, marshaler.SymbolStore);

                        marshaler.MarshalInto(rp.context, rp.marshallingRegion, mcall.Args[i]);
                    }
                    else
                    {
                        marshaler.EnterRegion(rp.marshallingRegion);
                        marshaler.Clear(marshaler.GetSize(rp.context, null));
                        marshaler.ExitRegion();
                    }
                    if (!rp.IsByRef)
                    {
                        actuals[i + actualsOffs] = rp.Get();
                    }
                    else
                    {
                        if (mcall.Args[i] == null && !rp.IsOut)
                        {
                            actuals[i + actualsOffs] = IntPtr.Zero;
                        }
                        else
                        {
                            actuals[i + actualsOffs] = rp.marshallingRegion.NativeMemory;
                        }
                    }

                    marshaler.DefineSymbol(mcall.GetArgName(i), actuals[i + actualsOffs]);
                }
            }

            // call
            object result;
            try
            {
                result = stub.stubMethod.Invoke(null, actuals);
            }
            catch (TargetInvocationException e)
            {
                throw e.InnerException;
            }

            // marshal output parameters
            object[] resultArgs = new object[n];

            marshaler.IsProbingUnmarshaling = true;
            for (int pass = 0; pass < 2; pass++)
            {
                for (int i = 0; i < n; i++)
                {
                    RpcParameter rp = stub.parameters[i];

                    if (rp.marshallingRegion != null)
                        rp.marshallingRegion.TryReset();
                    if (rp.IsByRef)
                    {
                        object res = resultArgs[i] =
                            marshaler.UnmarshalFrom(rp.context, rp.marshallingRegion);

                        if (marshaler.IsProbingUnmarshaling == false)
                        {
                            RpcAdapterValidate(res, rp.context.Attributes, marshaler.SymbolStore);

                            if (rp.IsOut && marshaler.GetNativeType(rp.context) == typeof(IntPtr))
                            {
                                foreach (IntPtr ptr in marshaler.ForeignMemory)
                                {
                                    if (ptr != IntPtr.Zero && rpcFreeMethod != null)
                                    {
                                        rpcFreeMethod.Invoke(null, new object[] { ptr });
                                    }
                                }
                            }
                        }
                        marshaler.ForeignMemory.Clear();
                        if (!rp.IsByRef)
                        {
                            marshaler.DefineSymbol(mcall.GetArgName(i), rp.Get());
                        }
                        else
                        {
                            marshaler.DefineSymbol(mcall.GetArgName(i),
                                rp.marshallingRegion.NativeMemory);
                        }
                    }
                    else
                    {
                        resultArgs[i] = mcall.Args[i];
                    }
                }
                marshaler.IsProbingUnmarshaling = false;
            }
            if (stub.returnParameter.nativeType != typeof(void))
            {
                stub.returnParameter.AllocateMemoryRegion(marshaler, result);

                stub.returnParameter.marshallingRegion.TryReset();
                stub.returnParameter.Set(result);
                result = marshaler.UnmarshalFrom(
                            stub.returnParameter.context,
                            stub.returnParameter.marshallingRegion);

                RpcAdapterValidate(result, null, null);
            }
            marshaler.ExitContext();
            marshaler.FreeMemory();
            marshaler.Dispose();
            marshaler = null;

            CheckOperation(mcall);
            ReturnMessage mret = new ReturnMessage(result, resultArgs, resultArgs.Length, mcall.LogicalCallContext, mcall);
            return mret;
        }