Пример #1
0
        private static string GetModuleFileName(IntPtr handle)
        {
            char[] buffer = null;

            // Try increased buffer sizes if on longpath-enabled Windows
            for (int bufferSize = NativeMethodsShared.MAX_PATH; bufferSize <= NativeMethodsShared.MaxPath; bufferSize *= 2)
            {
                buffer = System.Buffers.ArrayPool <char> .Shared.Rent(bufferSize);

                try
                {
                    var handleRef  = new System.Runtime.InteropServices.HandleRef(buffer, handle);
                    int pathLength = NativeMethodsShared.GetModuleFileName(handleRef, buffer, bufferSize);

                    bool isBufferTooSmall = (uint)Marshal.GetLastWin32Error() == NativeMethodsShared.ERROR_INSUFFICIENT_BUFFER;
                    if (pathLength != 0 && !isBufferTooSmall)
                    {
                        return(new string(buffer, 0, pathLength));
                    }
                }
                finally
                {
                    System.Buffers.ArrayPool <char> .Shared.Return(buffer);
                }

                // Double check that the buffer is not insanely big
                ErrorUtilities.VerifyThrow(bufferSize <= int.MaxValue / 2, "Buffer size approaching int.MaxValue");
            }

            return(string.Empty);
        }
Пример #2
0
        private static string GetModuleFileName(IntPtr handle)
        {
            bool success = false;
            var  buffer  = new StringBuilder();

            // Try increased buffer sizes if on longpath-enabled Windows
            for (int bufferSize = NativeMethodsShared.MAX_PATH; !success && bufferSize <= NativeMethodsShared.MaxPath; bufferSize *= 2)
            {
                buffer.EnsureCapacity(bufferSize);

                var handleRef  = new System.Runtime.InteropServices.HandleRef(buffer, handle);
                int pathLength = NativeMethodsShared.GetModuleFileName(handleRef, buffer, buffer.Capacity);

                bool isBufferTooSmall = ((uint)Marshal.GetLastWin32Error() == NativeMethodsShared.ERROR_INSUFFICIENT_BUFFER);
                success = pathLength != 0 && !isBufferTooSmall;
            }

            return(success ? buffer.ToString() : string.Empty);
        }
Пример #3
0
        /// <summary>
        /// Strips type library number from a type library path (for example, "ref.dll\2" becomes "ref.dll")
        /// </summary>
        /// <param name="typeLibPath">type library path with possible typelib number appended to it</param>
        /// <returns>proper file path to the type library</returns>
        internal static string StripTypeLibNumberFromPath(string typeLibPath, FileExists fileExists)
        {
            bool lastChance = false;

            if (typeLibPath != null && typeLibPath.Length > 0)
            {
                if (!fileExists(typeLibPath))
                {
                    // Strip the type library number
                    int lastSlash = typeLibPath.LastIndexOf('\\');

                    if (lastSlash != -1)
                    {
                        bool allNumbers = true;

                        for (int i = lastSlash + 1; i < typeLibPath.Length; i++)
                        {
                            if (!Char.IsDigit(typeLibPath[i]))
                            {
                                allNumbers = false;
                                break;
                            }
                        }

                        // If we had all numbers past the last slash then we're OK to strip
                        // the type library number
                        if (allNumbers)
                        {
                            typeLibPath = typeLibPath.Substring(0, lastSlash);
                            if (!fileExists(typeLibPath))
                            {
                                lastChance = true;
                            }
                        }
                        else
                        {
                            lastChance = true;
                        }
                    }
                    else
                    {
                        lastChance = true;
                    }
                }
            }

            // If we couldn't find the path directly, we'll use the same mechanism Windows uses to find
            // libraries.  LoadLibrary() will search all of the correct paths to find this module.  We can then
            // use GetModuleFileName() to determine the actual path from which the module was loaded.  This problem
            // was exposed in Vista where certain libraries are registered but are lacking paths in the registry,
            // so the old code would fail to find them on disk using the simplistic checks above.
            if (lastChance)
            {
                IntPtr libraryHandle = NativeMethodsShared.LoadLibrary(typeLibPath);
                if (IntPtr.Zero != libraryHandle)
                {
                    try
                    {
                        StringBuilder sb = new StringBuilder(NativeMethodsShared.MAX_PATH);
                        System.Runtime.InteropServices.HandleRef handleRef = new System.Runtime.InteropServices.HandleRef(sb, libraryHandle);
                        int len = NativeMethodsShared.GetModuleFileName(handleRef, sb, sb.Capacity);
                        if ((len != 0) &&
                            ((uint)Marshal.GetLastWin32Error() != NativeMethodsShared.ERROR_INSUFFICIENT_BUFFER))
                        {
                            typeLibPath = sb.ToString();
                        }
                        else
                        {
                            typeLibPath = "";
                        }
                    }
                    finally
                    {
                        NativeMethodsShared.FreeLibrary(libraryHandle);
                    }
                }
                else
                {
                    typeLibPath = "";
                }
            }

            return(typeLibPath);
        }