"尝试读取或写入受保护的内存"由urlmon.dll引起

时间:2014-09-26 13:12:26

标签: c# iis urlmon

我知道这已被多次询问但不幸的是我找不到解决我的问题的方法,我正在使用urlmon.dll从字节数组中找到MIME类型但我收到了IIS的崩溃流程w3wp.exe

  

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

代码:

public static int MimeSampleSize = 256;

public static string DefaultMimeType = "application/octet-stream";

[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
private extern static uint FindMimeFromData(
    uint pBC,
    [MarshalAs(UnmanagedType.LPStr)] string pwzUrl,
    [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
    uint cbSize,
    [MarshalAs(UnmanagedType.LPStr)] string pwzMimeProposed,
    uint dwMimeFlags,
    out uint ppwzMimeOut,
    uint dwReserverd
);

public static string GetMimeFromBytes(byte[] data)
{
    try
    {
        uint mimeType;
        FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0);

        var mimePointer = new IntPtr(mimeType);
        var mime = Marshal.PtrToStringUni(mimePointer); // <-- Crash happens here
        Marshal.FreeCoTaskMem(mimePointer);

        return mime ?? DefaultMimeType;
    }
    catch
    {
        return DefaultMimeType;
    }
}

崩溃恰好发生在以下一行:

var mime = Marshal.PtrToStringUni(mimePointer);

我试图取消选中“Suppress JIT optimization on module load”选项但没有运气。 还试图将构建更改为x86,而不是任何运气,而不是任何运行。

注意:我正在使用4.5框架,IIS 8

1 个答案:

答案 0 :(得分:2)

我认为问题是FindMimeFromData()的签名。在PInvoke.net上查看函数的正确签名:

http://www.pinvoke.net/default.aspx/urlmon/findmimefromdata.html

..所以不需要为pBC和ppwzMimeOut提供uint,你需要IntPtr!

另见:

urlmon.dll FindMimeFromData() works perfectly on 64bit desktop/console but generates errors on ASP.NET