win32中的CreateFile

CreateFile 方法详解(WinAPI)

CreateFile 是 Windows 系统中用于打开文件、设备、串口、管道、驱动设备等对象的核心函数。其函数原型如下:

HANDLE CreateFile(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

在 C# 中,它通常通过 P/Invoke 调用,如:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(
    string lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr lpSecurityAttributes,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    IntPtr hTemplateFile);

✅ 每个参数详解

参数名 类型 含义
lpFileName string 文件名或设备路径,例如 "\\.\xdma0_c2h_0" 表示 DMA 通道
dwDesiredAccess uint 访问权限,如 GENERIC_READ, GENERIC_WRITE
dwShareMode uint 共享模式,常为 0(独占访问)或 FILE_SHARE_READ
lpSecurityAttributes IntPtr 安全属性,一般为 IntPtr.Zero
dwCreationDisposition uint 创建方式,常用 OPEN_EXISTING 表示打开已存在的设备
dwFlagsAndAttributes uint 文件/设备属性,如 FILE_ATTRIBUTE_NORMALFILE_FLAG_OVERLAPPED
hTemplateFile IntPtr 模板句柄(复制属性),用于文件复制时,一般为 IntPtr.Zero

✅ 示例:打开 DMA 设备(推荐方式)

const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const uint OPEN_EXISTING = 3;
const uint FILE_ATTRIBUTE_NORMAL = 0x80;

SafeFileHandle handle = CreateFile(
    @"\\.\xdma0_c2h_0",     // DMA设备路径
    GENERIC_READ,           // 读取权限(C2H通道)
    0,                      // 不允许共享(独占)
    IntPtr.Zero,            // 默认安全属性
    OPEN_EXISTING,          // 打开已存在的设备
    FILE_ATTRIBUTE_NORMAL,  // 标准属性(不使用异步)
    IntPtr.Zero             // 模板句柄,未使用
);

✅ 参数选择注意事项(尤其用于 DMA)

参数 建议值 说明
dwDesiredAccess GENERIC_READGENERIC_WRITE 读取 C2H,写入 H2C
dwCreationDisposition OPEN_EXISTING 打开现有设备,不创建新文件
dwFlagsAndAttributes FILE_ATTRIBUTE_NORMAL 如果你不使用异步 I/O,必须省略 FILE_FLAG_OVERLAPPED,否则可能失败
dwShareMode 0(独占) 硬件驱动不建议多进程共享

⚠️ 常见错误原因

错误码 原因
ERROR_INVALID_PARAMETER (87) buffer 未对齐或句柄未正确打开
INVALID_HANDLE_VALUE CreateFile 参数错误,路径、权限或标志位有误
ERROR_ACCESS_DENIED (5) 权限不匹配,比如用 GENERIC_WRITE 打开只读设备

✅ Bonus:打开控制通道(寄存器操作)

var handle = CreateFile(
    @"\\.\xdma0_control",
    GENERIC_READ | GENERIC_WRITE,
    0,
    IntPtr.Zero,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    IntPtr.Zero);

posted @ 2025-06-23 10:52  青云Zeo  阅读(168)  评论(0)    收藏  举报