Пример #1
0
        /// <summary>
        /// Creates the shared memory region and map a view to it.
        /// </summary>
        private void InitializeMemoryMapping(string memoryMapName, bool allowExistingMapping)
        {
            // Null means use the default security permissions
            IntPtr pointerToSecurityAttributes = NativeMethods.NullPtr;
            IntPtr pSDNative = IntPtr.Zero;

            try
            {
                // Check to see if the user is an administrator, this is done to prevent non
                // administrator processes from accessing the shared memory. On a vista machine
                // the check does not differentiate beween the application being elevated to have
                // administrator rights or the application being started with administrator rights.
                // If the user is an administator create a new set of securityAttributes which make
                // the shared memory only accessable to administrators.
                if (NativeMethods.IsUserAdministrator())
                {
                    NativeMethods.SECURITY_ATTRIBUTES saAttr = new NativeMethods.SECURITY_ATTRIBUTES();
                    uint pSDLength = 0;
                    if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(NativeMethods.ADMINONLYSDDL, NativeMethods.SECURITY_DESCRIPTOR_REVISION, ref pSDNative, ref pSDLength))
                    {
                        throw new System.ComponentModel.Win32Exception();
                    }

                    saAttr.bInheritHandle       = 0;
                    saAttr.nLength              = Marshal.SizeOf(typeof(NativeMethods.SECURITY_ATTRIBUTES));
                    saAttr.lpSecurityDescriptor = pSDNative;
                    pointerToSecurityAttributes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NativeMethods.SECURITY_ATTRIBUTES)));
                    Marshal.StructureToPtr(saAttr, pointerToSecurityAttributes, true);
                }

                // The file mapping has either the default (current user) security permissions or
                // permissions restricted to only administrator users depending on the check above.
                // If pointerToSecurityAttributes is null the default permissions are used.
                this.pageFileMapping =
                    NativeMethods.CreateFileMapping
                    (
                        NativeMethods.InvalidHandle,
                        pointerToSecurityAttributes,
                        NativeMethods.PAGE_READWRITE,
                        0,
                        size + 4,
                        memoryMapName
                    );

                // If only new mappings are allowed and the current one has been created by somebody else
                // delete the mapping. Note that we would like to compare the GetLastError value against
                // ERROR_ALREADY_EXISTS but CLR sometimes overwrites the last error so to be safe we'll
                // not reuse the node for any unsuccessful value.
                if (!allowExistingMapping && Marshal.GetLastWin32Error() != NativeMethods.ERROR_SUCCESS)
                {
                    if (!pageFileMapping.IsInvalid && !pageFileMapping.IsClosed)
                    {
                        NativeMethods.UnmapViewOfFile(pageFileView);
                        pageFileMapping.Close();
                    }
                }
            }
            finally
            {
                NativeMethods.LocalFree(pointerToSecurityAttributes);
                NativeMethods.LocalFree(pSDNative);
            }

            if (!this.pageFileMapping.IsInvalid && !pageFileMapping.IsClosed)
            {
                // Maps a view of a file mapping into the address space of the calling process so that we can use the
                // view to read and write to the shared memory region.
                this.pageFileView =
                    NativeMethods.MapViewOfFile
                    (
                        this.pageFileMapping,
                        NativeMethods.FILE_MAP_ALL_ACCESS, // Give the map read, write, and copy access
                        0,                                 // Start mapped view at high order offset 0
                        0,                                 // Start mapped view at low order offset 0
                        // The size of the shared memory plus some extra space for an int
                        // to write the number of bytes written
                        (IntPtr)(size + 4)
                    );

                // Check to see if the file view has been created on the fileMapping.
                if (this.pageFileView == NativeMethods.NullPtr)
                {
                    // Make the shared memory not usable.
                    this.pageFileMapping.Close();
                }
                else
                {
                    this.name = memoryMapName;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Creates the shared memory region and map a view to it.
        /// </summary>
        private void InitializeMemoryMapping(string memoryMapName, bool allowExistingMapping)
        {
            // Null means use the default security permissions
            IntPtr pointerToSecurityAttributes = NativeMethods.NullPtr;
            IntPtr pSDNative = IntPtr.Zero;
            try
            {
                // Check to see if the user is an administrator, this is done to prevent non 
                // administrator processes from accessing the shared memory. On a vista machine 
                // the check does not differentiate beween the application being elevated to have
                // administrator rights or the application being started with administrator rights.
                // If the user is an administator create a new set of securityAttributes which make
                // the shared memory only accessable to administrators.
                if (NativeMethods.IsUserAdministrator())
                {
                    NativeMethods.SECURITY_ATTRIBUTES saAttr = new NativeMethods.SECURITY_ATTRIBUTES();
                    uint pSDLength = 0;
                    if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(NativeMethods.ADMINONLYSDDL, NativeMethods.SECURITY_DESCRIPTOR_REVISION, ref pSDNative, ref pSDLength))
                    {
                        throw new System.ComponentModel.Win32Exception();
                    }

                    saAttr.bInheritHandle = 0;
                    saAttr.nLength = Marshal.SizeOf(typeof(NativeMethods.SECURITY_ATTRIBUTES));
                    saAttr.lpSecurityDescriptor = pSDNative;
                    pointerToSecurityAttributes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NativeMethods.SECURITY_ATTRIBUTES)));
                    Marshal.StructureToPtr(saAttr, pointerToSecurityAttributes, true);
                }

               // The file mapping has either the default (current user) security permissions or 
               // permissions restricted to only administrator users depending on the check above.
               // If pointerToSecurityAttributes is null the default permissions are used.
               this.pageFileMapping =
                    NativeMethods.CreateFileMapping
                    (
                        NativeMethods.InvalidHandle,
                        pointerToSecurityAttributes,
                        NativeMethods.PAGE_READWRITE,
                        0,
                        size + 4,
                        memoryMapName
                    );

                // If only new mappings are allowed and the current one has been created by somebody else
                // delete the mapping. Note that we would like to compare the GetLastError value against
                // ERROR_ALREADY_EXISTS but CLR sometimes overwrites the last error so to be safe we'll
                // not reuse the node for any unsuccessful value.
                if (!allowExistingMapping && Marshal.GetLastWin32Error() != NativeMethods.ERROR_SUCCESS)
                {
                    if (!pageFileMapping.IsInvalid && !pageFileMapping.IsClosed)
                    {
                        NativeMethods.UnmapViewOfFile(pageFileView);
                        pageFileMapping.Close();
                    }
                }
            }
            finally
            {
                NativeMethods.LocalFree(pointerToSecurityAttributes);
                NativeMethods.LocalFree(pSDNative);
            }

            if (!this.pageFileMapping.IsInvalid && !pageFileMapping.IsClosed)
            {
                // Maps a view of a file mapping into the address space of the calling process so that we can use the 
                // view to read and write to the shared memory region.
                this.pageFileView =
                    NativeMethods.MapViewOfFile
                    (
                        this.pageFileMapping,
                        NativeMethods.FILE_MAP_ALL_ACCESS, // Give the map read, write, and copy access
                        0,  // Start mapped view at high order offset 0
                        0,  // Start mapped view at low order offset 0
                         // The size of the shared memory plus some extra space for an int
                         // to write the number of bytes written
                        (IntPtr)(size + 4)  
                    );

                // Check to see if the file view has been created on the fileMapping.
                if (this.pageFileView == NativeMethods.NullPtr)
                {
                    // Make the shared memory not usable.
                    this.pageFileMapping.Close();
                }
                else
                {
                    this.name = memoryMapName;
                }
            }
        }
Пример #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;
                }
            }
        }