// Note: in order to be consistent with other messagings (e.g. TcpMessaging) value 0 for timeouts mean infinite time.
        public SharedMemoryReceiver(string memoryMappedFileName, bool useExistingMemoryMappedFile, TimeSpan openTimeout, int maxMessageSize, MemoryMappedFileSecurity memmoryMappedFileSecurity)
        {
            using (EneterTrace.Entering())
            {
                myOpenTimeout          = (openTimeout == TimeSpan.Zero) ? TimeSpan.FromMilliseconds(-1) : openTimeout;
                myMemoryMappedFileName = memoryMappedFileName;
                myMaxMessageSize       = maxMessageSize;

                // If true then the listener will not create the new memory shared file but will open existing one.
                // This is useful for security restrictions if the functionality is used in the windows service.
                myUseExistingMemoryMappedFile = useExistingMemoryMappedFile;

                myMemmoryMappedFileSecurity = memmoryMappedFileSecurity;

                // If the security shall be applied.
                if (myMemmoryMappedFileSecurity != null)
                {
                    // Create the security for the WaitHandle sync logic.
                    myEventWaitHandleSecurity = new EventWaitHandleSecurity();
                    myEventWaitHandleSecurity.SetSecurityDescriptorSddlForm("S:(ML;;NW;;;LW)");
                    SecurityIdentifier        aSid         = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
                    EventWaitHandleAccessRule anAccessRule = new EventWaitHandleAccessRule(aSid,
                                                                                           EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize,
                                                                                           AccessControlType.Allow);
                    myEventWaitHandleSecurity.AddAccessRule(anAccessRule);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Create global events necessary for handshaking with the parent
        /// </summary>
        /// <param name="nodeNumber"></param>
        /// <returns>True if events created successfully and false otherwise</returns>
        private static bool CreateGlobalEvents(int nodeNumber)
        {
            bool createdNew;

            if (NativeMethods.IsUserAdministrator())
            {
                EventWaitHandleSecurity mSec = new EventWaitHandleSecurity();

                // Add a rule that grants the access only to admins and systems
                mSec.SetSecurityDescriptorSddlForm(NativeMethods.ADMINONLYSDDL);

                // Create an initiation event to allow the parent side  to prove to the child that we have the same level of privilege as it does.
                // this is done by having the parent set this event which means it needs to have administrative permissions to do so.
                globalInitiateActivationEvent = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeInitiateActivationEventName(nodeNumber), out createdNew, mSec);
            }
            else
            {
                // Create an initiation event to allow the parent side  to prove to the child that we have the same level of privilege as it does.
                // this is done by having the parent set this event which means it has atleast the same permissions as the child process
                globalInitiateActivationEvent = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeInitiateActivationEventName(nodeNumber), out createdNew);
            }

            // This process must be the creator of the event to prevent squating by a lower privilaged attacker
            if (!createdNew)
            {
                return(false);
            }

            // Informs the parent process that the child process has been created.
            globalNodeActive = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeActiveEventName(nodeNumber));
            globalNodeActive.Set();

            // Indicate to the parent process, this node is currently is ready to start to recieve requests
            globalNodeInUse = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeInUseEventName(nodeNumber));

            // Used by the parent process to inform the child process to shutdown due to the child process
            // not recieving the initialization command.
            globalNodeErrorShutdown = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeErrorShutdownEventName(nodeNumber));

            // Inform the parent process the node has started its communication threads.
            globalNodeActivate = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeActivedEventName(nodeNumber));

            return(true);
        }
        // Note: in order to be consistent with other messagings (e.g. TcpMessaging) value 0 for timeouts mean infinite time.
        public SharedMemorySender(string memoryMappedFileName, bool useExistingMemoryMappedFile, TimeSpan openTimeout, TimeSpan sendTimeout, int maxMessageSize, MemoryMappedFileSecurity memoryMappedFileSecurity)
        {
            using (EneterTrace.Entering())
            {
                try
                {
                    mySendTimeout = (sendTimeout == TimeSpan.Zero) ? TimeSpan.FromMilliseconds(-1) : sendTimeout;
                    myUseExistingMemoryMappedFile = useExistingMemoryMappedFile;
                    myMaxMessageSize = maxMessageSize;

                    // If the shared memory file is created by SharedMemoryReceiver then open existing one.
                    if (useExistingMemoryMappedFile)
                    {
                        TimeSpan anOpenTimeout = (openTimeout == TimeSpan.Zero) ? TimeSpan.FromMilliseconds(-1) : openTimeout;

                        // Try to open synchronization handlers.
                        mySharedMemoryReady   = EventWaitHandleExt.OpenExisting(memoryMappedFileName + "_SharedMemoryReady", anOpenTimeout);
                        mySharedMemoryFilled  = EventWaitHandleExt.OpenExisting(memoryMappedFileName + "_SharedMemoryFilled", anOpenTimeout);
                        mySharedMemoryCreated = EventWaitHandleExt.OpenExisting(memoryMappedFileName + "_ResponseSharedMemoryCreated", anOpenTimeout);

                        // Wait until the memory mapped file exist and then open it.
                        // Note: it shall be created by SharedMemoryReceiver.
                        if (!mySharedMemoryCreated.WaitOne(anOpenTimeout))
                        {
                            throw new InvalidOperationException(TracedObject + "failed to open memory mapped file because it does not exist.");
                        }
                        myMemoryMappedFile = MemoryMappedFile.OpenExisting(memoryMappedFileName);
                    }
                    // If the shared memory file shall be created by SharedMemorySender.
                    else
                    {
                        EventWaitHandleSecurity anEventWaitHandleSecurity = null;
                        if (memoryMappedFileSecurity != null)
                        {
                            // Create the security for the WaitHandle logic.
                            anEventWaitHandleSecurity = new EventWaitHandleSecurity();
                            anEventWaitHandleSecurity.SetSecurityDescriptorSddlForm("S:(ML;;NW;;;LW)");
                            SecurityIdentifier        aSid         = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
                            EventWaitHandleAccessRule anAccessRule = new EventWaitHandleAccessRule(aSid,
                                                                                                   EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize,
                                                                                                   AccessControlType.Allow);
                            anEventWaitHandleSecurity.AddAccessRule(anAccessRule);
                        }

                        // Create synchronization handlers.
                        bool aDummy;
                        mySharedMemoryReady   = new EventWaitHandle(false, EventResetMode.AutoReset, memoryMappedFileName + "_SharedMemoryReady", out aDummy, anEventWaitHandleSecurity);
                        mySharedMemoryFilled  = new EventWaitHandle(false, EventResetMode.AutoReset, memoryMappedFileName + "_SharedMemoryFilled", out aDummy, anEventWaitHandleSecurity);
                        mySharedMemoryCreated = new EventWaitHandle(false, EventResetMode.ManualReset, memoryMappedFileName + "_ResponseSharedMemoryCreated", out aDummy, anEventWaitHandleSecurity);

                        // Create the memory mapped file.
                        myMemoryMappedFile = MemoryMappedFile.CreateNew(memoryMappedFileName, maxMessageSize, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, memoryMappedFileSecurity, HandleInheritability.None);

                        // Indicate the shared memory is created.
                        mySharedMemoryCreated.Set();
                    }

                    myMemoryMappedFileStream = myMemoryMappedFile.CreateViewStream();
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + "failed to create SharedMemorySender.", err);

                    // Dispose resources alocated so far.
                    Dispose();

                    throw;
                }
            }
        }