EnumResourceNames 问题 - 未知错误

发布于 2024-10-13 12:06:00 字数 931 浏览 1 评论 0原文

我最近正在使用辅助库/二进制模块中的资源,并遇到了一个奇怪的错误。

我有两个本机 WinAPI 引用:

[DllImport("kernel32.dll", SetLastError = true)]
public extern static bool EnumResourceNames(IntPtr hModule, int lpszType, EnumResNameProc lpEnumFunc, IntPtr lParam);

[DllImport("kernel32.dll", SetLastError=true)]
public extern static IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, int dwFlags);

当我调用 LoadLibraryEx 时,我得到 IntPtr 实例 - 正是我所需要的:

IntPtr x = WinApi.LoadLibraryEx(@"D:\Software\Reflector\Reflector.exe",IntPtr.Zero,2);
Debug.WriteLine(x.ToInt32());

但是,当我尝试枚举图标资源(由 ID = 3 定义)时:

Debug.WriteLine(WinApi.EnumResourceNames(x, 3, new EnumResNameProc(ListCallback), IntPtr.Zero));
Debug.WriteLine(Marshal.GetLastWin32Error());

我收到此错误代码(返回by GetLastError):

-532462766

据我所知,这通常意味着存在未知错误,但我只是很好奇 - 从可执行文件中列出资源可能会出现什么问题?

I was recently working with resources from secondary libraries/binary modules and encountered a strange error.

I have two native WinAPI references:

[DllImport("kernel32.dll", SetLastError = true)]
public extern static bool EnumResourceNames(IntPtr hModule, int lpszType, EnumResNameProc lpEnumFunc, IntPtr lParam);

[DllImport("kernel32.dll", SetLastError=true)]
public extern static IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, int dwFlags);

When I call LoadLibraryEx, I am getting the IntPtr instance - just what I need:

IntPtr x = WinApi.LoadLibraryEx(@"D:\Software\Reflector\Reflector.exe",IntPtr.Zero,2);
Debug.WriteLine(x.ToInt32());

However, when I try to enumerate icon resources (defined by the ID = 3):

Debug.WriteLine(WinApi.EnumResourceNames(x, 3, new EnumResNameProc(ListCallback), IntPtr.Zero));
Debug.WriteLine(Marshal.GetLastWin32Error());

I am getting this error code (returned by GetLastError):

-532462766

This usually means there is an unknown error, as far as I know, but I am just curious - what could be the problem with listing resources from the executable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奶气 2024-10-20 12:06:00

-532462766 == 0xe0434352。最后三个十六进制对拼写为“CCR”,这是 Microsoft 程序员用来尝试得出易于识别的异常代码的常见技巧。确切的含义非常神秘,除了它通常与托管代码相关联之外,并且似乎在子系统中处于非常低的级别,通常不会无法产生有意义的托管异常。

对于这个神秘的异常有一个很好的候选原因,您的 EnumResources pinvoke 声明是错误的。第二个参数是 IntPtr,而不是 int。这有可能在 64 位操作系统上大受欢迎。

如果您弄清楚 CCR 的含义,请回复。


using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics;

class Program {
    static void Main(string[] args) {
        try {
            IntPtr module = LoadLibraryEx(@"C:\windows\system32\user32.dll", IntPtr.Zero, 2);
            if (module == IntPtr.Zero) throw new Win32Exception();
            if (!EnumResourceNames(module, (IntPtr)3, new EnumResNameProc(ListCallback), IntPtr.Zero))
                throw new Win32Exception();
        }
        catch (Win32Exception ex) {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }

    static bool ListCallback(IntPtr hModule, IntPtr type, IntPtr name, IntPtr lp) {
        long idorname = (long)name;
        if (idorname >> 16 == 0) Console.WriteLine("#{0}", idorname);
        else Console.WriteLine(Marshal.PtrToStringAnsi(name));
        return true;
    }

    public delegate bool EnumResNameProc(IntPtr hModule, IntPtr type, IntPtr name, IntPtr lp);
    [DllImport("kernel32.dll", SetLastError = true)]
    public extern static bool EnumResourceNames(IntPtr hModule, IntPtr type, EnumResNameProc lpEnumFunc, IntPtr lParam);
    [DllImport("kernel32.dll", SetLastError = true)]
    public extern static IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, int dwFlags);
}

-532462766 == 0xe0434352. The last three hex pairs spell "CCR", a common trick that Microsoft programmers use to try to come up with an easily recognizable exception code. The exact meaning is quite mysterious, beyond it being commonly associated with managed code and seemingly being very low level in a sub-system that doesn't normally fail to produce a meaningful managed exception.

There is an excellent candidate reason for that mysterious exception, your EnumResources pinvoke declaration is wrong. The 2nd argument is IntPtr, not int. That has some odds of going kaboom on a 64-bit operating system.

Please post back if you ever figure out what CCR means.


using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics;

class Program {
    static void Main(string[] args) {
        try {
            IntPtr module = LoadLibraryEx(@"C:\windows\system32\user32.dll", IntPtr.Zero, 2);
            if (module == IntPtr.Zero) throw new Win32Exception();
            if (!EnumResourceNames(module, (IntPtr)3, new EnumResNameProc(ListCallback), IntPtr.Zero))
                throw new Win32Exception();
        }
        catch (Win32Exception ex) {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }

    static bool ListCallback(IntPtr hModule, IntPtr type, IntPtr name, IntPtr lp) {
        long idorname = (long)name;
        if (idorname >> 16 == 0) Console.WriteLine("#{0}", idorname);
        else Console.WriteLine(Marshal.PtrToStringAnsi(name));
        return true;
    }

    public delegate bool EnumResNameProc(IntPtr hModule, IntPtr type, IntPtr name, IntPtr lp);
    [DllImport("kernel32.dll", SetLastError = true)]
    public extern static bool EnumResourceNames(IntPtr hModule, IntPtr type, EnumResNameProc lpEnumFunc, IntPtr lParam);
    [DllImport("kernel32.dll", SetLastError = true)]
    public extern static IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, int dwFlags);
}
终遇你 2024-10-20 12:06:00

Hans Passant 的说法是正确的,但为了详细说明错误消息,0xe0434352 是 .NET 异常的通用错误代码。如果从 Visual Studio 调试器运行此命令,您将看到当 EnumResourceNames 尝试调用回调时引发 System.ArgumentException。错误信息是:

作为字符串传入的指针不得位于进程地址空间的底部 64K。

此异常被 EnumResourceNames 捕获并变成失败。正如 Hans 所示,解决方案是回调函数必须将第二个和第三个参数作为 IntPtr 而不是字符串。

Hans Passant has it correct, but to elaborate on the error message, 0xe0434352 is the generic error code for a .NET exception. If you run this from the Visual Studio debugger you'll see that a System.ArgumentException is being raised when EnumResourceNames tries to invoke the callback. The error message is:

The pointer passed in as a String must not be in the bottom 64K of the process's address space.

This exception gets caught by EnumResourceNames and turns into a failure. The solution, as Hans showed, is that the callback function must take the second and third parameters as IntPtr rather than string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文