Пример #1
0
        /// <summary>
        /// Generic copy (either from kernel or to kernel)
        /// Determines if the thing we are moving is an endpoint and copies it accordingly.
        /// </summary>
        public static Allocation *MoveData(SharedHeap fromHeap,
                                           SharedHeap toHeap,
                                           Process newOwner,
                                           Allocation *data)
        {
            if (data == null)
            {
                return(data);
            }

            if (!fromHeap.Validate(data))
            {
                throw new ArgumentException("Bad argument. Not visible");
            }

            // We can only transfer either into our out of the kernel's heap
            DebugStub.Assert(fromHeap == SharedHeap.KernelSharedHeap ||
                             toHeap == SharedHeap.KernelSharedHeap);

            if (SystemType.IsSubtype(data, EndpointCoreSystemType))
            {
                // we have an endpoint
                DeliveryImpl di = EndpointCore.AllocationEndpointDeliveryImpl(data);
                return(di.MoveEndpoint(fromHeap, toHeap, newOwner));
            }
            else
            {
                // we have a NON-endpoint
                // TODO FIX this!
                return(null); // MoveNonEndpoint(fromHeap, toHeap, newOwner, data);
            }
        }
        /// <summary>
        /// The peer thread might try this too, so we use the ref count of the
        /// underlying memory to allow only the last freeer to also free the
        /// associated auto-reset event handle.  Make sure to grab the handle
        /// before freeing the endpoint.
        /// </summary>
        unsafe private static bool TryFreeResources(
            Allocation * /*EndpointCore*/ endpoint,
            SharedHeap.AllocationOwnerId ownerId)
        {
            EndpointCore *epData =
                (EndpointCore *)Allocation.GetDataUnchecked(endpoint);

            AutoResetEventHandle areHandle = epData->GetAreHandle();
            DeliveryHandle       dh        = epData->dImpHandle;

            int channelId = epData->ChannelId;

            bool lastRefGone = SharedHeap.KernelSharedHeap.Free(endpoint,
                                                                ownerId);

            if (lastRefGone)
            {
                if (dh != DeliveryHandle.Zero)
                {
                    DeliveryHandle.Dispose(dh);
                }
                if (areHandle.id != UIntPtr.Zero)
                {
                    Process.kernelProcess.ReleaseHandle(areHandle.id);
                }
            }

            return(lastRefGone);
        }
Пример #3
0
 /// <summary>
 /// Performs the initialization of the core part of each endpoint and cross links
 /// them to form a channel.  Uses the standard shared address space delivery
 /// mechanism.
 /// </summary>
 public static void Connect(
     Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
     Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
     Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp)
 {
     Connect(imp, exp, securityEp, SingleAddrSpaceDelivery.ImplName);
 }
Пример #4
0
        /// <summary>
        /// Explicitly frees this end of the channel.
        ///
        /// Since both threads on the channel could try to do this simultaneously,
        /// we use the ref counting on the underlying endpoints to let the last
        /// free operation (the one pulling the ref count to 0) to free the associated
        /// event.
        /// </summary>
        public unsafe static void Free(Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint)
        {
            // Use unchecked GetData here, since this may be called from the
            // cleanup threading running in the kernel.
            EndpointCore *ep = ((EndpointCore *)Allocation.GetDataUnchecked(endpoint));

            if (ep->deliveryHandle != DeliveryHandle.Zero)
            {
                if (DeliveryHandle.Free(ep->deliveryHandle))
                {
                    Interlocked.Decrement(ref openChannelCount);
                }
            }
            else
            {
                // was never connected, just free this endpoint
                AutoResetEventHandle areHandle = ep->cachedMessageEvent;

                SharedHeap.KernelSharedHeap.Free(endpoint,
                                                 SharedHeap.CurrentProcessSharedHeap.EndpointPeerOwnerId);
                if (areHandle.id != UIntPtr.Zero)
                {
                    Process.kernelProcess.ReleaseHandle(areHandle.id);
                }
            }
        }
Пример #5
0
 /// <summary>
 /// Used internally by the kernel to transfer an endpoint to a new owner
 ///
 /// Can be used to transfer ANY kind of shared heap data, not just endpoints.
 /// </summary>
 public static Allocation *MoveEndpoint(SharedHeap fromHeap,
                                        SharedHeap toHeap,
                                        Process newOwner,
                                        Allocation *ep)
 {
     return(DeliveryImpl.MoveData(fromHeap, toHeap, newOwner, ep));
 }
Пример #6
0
        /// <summary>
        /// Transfer any contents that needs to be adjusted from the transferee to the target
        /// endpoint.
        /// </summary>
        // TODO: change "ref EndpointCore" to "EndpointCore"
        public static void TransferContentOwnership(
            ref EndpointCore transferee,
            ref EndpointCore target)
        {
            // TODO MAKE THIS APROPRIATE TO BOTH SINGLE AND PAGED IMPLS
            DeliveryImpl transfereeDi = transferee.EndpointDeliveryImpl;

            // XXX BUG? BUG? BUG?
            //   targetDi = transferee.EndpointDeliveryImpl
            // should be:
            //   targetDi = target.EndpointDeliveryImpl
            DeliveryImpl targetDi = transferee.EndpointDeliveryImpl;

            VTable.Assert((transfereeDi != null) && (targetDi != null));
            //Monitoring.Log(Monitoring.Provider.ChannelService,
            //               (ushort)ChannelServiceEvent.TransferContentOwnership, 0,
            //               (uint)transfereeDi.ProcessId,
            //               (uint)targetDi.ProcessId,
            //               (uint)transfereeDi.ChannelId,
            //               (uint)targetDi.ChannelId,
            //               (uint)targetDi.Peer.ChannelId);
            int toProcessId = targetDi.ProcessId;

            transfereeDi.ProcessId = toProcessId;
            DelegationState newstate = transfereeDi.OwnerDelegationState;

            transfereeDi.OwnerPrincipalHandle =
                TransferPrincipal(transfereeDi.OwnerPrincipalHandle, toProcessId, ref newstate);
            transfereeDi.OwnerDelegationState = newstate;
            Allocation *transfereePeerAllocation = transfereeDi.Peer();

            // also transfer the peer allocation
            Allocation.SetOwnerProcessId(transfereePeerAllocation, toProcessId);
        }
 public static unsafe void Truncate(Allocation *allocation,
                                    UIntPtr newLength)
 {
     SharedHeap.CurrentProcessSharedHeap.Truncate(
         (SharedHeap.Allocation *)allocation,
         newLength
         );
 }
 public static unsafe Allocation *Split(Allocation *allocation,
                                        UIntPtr offset)
 {
     return((Allocation *)SharedHeap.CurrentProcessSharedHeap.Split(
                (SharedHeap.Allocation *)allocation,
                SharedHeap.CurrentProcessSharedHeap.DataOwnerId,
                offset));
 }
        internal override void Connect(DeliveryImpl expDi,
                                       Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp)
        {
            base.Connect(expDi, securityEp);

            this.Initialize(expDi);
            expDi.Initialize(this);
        }
Пример #10
0
 internal static unsafe void SetOwnerProcessId(
     Allocation *allocation,
     int newOwnerProcessId)
 {
     SharedHeap.Allocation.SetOwnerProcessId(
         (SharedHeap.Allocation *)allocation,
         newOwnerProcessId);
 }
Пример #11
0
 internal static unsafe void SetType(
     Allocation *allocation,
     UIntPtr type)
 {
     SharedHeap.Allocation.SetType(
         (SharedHeap.Allocation *)allocation,
         type);
 }
Пример #12
0
 public static void AcceptDelegation(Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
                                     Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
                                     Allocation * /*EndpointCore* opt(ExHeap)!*/ ep)
 {
     EndpointCoreImplementation.AcceptDelegation((SharedHeap.Allocation *)imp,
                                                 (SharedHeap.Allocation *)exp,
                                                 (SharedHeap.Allocation *)ep);
 }
Пример #13
0
 public static unsafe void TransferTo(
     Allocation *allocation,
     AllocationOwnerId newOwner)
 {
     return(SharedHeap.TransferOwnership(
                (SharedHeap.Allocation *)allocation,
                SharedHeap.CurrentProcessSharedHeap.DataOwnerId,
                newOwner));
 }
Пример #14
0
 public static unsafe void TransferFrom(
     Allocation *allocation,
     AllocationOwnerId oldOwner)
 {
     return(SharedHeap.TransferOwnership(
                (SharedHeap.Allocation *)allocation,
                oldOwner,
                SharedHeap.CurrentProcessSharedHeap.DataOwnerId));
 }
Пример #15
0
 public static void Connect(
     Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
     Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
     Allocation * /*EndpointCore* opt(ExHeap) */ ep)
 {
     EndpointCoreImplementation.Connect((SharedHeap.Allocation *)imp,
                                        (SharedHeap.Allocation *)exp,
                                        (SharedHeap.Allocation *)ep);
 }
Пример #16
0
        public static void TransferBlockOwnership(Allocation *ptr, ref EndpointCore target)
        {
            fixed(EndpointCore *ep = &target)
            {
                EndpointCoreImplementation *epimp = (EndpointCoreImplementation *)ep;

                EndpointCoreImplementation.TransferBlockOwnership((SharedHeap.Allocation *)ptr, ref *epimp);
            }
        }
Пример #17
0
 public static unsafe Allocation *Share(Allocation *allocation,
                                        UIntPtr startOffset,
                                        UIntPtr endOffset)
 {
     return((Allocation *)SharedHeap.CurrentProcessSharedHeap.Share(
                (SharedHeap.Allocation *)allocation,
                SharedHeap.CurrentProcessSharedHeap.DataOwnerId,
                startOffset,
                endOffset));
 }
        internal override void Initialize(DeliveryImpl peerDi)
        {
            peerEp = SharedHeap.CurrentProcessSharedHeap.Share(peerDi.EndpointAlloc,
                                                               SharedHeap.CurrentProcessSharedHeap.EndpointPeerOwnerId,
                                                               (UIntPtr)0,
                                                               Allocation.GetSize(peerDi.EndpointAlloc));

            this.endpoint->SetCachedPeer(peerEp);
            this.endpoint->SetPeerStateValid(true);
        }
Пример #19
0
        public static Allocation * //EndpointCore* opt(ExHeap)!
        Allocate(uint size, SystemType st)
        {
            Allocation *ep = (Allocation *)SharedHeap.CurrentProcessSharedHeap.Allocate(
                size, st.id, 0, SharedHeap.CurrentProcessSharedHeap.EndpointOwnerId);

            if (ep == null)
            {
                throw new ApplicationException("SharedHeap.Allocate returned null");
            }
            return(ep);
        }
Пример #20
0
 public static unsafe UIntPtr GetData(Allocation *allocation)
 {
     // CANNOT CHECK THE OWNER HERE UNLESS WE MAKE CURRENTPROCESS visible
     // to this compilation
     //
     // Check owner!
     //            if (allocation->owner != Thread.CurrentProcess.ProcessId) {
     //                DebugStub.Break();
     //            }
     return(allocation->data);
 }
Пример #21
0
        public static void AcceptDelegation(Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
                                            Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
                                            Allocation * /*EndpointCore* opt(ExHeap)!*/ ep)
        {
            DeliveryImpl impDi = AllocationEndpointDeliveryImpl(imp);
            DeliveryImpl expDi = AllocationEndpointDeliveryImpl(exp);
            DeliveryImpl epDi  = AllocationEndpointDeliveryImpl(ep);

            VTable.Assert((impDi != null && expDi != null && epDi != null));
            VTable.Assert((impDi.GetType() == expDi.GetType()) &&
                          (impDi.GetType() == epDi.GetType()));
            impDi.AcceptDelegation(expDi, epDi);
        }
Пример #22
0
        internal static DeliveryImpl AllocationEndpointDeliveryImplUnchecked(
            Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint)
        {
            EndpointCore *ep = (EndpointCore *)Allocation.GetDataUnchecked(endpoint);

            if (ep == null)
            {
                return(null);
            }
            else
            {
                return(ep->EndpointDeliveryImpl);
            }
        }
Пример #23
0
        /// <summary>
        /// Performs the initialization of the core part of each endpoint and cross links
        /// them to form a channel.  Uses the given delivery mechanism.
        /// </summary>
        public static void Connect(
            Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
            Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
            Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp,
            string deliveryImplType)
        {
            if (imp == null || exp == null)
            {
                throw new ApplicationException("Connect called with null endpoints");
            }
            EndpointCore *impData = (EndpointCore *)Allocation.GetData(imp);
            EndpointCore *expData = (EndpointCore *)Allocation.GetData(exp);

            if (impData == null || expData == null)
            {
                throw new ApplicationException("SharedHeap.GetData return null");
            }

            Tracing.Log(Tracing.Debug, "connect {0:x8} and {1:x8}",
                        (UIntPtr)imp, (UIntPtr)exp);

            if (!(DeliveryHandle.Create(deliveryImplType, imp, out impData->deliveryHandle) &&
                  DeliveryHandle.Create(deliveryImplType, exp, out expData->deliveryHandle)))
            {
                throw new EndpointCoreException(
                          "Error trying to create EndpointCore using \"" +
                          deliveryImplType +
                          "\" delivery implementation");
            }
#if false
            DebugStub.Print("imp handle {0,8:x} exp handle {1,8:x}\n",
                            __arglist((uint)impData->deliveryHandle.id, (uint)expData->deliveryHandle.id));
#endif
            DeliveryImpl impDi = impData->EndpointDeliveryImpl;
            DeliveryImpl expDi = expData->EndpointDeliveryImpl;

            VTable.Assert(impDi != null && expDi != null);

            impDi.Connect(expDi, securityEp);

            // keep track of how many channels are open
            Interlocked.Increment(ref openChannelCount);
#if CHANNEL_COUNT
            PerfCounters.IncrementChannelsCreated();
#endif
            Monitoring.Log(Monitoring.Provider.EndpointCore,
                           (ushort)EndpointCoreEvent.Connect, 0,
                           (uint)expData->ChannelId, 0, 0, 0, 0);
        }
Пример #24
0
        /// <summary>
        /// Transfer the given Allocation block to the target endpoint
        /// </summary>
        public static void TransferBlockOwnership(Allocation *ptr, ref EndpointCore target)
        {
            Allocation.SetOwnerProcessId(ptr, target.cachedOwnerProcessId);
            // TODO MAKE THIS APROPRIATE TO BOTH SINGLE AND PAGED IMPLS
            DeliveryImpl di = target.EndpointDeliveryImpl;

            VTable.Assert(di != null);
            //Monitoring.Log(Monitoring.Provider.ChannelService,
            //               (ushort)ChannelServiceEvent.TransferBlockOwnership, 0,
            //               (uint)di.ChannelId,
            //               (uint)di.ProcessId,
            //               0, 0, 0);
#if CHANNEL_COUNT
            IncreaseBytesSentCount((long)Allocation.GetSize(ptr));
#endif
            Allocation.SetOwnerProcessId(ptr, di.ProcessId);
        }
Пример #25
0
        ////////////////////////////////////////////////////////////////////
        // Class Methods
        //

        internal DeliveryImpl(Allocation * /*EndpointCore* opt(ExHeap)!*/ ep)
        {
            this.endpointAlloc = ep;
            this.endpoint      = ((EndpointCore *)Allocation.GetData(ep));

            // set default values (shadow cached values in EndpointCore if necessary)
            setMessageEvent(new AutoResetEventHandle(
                                Process.kernelProcess.AllocateHandle(new AutoResetEvent(false))));
            endpoint->CollectionEvent = new AutoResetEventHandle();

            endpoint->SetCachedPeer(null);    // set as null by default

            ProcessId = Thread.CurrentProcess.ProcessId;
            ChannelId = 0;                    // zero initially, corrected in connect
            Marshall  = false;                // false by default
            Closed    = true;                 // opened in connect

            principalHandle = new PrincipalHandle(Thread.CurrentProcess.Principal.Val);
            delegationState = DelegationState.None;
            receiveCount    = 0;
        }
Пример #26
0
        public unsafe static bool Create(
            string implName,
            Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint,
            out DeliveryHandle handle)
        {
            DeliveryImpl deliveryImpl;

            switch (implName)
            {
            case SingleAddrSpaceDelivery.ImplName:
                deliveryImpl = new SingleAddrSpaceDelivery(endpoint);
                break;

#if PAGING
                // TODO paging
#endif
            default:
                throw new DeliveryHandleException(
                          "Unknown channel delivery implementation \"" +
                          implName +
                          "\" requested");
            }

            if (!deliveryImpl.IsMechanismInitialized())
            {
                DebugStub.Print("Ack! IsMechInit returns false!\n");
                DebugStub.Break();
                handle = Zero;
                return(false);
            }

            handle = new DeliveryHandle(
                Process.kernelProcess.AllocateHandle(deliveryImpl));
#if false
            unsafe {
                DebugStub.WriteLine("DeliveryHandle.Create: got handle {0,8:x}\n", __arglist((uint)handle.id));
            }
#endif
            return(true);
        }
Пример #27
0
        internal virtual void Connect(DeliveryImpl expDi,
                                      Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp)
        {
            // security principals are held in the delivery impl, not the endpoint core
            // since this allows them to be kept out of user memory in paging builds
            if (securityEp != null)
            {
                DeliveryImpl secImpl =
                    EndpointCore.AllocationEndpointDeliveryImpl(securityEp);
                if (secImpl != null &&
                    secImpl.OwnerDelegationState == DelegationState.Mediated)
                {
                    this.OwnerPrincipalHandle = secImpl.OwnerPrincipalHandle;
                }
            }

            int newChannelId = EndpointCore.GetNextChannelId();

            this.ChannelId  = -newChannelId;
            expDi.ChannelId = newChannelId;

            this.Closed  = false;
            expDi.Closed = false;
        }
Пример #28
0
 public static extern void AcceptDelegation(Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
                                            Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
                                            Allocation * /*EndpointCore* opt(ExHeap)!*/ ep);
Пример #29
0
 public static void Free(Allocation * /* EndpointCore* opt(ExHeap) */ endpoint)
 {
     EndpointCoreImplementation.Free((SharedHeap.Allocation *)endpoint);
 }
Пример #30
0
 public void SetCachedPeer(Allocation * /* EndpointCore */ peer)
 {
     cachedPeer = peer;
 }