asp.net-mvcmimeunmanagedapplication-poolurlmon

Application pool crashes with URLMoniker urlmon.dll during MIME type checking


My application is ASP.NET MVC website deployed on Windows Server 2012 R2. I am using built-in Windows library URLMoniker - urlmon.dll to get MIME type of a file. I am passing its file path to GetMimeType method. Problem i am facing is, when I debug it using Visual Studio, it returns the mime type of that file (in my testing case, for a txt file, it returns "application/octet-stream"). But after deployment on production server, the application pool crashes unexpectedly and there are no logs in log file, it took me 3 days to get down to this code block (with help of additional log entries).

    private string GetMimeType(string filePath)
    {
        log.Info("Getting mime type for " + filePath);

        byte[] buffer = new byte[256];
        using (FileStream fs = new FileStream(filePath, FileMode.Open))
        {
            if (fs.Length >= 256)
                fs.Read(buffer, 0, 256);
            else
                fs.Read(buffer, 0, (int)fs.Length);
        }
        log.Info("Done reading into byte array for " + filePath);
        try
        {
            System.UInt32 mimetype;
            FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
            System.IntPtr mimeTypePtr = new IntPtr(mimetype);
            string mime = Marshal.PtrToStringUni(mimeTypePtr);
            Marshal.FreeCoTaskMem(mimeTypePtr);
            log.Info("Got mime type for " + filePath + " " + mime);
            return mime;
        }
        catch (Exception e)
        {
            log.Error("Cannot get mime type for file " + filePath, e);
            return "unknown/unknown";
        }
    }

Even the event viewer does not show any reason for app pool crash except this: A process serving application pool "SampleApp" suffered a fatal communication error with Windows Process Activation Service. The process id is 'yyyy'.

After doing detail research as much as I could find, i have following articles that might provide some solution but I still can't find the exact cause of this problem.

  1. https://www.experts-exchange.com/questions/24821266/Marshal-FreeCoTaskMem-crashing-application-in-x64-but-not-x86.html

  2. This one here also faced similar problem : https://superuser.com/questions/568806/iis-worker-process-crashing-without-stack-trace-what-else-can-i-try

  3. It says urlmon.dll might not be registered on system but I have checked in windows registry and it is registered. In fact that library is latest and I need to find root cause before applying any registry changes on production server. Replacing dll with new version, fixing registry issues is my last resort. https://answers.microsoft.com/en-us/ie/forum/ie8-windows_7/urlmondll-causing-many-programs-to-crash/cda9a6cb-cf51-499c-8855-45c97110eafe

  4. https://social.technet.microsoft.com/Forums/windows/en-US/c3f1517b-a8c5-422e-9317-2f539715badc/ie11-x64-on-win7-crash-ntdlldll-urlmondll?forum=w7itprohardware


Solution

  • Your problem is declaration of "FindMimeFromData" method ! it works fine some where and it cause iis process crashes some where else. Take a look at: https://stackoverflow.com/a/18554243/4257500 You need to change declaration of "FindMimeFromData" as :

    [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]static extern int FindMimeFromData(IntPtr pBC,
    [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
    [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] 
    byte[] pBuffer,
    int cbSize,
    [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
    int dwMimeFlags,
    out IntPtr ppwzMimeOut,
    int dwReserved);
    

    and also you should make some changes to call this function. for example:

     IntPtr mimeTypePtr;
     FindMimeFromData(IntPtr.Zero, null,file, 256, null, 0,out mimeTypePtr, 0);
     var mime = Marshal.PtrToStringUni(mimeTypePtr);