OpenProcess() public static method

public static OpenProcess ( int processId, int access, bool throwIfExited ) : SafeProcessHandle
processId int
access int
throwIfExited bool
return SafeProcessHandle
Beispiel #1
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
#if FEATURE_TRACESWITCH
            Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
            if (_processTracing.TraceVerbose)
            {
                StackFrame calledFrom = new StackTrace(true).GetFrame(0);
                Debug.WriteLine("   called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
            }
#endif
#endif
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with
                    // zero timeout to see if the process has exited.
                    using (Interop.Kernel32.ProcessWaitHandle waitHandle = new Interop.Kernel32.ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                            {
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                            }
                        }
                    }
                }

                // If we dispose of our contained handle we'll be in a bad state. NetFX dealt with this
                // by doing a try..finally around every usage of GetProcessHandle and only disposed if
                // it wasn't our handle.
                return(new SafeProcessHandle(_processHandle.DangerousGetHandle(), ownsHandle: false));
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.Kernel32.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return(handle);
            }
        }
Beispiel #2
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
#if FEATURE_TRACESWITCH
            Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
            if (_processTracing.TraceVerbose)
            {
                StackFrame calledFrom = new StackTrace(true).GetFrame(0);
                Debug.WriteLine("   called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
            }
#endif
#endif
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with
                    // zero timeout to see if the process has exited.
                    using (ProcessWaitHandle waitHandle = new ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                            {
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                            }
                        }
                    }
                }
                return(_processHandle);
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.mincore.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.mincore.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.mincore.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return(handle);
            }
        }
Beispiel #3
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with
                    // zero timeout to see if the process has exited.
                    using (Interop.Kernel32.ProcessWaitHandle waitHandle = new Interop.Kernel32.ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                            {
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                            }
                        }
                    }
                }

                // If we dispose of our contained handle we'll be in a bad state. NetFX dealt with this
                // by doing a try..finally around every usage of GetProcessHandle and only disposed if
                // it wasn't our handle.
                return(new SafeProcessHandle(_processHandle.DangerousGetHandle(), ownsHandle: false));
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.Kernel32.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return(handle);
            }
        }
        private static ProcessModuleCollection GetModules(int processId, bool firstModuleOnly)
        {
            // preserving Everett behavior.
            if (processId == SystemProcessID || processId == IdleProcessID)
            {
                // system process and idle process doesn't have any modules
                throw new Win32Exception(HResults.E_FAIL, SR.EnumProcessModuleFailed);
            }

            SafeProcessHandle processHandle = SafeProcessHandle.InvalidHandle;

            try
            {
                processHandle = ProcessManager.OpenProcess(processId, Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION | Interop.Advapi32.ProcessOptions.PROCESS_VM_READ, true);

                bool succeeded = Interop.Kernel32.EnumProcessModules(processHandle, null, 0, out int needed);

                // The API we need to use to enumerate process modules differs on two factors:
                //   1) If our process is running in WOW64.
                //   2) The bitness of the process we wish to introspect.
                //
                // If we are not running in WOW64 or we ARE in WOW64 but want to inspect a 32 bit process
                // we can call psapi!EnumProcessModules.
                //
                // If we are running in WOW64 and we want to inspect the modules of a 64 bit process then
                // psapi!EnumProcessModules will return false with ERROR_PARTIAL_COPY (299).  In this case we can't
                // do the enumeration at all.  So we'll detect this case and bail out.
                if (!succeeded)
                {
                    if (!Interop.Kernel32.IsWow64Process(Interop.Kernel32.GetCurrentProcess(), out bool sourceProcessIsWow64))
                    {
                        throw new Win32Exception();
                    }

                    if (!Interop.Kernel32.IsWow64Process(processHandle, out bool targetProcessIsWow64))
                    {
                        throw new Win32Exception();
                    }

                    if (sourceProcessIsWow64 && !targetProcessIsWow64)
                    {
                        // Wow64 isn't going to allow this to happen, the best we can do is give a descriptive error to the user.
                        throw new Win32Exception(Interop.Errors.ERROR_PARTIAL_COPY, SR.EnumProcessModuleFailedDueToWow);
                    }

                    EnumProcessModulesUntilSuccess(processHandle, null, 0, out needed);
                }

                int      modulesCount  = needed / IntPtr.Size;
                IntPtr[] moduleHandles = new IntPtr[modulesCount];
                while (true)
                {
                    int size = needed;
                    EnumProcessModulesUntilSuccess(processHandle, moduleHandles, size, out needed);
                    if (size == needed)
                    {
                        break;
                    }

                    if (needed > size && needed / IntPtr.Size > modulesCount)
                    {
                        modulesCount  = needed / IntPtr.Size;
                        moduleHandles = new IntPtr[modulesCount];
                    }
                }

                var modules = new ProcessModuleCollection(firstModuleOnly ? 1 : modulesCount);

                char[] chars = ArrayPool <char> .Shared.Rent(1024);

                try
                {
                    for (int i = 0; i < modulesCount; i++)
                    {
                        if (i > 0)
                        {
                            // If the user is only interested in the main module, break now.
                            // This avoid some waste of time. In addition, if the application unloads a DLL
                            // we will not get an exception.
                            if (firstModuleOnly)
                            {
                                break;
                            }
                        }

                        IntPtr moduleHandle = moduleHandles[i];
                        Interop.Kernel32.NtModuleInfo ntModuleInfo;
                        if (!Interop.Kernel32.GetModuleInformation(processHandle, moduleHandle, out ntModuleInfo))
                        {
                            HandleLastWin32Error();
                            continue;
                        }

                        var module = new ProcessModule()
                        {
                            ModuleMemorySize  = ntModuleInfo.SizeOfImage,
                            EntryPointAddress = ntModuleInfo.EntryPoint,
                            BaseAddress       = ntModuleInfo.BaseOfDll
                        };

                        int length = Interop.Kernel32.GetModuleBaseName(processHandle, moduleHandle, chars, chars.Length);
                        if (length == 0)
                        {
                            HandleLastWin32Error();
                            continue;
                        }

                        module.ModuleName = new string(chars, 0, length);

                        length = Interop.Kernel32.GetModuleFileNameEx(processHandle, moduleHandle, chars, chars.Length);
                        if (length == 0)
                        {
                            HandleLastWin32Error();
                            continue;
                        }

                        module.FileName = (length >= 4 && chars[0] == '\\' && chars[1] == '\\' && chars[2] == '?' && chars[3] == '\\') ?
                                          new string(chars, 4, length - 4) :
                                          new string(chars, 0, length);

                        modules.Add(module);
                    }
                }
                finally
                {
                    ArrayPool <char> .Shared.Return(chars);
                }

                return(modules);
            }
            finally
            {
                if (!processHandle.IsInvalid)
                {
                    processHandle.Dispose();
                }
            }
        }
Beispiel #5
0
        private static ProcessModuleCollection GetModules(int processId, bool firstModuleOnly)
        {
            // preserving Everett behavior.
            if (processId == SystemProcessID || processId == IdleProcessID)
            {
                // system process and idle process doesn't have any modules
                throw new Win32Exception(Interop.Errors.EFail, SR.EnumProcessModuleFailed);
            }

            SafeProcessHandle processHandle = SafeProcessHandle.InvalidHandle;

            try
            {
                processHandle = ProcessManager.OpenProcess(processId, Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION | Interop.Advapi32.ProcessOptions.PROCESS_VM_READ, true);

                IntPtr[] moduleHandles            = new IntPtr[64];
                GCHandle moduleHandlesArrayHandle = new GCHandle();
                int      moduleCount = 0;
                for (;;)
                {
                    bool enumResult = false;
                    try
                    {
                        moduleHandlesArrayHandle = GCHandle.Alloc(moduleHandles, GCHandleType.Pinned);
                        enumResult = Interop.Kernel32.EnumProcessModules(processHandle, moduleHandlesArrayHandle.AddrOfPinnedObject(), moduleHandles.Length * IntPtr.Size, ref moduleCount);

                        // The API we need to use to enumerate process modules differs on two factors:
                        //   1) If our process is running in WOW64.
                        //   2) The bitness of the process we wish to introspect.
                        //
                        // If we are not running in WOW64 or we ARE in WOW64 but want to inspect a 32 bit process
                        // we can call psapi!EnumProcessModules.
                        //
                        // If we are running in WOW64 and we want to inspect the modules of a 64 bit process then
                        // psapi!EnumProcessModules will return false with ERROR_PARTIAL_COPY (299).  In this case we can't
                        // do the enumeration at all.  So we'll detect this case and bail out.
                        //
                        // Also, EnumProcessModules is not a reliable method to get the modules for a process.
                        // If OS loader is touching module information, this method might fail and copy part of the data.
                        // This is no easy solution to this problem. The only reliable way to fix this is to
                        // suspend all the threads in target process. Of course we don't want to do this in Process class.
                        // So we just to try avoid the race by calling the same method 50 (an arbitrary number) times.
                        //
                        if (!enumResult)
                        {
                            bool sourceProcessIsWow64     = false;
                            bool targetProcessIsWow64     = false;
                            SafeProcessHandle hCurProcess = SafeProcessHandle.InvalidHandle;
                            try
                            {
                                hCurProcess = ProcessManager.OpenProcess(unchecked ((int)Interop.Kernel32.GetCurrentProcessId()), Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION, true);
                                bool wow64Ret;

                                wow64Ret = Interop.Kernel32.IsWow64Process(hCurProcess, ref sourceProcessIsWow64);
                                if (!wow64Ret)
                                {
                                    throw new Win32Exception();
                                }

                                wow64Ret = Interop.Kernel32.IsWow64Process(processHandle, ref targetProcessIsWow64);
                                if (!wow64Ret)
                                {
                                    throw new Win32Exception();
                                }

                                if (sourceProcessIsWow64 && !targetProcessIsWow64)
                                {
                                    // Wow64 isn't going to allow this to happen, the best we can do is give a descriptive error to the user.
                                    throw new Win32Exception(Interop.Errors.ERROR_PARTIAL_COPY, SR.EnumProcessModuleFailedDueToWow);
                                }
                            }
                            finally
                            {
                                if (hCurProcess != SafeProcessHandle.InvalidHandle)
                                {
                                    hCurProcess.Dispose();
                                }
                            }

                            // If the failure wasn't due to Wow64, try again.
                            for (int i = 0; i < 50; i++)
                            {
                                enumResult = Interop.Kernel32.EnumProcessModules(processHandle, moduleHandlesArrayHandle.AddrOfPinnedObject(), moduleHandles.Length * IntPtr.Size, ref moduleCount);
                                if (enumResult)
                                {
                                    break;
                                }
                                Thread.Sleep(1);
                            }
                        }
                    }
                    finally
                    {
                        moduleHandlesArrayHandle.Free();
                    }

                    if (!enumResult)
                    {
                        throw new Win32Exception();
                    }

                    moduleCount /= IntPtr.Size;
                    if (moduleCount <= moduleHandles.Length)
                    {
                        break;
                    }
                    moduleHandles = new IntPtr[moduleHandles.Length * 2];
                }

                var modules = new ProcessModuleCollection(firstModuleOnly ? 1 : moduleCount);

                char[] chars = new char[1024];

                for (int i = 0; i < moduleCount; i++)
                {
                    if (i > 0)
                    {
                        // If the user is only interested in the main module, break now.
                        // This avoid some waste of time. In addition, if the application unloads a DLL
                        // we will not get an exception.
                        if (firstModuleOnly)
                        {
                            break;
                        }
                    }

                    IntPtr moduleHandle = moduleHandles[i];
                    Interop.Kernel32.NtModuleInfo ntModuleInfo;
                    if (!Interop.Kernel32.GetModuleInformation(processHandle, moduleHandle, out ntModuleInfo))
                    {
                        HandleError();
                        continue;
                    }

                    var module = new ProcessModule()
                    {
                        ModuleMemorySize  = ntModuleInfo.SizeOfImage,
                        EntryPointAddress = ntModuleInfo.EntryPoint,
                        BaseAddress       = ntModuleInfo.BaseOfDll
                    };

                    int length = Interop.Kernel32.GetModuleBaseName(processHandle, moduleHandle, chars, chars.Length);
                    if (length == 0)
                    {
                        HandleError();
                        continue;
                    }

                    module.ModuleName = new string(chars, 0, length);

                    length = Interop.Kernel32.GetModuleFileNameEx(processHandle, moduleHandle, chars, chars.Length);
                    if (length == 0)
                    {
                        HandleError();
                        continue;
                    }

                    module.FileName = (length >= 4 && chars[0] == '\\' && chars[1] == '\\' && chars[2] == '?' && chars[3] == '\\') ?
                                      new string(chars, 4, length - 4) :
                                      new string(chars, 0, length);

                    modules.Add(module);
                }

                return(modules);
            }
            finally
            {
                if (!processHandle.IsInvalid)
                {
                    processHandle.Dispose();
                }
            }
        }
Beispiel #6
0
        private static ModuleInfo[] GetModuleInfos(int processId, bool firstModuleOnly)
        {
            Contract.Ensures(Contract.Result <ModuleInfo[]>().Length >= 1);

            // preserving Everett behavior.
            if (processId == SystemProcessID || processId == IdleProcessID)
            {
                // system process and idle process doesn't have any modules
                throw new Win32Exception(Interop.EFail, SR.EnumProcessModuleFailed);
            }

            SafeProcessHandle processHandle = SafeProcessHandle.InvalidHandle;

            try
            {
                processHandle = ProcessManager.OpenProcess(processId, Interop.PROCESS_QUERY_INFORMATION | Interop.PROCESS_VM_READ, true);

                IntPtr[] moduleHandles            = new IntPtr[64];
                GCHandle moduleHandlesArrayHandle = new GCHandle();
                int      moduleCount = 0;
                for (; ;)
                {
                    bool enumResult = false;
                    try
                    {
                        moduleHandlesArrayHandle = GCHandle.Alloc(moduleHandles, GCHandleType.Pinned);
                        enumResult = Interop.mincore.EnumProcessModules(processHandle, moduleHandlesArrayHandle.AddrOfPinnedObject(), moduleHandles.Length * IntPtr.Size, ref moduleCount);

                        // The API we need to use to enumerate process modules differs on two factors:
                        //   1) If our process is running in WOW64.
                        //   2) The bitness of the process we wish to introspect.
                        //
                        // If we are not running in WOW64 or we ARE in WOW64 but want to inspect a 32 bit process
                        // we can call psapi!EnumProcessModules.
                        //
                        // If we are running in WOW64 and we want to inspect the modules of a 64 bit process then
                        // psapi!EnumProcessModules will return false with ERROR_PARTIAL_COPY (299).  In this case we can't
                        // do the enumeration at all.  So we'll detect this case and bail out.
                        //
                        // Also, EnumProcessModules is not a reliable method to get the modules for a process.
                        // If OS loader is touching module information, this method might fail and copy part of the data.
                        // This is no easy solution to this problem. The only reliable way to fix this is to
                        // suspend all the threads in target process. Of course we don't want to do this in Process class.
                        // So we just to try avoid the race by calling the same method 50 (an arbitary number) times.
                        //
                        if (!enumResult)
                        {
                            bool sourceProcessIsWow64     = false;
                            bool targetProcessIsWow64     = false;
                            SafeProcessHandle hCurProcess = SafeProcessHandle.InvalidHandle;
                            try
                            {
                                hCurProcess = ProcessManager.OpenProcess(unchecked ((int)Interop.mincore.GetCurrentProcessId()), Interop.PROCESS_QUERY_INFORMATION, true);
                                bool wow64Ret;

                                wow64Ret = Interop.mincore.IsWow64Process(hCurProcess, ref sourceProcessIsWow64);
                                if (!wow64Ret)
                                {
                                    throw new Win32Exception();
                                }

                                wow64Ret = Interop.mincore.IsWow64Process(processHandle, ref targetProcessIsWow64);
                                if (!wow64Ret)
                                {
                                    throw new Win32Exception();
                                }

                                if (sourceProcessIsWow64 && !targetProcessIsWow64)
                                {
                                    // Wow64 isn't going to allow this to happen, the best we can do is give a descriptive error to the user.
                                    throw new Win32Exception(Interop.ERROR_PARTIAL_COPY, SR.EnumProcessModuleFailedDueToWow);
                                }
                            }
                            finally
                            {
                                if (hCurProcess != SafeProcessHandle.InvalidHandle)
                                {
                                    hCurProcess.Dispose();
                                }
                            }

                            // If the failure wasn't due to Wow64, try again.
                            for (int i = 0; i < 50; i++)
                            {
                                enumResult = Interop.mincore.EnumProcessModules(processHandle, moduleHandlesArrayHandle.AddrOfPinnedObject(), moduleHandles.Length * IntPtr.Size, ref moduleCount);
                                if (enumResult)
                                {
                                    break;
                                }
                                Thread.Sleep(1);
                            }
                        }
                    }
                    finally
                    {
                        moduleHandlesArrayHandle.Free();
                    }

                    if (!enumResult)
                    {
                        throw new Win32Exception();
                    }

                    moduleCount /= IntPtr.Size;
                    if (moduleCount <= moduleHandles.Length)
                    {
                        break;
                    }
                    moduleHandles = new IntPtr[moduleHandles.Length * 2];
                }
                List <ModuleInfo> moduleInfos = new List <ModuleInfo>();

                int ret;
                for (int i = 0; i < moduleCount; i++)
                {
                    try
                    {
                        ModuleInfo           moduleInfo   = new ModuleInfo();
                        IntPtr               moduleHandle = moduleHandles[i];
                        Interop.NtModuleInfo ntModuleInfo = new Interop.NtModuleInfo();
                        if (!Interop.mincore.GetModuleInformation(processHandle, moduleHandle, ntModuleInfo, Marshal.SizeOf(ntModuleInfo)))
                        {
                            throw new Win32Exception();
                        }
                        moduleInfo._sizeOfImage = ntModuleInfo.SizeOfImage;
                        moduleInfo._entryPoint  = ntModuleInfo.EntryPoint;
                        moduleInfo._baseOfDll   = ntModuleInfo.BaseOfDll;

                        StringBuilder baseName = new StringBuilder(1024);
                        ret = Interop.mincore.GetModuleBaseName(processHandle, moduleHandle, baseName, baseName.Capacity * 2);
                        if (ret == 0)
                        {
                            throw new Win32Exception();
                        }
                        moduleInfo._baseName = baseName.ToString();

                        StringBuilder fileName = new StringBuilder(1024);
                        ret = Interop.mincore.GetModuleFileNameEx(processHandle, moduleHandle, fileName, fileName.Capacity * 2);
                        if (ret == 0)
                        {
                            throw new Win32Exception();
                        }
                        moduleInfo._fileName = fileName.ToString();

                        if (moduleInfo._fileName != null &&
                            moduleInfo._fileName.Length >= 4 &&
                            moduleInfo._fileName.StartsWith(@"\\?\", StringComparison.Ordinal))
                        {
                            moduleInfo._fileName = moduleInfo._fileName.Substring(4);
                        }

                        moduleInfos.Add(moduleInfo);
                    }
                    catch (Win32Exception e)
                    {
                        if (e.NativeErrorCode == Interop.ERROR_INVALID_HANDLE || e.NativeErrorCode == Interop.ERROR_PARTIAL_COPY)
                        {
                            // It's possible that another thread casued this module to become
                            // unloaded (e.g FreeLibrary was called on the module).  Ignore it and
                            // move on.
                        }
                        else
                        {
                            throw;
                        }
                    }

                    //
                    // If the user is only interested in the main module, break now.
                    // This avoid some waste of time. In addition, if the application unloads a DLL
                    // we will not get an exception.
                    //
                    if (firstModuleOnly)
                    {
                        break;
                    }
                }
                ModuleInfo[] temp = new ModuleInfo[moduleInfos.Count];
                moduleInfos.CopyTo(temp, 0);
                return(temp);
            }
            finally
            {
#if FEATURE_TRACESWITCH
                Debug.WriteLineIf(Process._processTracing.TraceVerbose, "Process - CloseHandle(process)");
#endif
                if (!processHandle.IsInvalid)
                {
                    processHandle.Dispose();
                }
            }
        }
Beispiel #7
0
        private static ModuleInfo[] GetModuleInfos(int processId, bool firstModuleOnly)
        {
            ModuleInfo[] infoArray2;
            if ((processId == SystemProcessID) || (processId == 0))
            {
                throw new Win32Exception(-2147467259, SR.GetString("EnumProcessModuleFailed"));
            }
            Microsoft.Win32.SafeHandles.SafeProcessHandle invalidHandle = Microsoft.Win32.SafeHandles.SafeProcessHandle.InvalidHandle;
            try
            {
                bool flag;
                invalidHandle = ProcessManager.OpenProcess(processId, 0x410, true);
                IntPtr[] ptrArray = new IntPtr[0x40];
                GCHandle handle2  = new GCHandle();
                int      needed   = 0;
Label_0045:
                flag = false;
                try
                {
                    handle2 = GCHandle.Alloc(ptrArray, GCHandleType.Pinned);
                    flag    = Microsoft.Win32.NativeMethods.EnumProcessModules(invalidHandle, handle2.AddrOfPinnedObject(), ptrArray.Length * IntPtr.Size, ref needed);
                    if (!flag)
                    {
                        bool flag2 = false;
                        bool flag3 = false;
                        if (!ProcessManager.IsOSOlderThanXP)
                        {
                            Microsoft.Win32.SafeHandles.SafeProcessHandle hProcess = Microsoft.Win32.SafeHandles.SafeProcessHandle.InvalidHandle;
                            try
                            {
                                hProcess = ProcessManager.OpenProcess(Microsoft.Win32.NativeMethods.GetCurrentProcessId(), 0x400, true);
                                if (!Microsoft.Win32.SafeNativeMethods.IsWow64Process(hProcess, ref flag2))
                                {
                                    throw new Win32Exception();
                                }
                                if (!Microsoft.Win32.SafeNativeMethods.IsWow64Process(invalidHandle, ref flag3))
                                {
                                    throw new Win32Exception();
                                }
                                if (flag2 && !flag3)
                                {
                                    throw new Win32Exception(0x12b, SR.GetString("EnumProcessModuleFailedDueToWow"));
                                }
                            }
                            finally
                            {
                                if (hProcess != Microsoft.Win32.SafeHandles.SafeProcessHandle.InvalidHandle)
                                {
                                    hProcess.Close();
                                }
                            }
                        }
                        for (int j = 0; j < 50; j++)
                        {
                            flag = Microsoft.Win32.NativeMethods.EnumProcessModules(invalidHandle, handle2.AddrOfPinnedObject(), ptrArray.Length * IntPtr.Size, ref needed);
                            if (flag)
                            {
                                goto Label_012F;
                            }
                            Thread.Sleep(1);
                        }
                    }
                }
                finally
                {
                    handle2.Free();
                }
Label_012F:
                if (!flag)
                {
                    throw new Win32Exception();
                }
                needed /= IntPtr.Size;
                if (needed > ptrArray.Length)
                {
                    ptrArray = new IntPtr[ptrArray.Length * 2];
                    goto Label_0045;
                }
                ArrayList list = new ArrayList();
                for (int i = 0; i < needed; i++)
                {
                    ModuleInfo info   = new ModuleInfo();
                    IntPtr     handle = ptrArray[i];
                    Microsoft.Win32.NativeMethods.NtModuleInfo ntModuleInfo = new Microsoft.Win32.NativeMethods.NtModuleInfo();
                    if (!Microsoft.Win32.NativeMethods.GetModuleInformation(invalidHandle, new HandleRef(null, handle), ntModuleInfo, Marshal.SizeOf(ntModuleInfo)))
                    {
                        throw new Win32Exception();
                    }
                    info.sizeOfImage = ntModuleInfo.SizeOfImage;
                    info.entryPoint  = ntModuleInfo.EntryPoint;
                    info.baseOfDll   = ntModuleInfo.BaseOfDll;
                    StringBuilder baseName = new StringBuilder(0x400);
                    if (Microsoft.Win32.NativeMethods.GetModuleBaseName(invalidHandle, new HandleRef(null, handle), baseName, baseName.Capacity * 2) == 0)
                    {
                        throw new Win32Exception();
                    }
                    info.baseName = baseName.ToString();
                    StringBuilder builder2 = new StringBuilder(0x400);
                    if (Microsoft.Win32.NativeMethods.GetModuleFileNameEx(invalidHandle, new HandleRef(null, handle), builder2, builder2.Capacity * 2) == 0)
                    {
                        throw new Win32Exception();
                    }
                    info.fileName = builder2.ToString();
                    if (string.Compare(info.fileName, @"\SystemRoot\System32\smss.exe", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        info.fileName = Path.Combine(Environment.SystemDirectory, "smss.exe");
                    }
                    if (((info.fileName != null) && (info.fileName.Length >= 4)) && info.fileName.StartsWith(@"\\?\", StringComparison.Ordinal))
                    {
                        info.fileName = info.fileName.Substring(4);
                    }
                    list.Add(info);
                    if (firstModuleOnly)
                    {
                        break;
                    }
                }
                ModuleInfo[] array = new ModuleInfo[list.Count];
                list.CopyTo(array, 0);
                infoArray2 = array;
            }
            finally
            {
                if (!invalidHandle.IsInvalid)
                {
                    invalidHandle.Close();
                }
            }
            return(infoArray2);
        }