具有从 C# 到非托管驱动程序的嵌入式指针的编组结构

2023-12-08

我正在尝试使用 P/Invoked DeviceIoControl() 调用将 C# (.NET Compact Framework 3.5) 与 Windows CE 6 R2 流驱动程序连接起来。对于 IOCTL 代码之一,驱动程序需要一个 DeviceIoControl 输入缓冲区,该缓冲区是以下包含嵌入指针的非托管结构:

typedef struct {
    DWORD address;
    const void* pBuffer;
    DWORD size; // buffer size
} IOCTL_TWL_WRITEREGS_IN;

我在 C# 中将结构体定义为:

[StructLayout(LayoutKind.Sequential)]
public struct IoctlWriteRegsIn
{
    public uint Address;
    public byte[] Buffer;
    public uint Size;
}

我的 P/Invoke 签名为:

[DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool DeviceIoControl(IntPtr hDevice,
                                    UInt32 dwIoControlCode,
                                    ref IoctlWriteRegsIn lpInBuffer,
                                    UInt32 nInBufferSize,
                                    UInt32[] lpOutBuffer,
                                    UInt32 nOutBufferSize,
                                    ref UInt32 lpBytesReturned,
                                    IntPtr lpOverlapped);

但是,每当我在 C# 中调用 DeviceIoControl() 时,它总是返回 false,最后一个 Win32 错误为ERROR_INVALID_PARAMETER。以下是驱动程序中 IOCTL switch 语句的源代码片段,用于处理 IOCTL 代码并对输入缓冲区进行错误检查,其中 inSize 是 nInBufferSize 参数:

    case IOCTL_TWL_WRITEREGS:
        if ((pInBuffer == NULL) || 
            (inSize < sizeof(IOCTL_TWL_WRITEREGS_IN)))
            {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
            }
        address = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->address;
        pBuffer = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->pBuffer;
        size = ((IOCTL_TWL_WRITEREGS_IN*)pInBuffer)->size;
        if (inSize < (sizeof(IOCTL_TWL_WRITEREGS_IN) + size))
            {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
            }
        rc = TWL_WriteRegs(context, address, pBuffer, size);

我尝试了应该通过驱动程序错误检查的硬编码大小,但没有成功,这表明这是一个编组问题。我可能没有正确定义 C# 结构中的嵌入指针,或者我的 P/Invoke 签名错误。有任何想法吗?

提前致谢, 本

作为参考,我可以从 C++ 与驱动程序对话,不会出现如下问题:

IOCTL_TWL_WRITEREGS_IN reg;
reg.address = 0x004B0014;
unsigned char data = 0xBE;
reg.pBuffer = &data;
reg.size = sizeof(char);

BOOL writeSuccess = DeviceIoControl(driver, IOCTL_TWL_WRITEREGS, &reg, sizeof(IOCTL_TWL_WRITEREGS_IN) + 1, NULL, 0, NULL, NULL);

更新:这就是有效的! 使用 JaredPar 的 IntPtr 建议并通过 SwDevMan81 的建议清理我的 P/Invoke 签名:

    [StructLayout(LayoutKind.Sequential)]
    public struct IoctlWriteRegsIn
    {
        public uint Address;
        public IntPtr Buffer;
        public uint Size;
    }

    // elided

    byte regData = 0xFF;
    GCHandle pin = GCHandle.Alloc(regData, GCHandleType.Pinned);
    IoctlWriteRegsIn writeInBuffer = new IoctlWriteRegsIn{Address = twlBackupRegA, Buffer = pin.AddrOfPinnedObject(), Size = 1};
    bool writeSuccess = DeviceIoControl(driverHandle, IoctlTwlWriteRegs, ref writeInBuffer, (uint) Marshal.SizeOf(writeInBuffer) + 1, IntPtr.Zero, 0, ref numBytesReturned, IntPtr.Zero);

    // P/Invoke signature
    [DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern bool DeviceIoControl(IntPtr hDevice,
                                        UInt32 dwIoControlCode,
                                        ref IoctlWriteRegsIn lpInBuffer,
                                        UInt32 nInBufferSize,
                                        IntPtr lpOutBuffer,
                                        UInt32 nOutBufferSize,
                                        ref UInt32 lpBytesReturned,
                                        IntPtr lpOverlapped);

当编组具有内联指针的结构时,您需要将值定义为 IntPtr 而不是数组

[StructLayout(LayoutKind.Sequential)]
public struct IoctlWriteRegsIn
{
    public uint Address;
    public IntPtr Buffer;
    public uint Size;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有从 C# 到非托管驱动程序的嵌入式指针的编组结构 的相关文章

  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • CharBuffer 位于内存映射的 ByteBuffer 之上,无需使用大量堆空间

    我正在编写一个java代码来在一个大的txt文件 6 8Gb 中搜索电子邮件地址和密码 我已经编写了代码 它可以处理 200Mb txt 文件并给出输出 但是当我输入 500Mb 文件时 它显示以下错误 Exception in threa
  • TensorFlow:“ValueError:没有为任何变量提供梯度”

    我正在张量流中实现 DeepMind 的 DQN 算法 并在我调用的线路上遇到此错误optimizer minimize self loss ValueError No gradients provided for any variable
  • PHP 表单 - 提交时停留在同一页面

    我有一个位于文件中的 PHP 表单contact html 该表格是从文件处理的processForm php 当用户填写表单并单击提交时 processForm php发送电子邮件并引导用户至 processForm php该页面上有一条
  • 将多个 IIS7 重写规则(重定向)合并为一个

    我使用iis7的URL重写模块来完成几件事 301重定向规则从非www到www 301 将规则 info 重定向到 com 已移至我的域的 com 版本 301 从旧页面重定向规则 例如 page name asp 改为 page name
  • Android Facebook 风格幻灯片

    新的 Facebook 应用程序及其导航非常酷 我只是想看看如何在我的应用程序中模拟它 任何人都知道如何实现它 单击左上角按钮后 页面会滑动并显示以下屏幕 Youtube 视频 我自己尝试过这个 我能找到的最好方法是使用 FrameLayo
  • 如何在 ruby​​mine 中停止/终止服务器(开发)

    这里是新手 我在 ruby mine 中创建了一个 Rails 项目来运行公共文件夹中的默认 index html 我按下了 shift F10 键 这与终端的 Rails 服务器相同 这就是我得到的 home bubble rvm rub
  • Java:转义 XML 文本内容而不是整个文本

    我想发送下面的 XML 请求 文本内容应该被转义 但标签不应该被转义 我试过了使用下面的转义逻辑 String str escapeXml11 req 然而 我的整个请求都被逃脱了 因此 它不再是有效的 XML 我原来的字符串 String
  • 在 Flexbox 中组合行和列

    我有三个元素article 照片 类别 然后是帖子信息 我试图弄清楚如何让类别元素堆叠在帖子信息列的顶部 2 在 3 的顶部 如果您正在查看所附照片 因此它看起来像两个 50 的列 即使有是三个弹性元素 flexbox display fl
  • 如何更改 gWidgets RGtk2 中鼠标光标的形状?

    在gWidgets中的ggraphics绘图区域中 将鼠标光标更改为 GDK TCROSS 但我想要与gwindow GDK LEFT PTR 相同的鼠标光标 library gWidgets library gWidgetsRGtk2 l
  • 球拍中的树形折叠

    我是 Racket 的初学者 我有这样的问题 定义一个结构 node 其中包含以下字段 value left middle right 该结构表示树结构中的节点 这些字段包含存储在节点 左子树中的值 分别为中子树和右子树 如果一个子树 不存
  • EntityFramework Core 自动迁移

    有没有代码可以实现自动迁移Entity Framework core code first在 asp net core 项目中 我只是在 MVC4 5 中添加 Database SetInitializer new MigrateDatab
  • Python 向量化嵌套 for 循环

    我希望能够帮助您找到和理解一种 Pythonic 方法来优化嵌套 for 循环中的以下数组操作 def func a b radius Return 0 if a gt b otherwise return 1 if distance eu
  • 在 Laravel Post 中授权资源控制器不起作用?

    我创建了一个 ProductPolicy 其中有
  • PHP:将表单中的值插入 MySQL

    我创建了一个users表中mysql从终端 我正在尝试创建简单的任务 从表单插入值 这是我的dbConfig file 这是我的Index php
  • Android Telegram 应用程序 --> java.lang.UnsatisfiedLinkError: 未找到 void 的实现

    不幸的是 几周前 Stackoverflow 上删除了一个类似的问题 我必须提出一个新问题 我正在尝试通过源 为Android构建一个自己的Telegram应用程序https github com DrKLO Telegram 我无法让它工
  • 如何使用选项字典关闭 Swift 中的 Core Data Write-Ahead 日志记录?

    如何使用 Apple 新编程语言 Swift 关闭 Core Data 中的 SQLite 预写日志记录 WAL 在 ObjC 中 我曾经在选项字典中传入键值对 journal mode DELETE storeCoordinator ad
  • 稀疏签出后过滤 git 提交历史记录

    git repo 下有几十个文件夹 但我只与其中之一合作 所以 我不想知道其他文件夹下的项目发生了什么 我从远程签出了一个启用了稀疏签出的分支 现在我本地只有一个文件夹 但使用 gitk 时我仍然可以看到完整的提交历史记录 我在交互式变基期
  • 如何处理.NET Winforms中的堆叠控件?

    我有一个表单 它将多个面板控件堆叠在一起 每个控件都根据表单上的其他选定选项显示 隐藏 在表单设计器中管理起来确实很痛苦 因为面板的行为不像完整的 TabControl 但是 您似乎无法在没有选项卡的情况下使用 TabControl 处理这
  • 使用 PDFBox 拆分大型 Pdf 文件会得到大型结果文件

    我正在使用 pdfbox 处理一些大型 pdf 文件 高达 100MB 大约 2000 页 有些页面包含二维码 我想将这些文件分割成更小的文件 页面从一个二维码到下一个二维码 我得到了这个 但结果文件大小与源文件相同 我的意思是 如果我将一
  • 具有从 C# 到非托管驱动程序的嵌入式指针的编组结构

    我正在尝试使用 P Invoked DeviceIoControl 调用将 C NET Compact Framework 3 5 与 Windows CE 6 R2 流驱动程序连接起来 对于 IOCTL 代码之一 驱动程序需要一个 Dev