/// <summary>
        /// This function attempts to find out if there is currently a node running
        /// for a given index. The node is running if the global mutex with a
        /// "Node_" + nodeId + "_ActiveReady" as a name was created
        /// </summary>
        private static bool checkIfNodeActive(int nodeNumber)
        {
            bool            nodeIsActive     = false;
            EventWaitHandle nodeActiveHandle = null;

            try
            {
                nodeActiveHandle = EventWaitHandle.OpenExisting(LocalNodeProviderGlobalNames.NodeActiveEventName(nodeNumber));
                nodeIsActive     = true;
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                // Assume that the node is not running
            }
            finally
            {
                nodeActiveHandle?.Close();
            }

            return(nodeIsActive);
        }
示例#2
0
文件: LocalNode.cs 项目: xen2/msbuild
        /// <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);
        }
示例#3
0
        /// <summary>
        /// This function launches a new node given a node index
        /// </summary>
        private void LaunchNode(int nodeIndex)
        {
            EventWaitHandle nodeReadyEvent = null;

            string msbuildLocation = Path.Combine(locationOfMSBuildExe, "MSBuild.exe");

            ErrorUtilities.VerifyThrow(File.Exists(msbuildLocation), "Msbuild.exe cannot be found at: " + msbuildLocation);

            bool exitedDueToError = true;

            try
            {
                NativeMethods.STARTUPINFO startInfo = new NativeMethods.STARTUPINFO();
                startInfo.cb = Marshal.SizeOf(startInfo);
                uint dwCreationFlags = NativeMethods.NORMAL_PRIORITY_CLASS;
                if (!Engine.debugMode)
                {
                    startInfo.hStdError  = NativeMethods.InvalidHandle;
                    startInfo.hStdInput  = NativeMethods.InvalidHandle;
                    startInfo.hStdOutput = NativeMethods.InvalidHandle;
                    startInfo.dwFlags    = NativeMethods.STARTF_USESTDHANDLES;
                    dwCreationFlags      = dwCreationFlags | NativeMethods.CREATE_NO_WINDOW;
                }

                NativeMethods.SECURITY_ATTRIBUTES pSec = new NativeMethods.SECURITY_ATTRIBUTES();
                NativeMethods.SECURITY_ATTRIBUTES tSec = new NativeMethods.SECURITY_ATTRIBUTES();
                pSec.nLength = Marshal.SizeOf(pSec);
                tSec.nLength = Marshal.SizeOf(tSec);

                NativeMethods.PROCESS_INFORMATION pInfo = new NativeMethods.PROCESS_INFORMATION();

                string appName = msbuildLocation;
                // Repeat the executable name as the first token of the command line because the command line
                // parser logic expects it and will otherwise skip the first argument
                string cmdLine = msbuildLocation + " /nologo /oldom /nodemode:" + nodeData[nodeIndex].NodeNumber;
                NativeMethods.CreateProcess(appName, cmdLine,
                                            ref pSec, ref tSec,
                                            false, dwCreationFlags,
                                            NativeMethods.NullPtr, null, ref startInfo, out pInfo);

                nodeReadyEvent = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeActiveEventName(nodeData[nodeIndex].NodeNumber));

                // Wait until the node is ready to process the requests
                if (nodeReadyEvent.WaitOne(launchTimeout, false))
                {
                    exitedDueToError = false;
                }
            }
            finally
            {
                // Dispose before losing scope
                if (nodeReadyEvent != null)
                {
                    nodeReadyEvent.Close();
                }

                if (exitedDueToError)
                {
                    nodeData[nodeIndex].CommunicationFailed = true;
                }
            }
        }