internal override Allocation *MoveEndpoint(SharedHeap fromHeap,
                                                   SharedHeap toHeap,
                                                   Process newOwner)
        {
            DebugStub.Assert(fromHeap == toHeap);

            // Careful about the order.
            // Since we don't know if this is a release (current process owns it)
            // or an acquire (current process does not necessarily own it), we
            // have to bypass the owner check here.
            int processId = newOwner.ProcessId;

            this.ProcessId            = processId;
            this.OwnerPrincipalHandle = new PrincipalHandle(newOwner.Principal.Val);
            // Don't check for delegation here since this is for kernel calls on
            // moving endpoints to SIPs.  Delegation should not be involved.
            // The following should not be necessary, but just in case:
            this.OwnerDelegationState = DelegationState.None;

            Allocation.SetOwnerProcessId(this.endpointAlloc, processId);
            Allocation.SetOwnerProcessId(this.peerEp, processId);

            Monitoring.Log(Monitoring.Provider.EndpointCore,
                           (ushort)EndpointCoreEvent.TransferToProcess, 0,
                           (uint)ChannelId, (uint)processId, 0, 0, 0);
            return(this.endpointAlloc);
        }
        /// <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);
        }
        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);
        }