基本概念
CreateFile
是Windows
系统编程中最核心的API
函数之一,创建或打开文件或I/O
设备。 最常用的I/O
设备如下所示:文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道。 该函数返回一个句柄,该句柄可用于访问各种类型的I/O
的文件或设备,具体取决于文件或设备以及指定的标志和属性。
CreateFile 本身并非实际函数,而是一个条件编译宏,根据项目是否定义UNICODE
宏,自动映射到两个实际实现:
CreateFileW
:宽字符(Unicode/UTF-16)版本,接受LPCWSTR
类型路径,支持多语言(如中文)路径,是现代应用的推荐选择。
CreateFileA
:ANSI 版本,接受单字节字符串(LPCSTR),仅支持英文字符及有限扩展字符,已逐渐被淘汰。
语法
1 2 3 4 5 6 7 8 9
| HANDLE CreateFile( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
|
HANDLE定义:
1 2
| typedef void *HANDLE; void *:无类型指针;
|
HANDLE
(句柄),是 Windows 中用于标识系统资源的抽象符号,它是各种系统对象(文件、窗口、进程等)的“唯一标识”!在实际使用中,它不代表具体的内存地址,而是系统内核中资源表的索引或标识,所有对资源的操作(创建、读取、修改、释放)都必须通过句柄调用相应的API函数(如ReadFile 操作文件句柄、CloseHandle 释放资源)完成。
将HANDLE
定义为void *
(无类型指针):
通用性:void *
可指向任何类型的资源,让HANDLE
能统一标识各种系统对象(文件、窗口、进程等);
安全性:void *
不能直接解引用(无法直接修改指向的内存),确保用户无法绕过API
函数直接操作资源内部数据
API数据类型
在Windows API中,有一套由C语言原生类型(int、char等)通过typedef
或宏定义开发而来的标准化定义的数据类型(Windows是有C语言开发的),用于确保跨平台兼容性、明确数据长度和用途,并简化系统资源的操作。
我们在VS可以通过转到定义去查看他们的定义,

LPCWSTR定义:
1 2 3 4 5 6 7 8 9
| typedef _Null_terminated_ CONST WCHAR *LPCWSTR, *PCWSTR;
typedef 是 C/C++ 中的关键字,用于为已有的数据类型定义别名; _Null_terminated_:静态代码分析注解,这里该指针指向的字符串是以空字符(\0 或 L'\0')结尾的(即 C 风格字符串); CONST:用于表示 “常量”,这里表示指针指向的宽字符内容不可被修改(只读); WCHAR:Windows API 定义的宽字符类型,每个字符占用2字节(16 位),用于存储 Unicode 编码(UTF-16)的字符(支持中文、日文等多语言字符)。 CONST WCHAR * : “指向常量宽字符的指针” 总体而言: 指向以空字符结尾的常量宽字符(Unicode/UTF-16)字符串的指针” 定义了两个别名 LPCWSTR 和 PCWSTR。
|
DWORD定义:
1 2 3 4
| typedef unsigned long DWORD;
unsigned long: C语言原生的无符号长整数类型; DWORD 为4 字节(32 位)无符号整数。
|
LPSECURITY_ATTRIBUTES定义:
1 2 3 4 5 6 7 8 9 10 11 12 13
| typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; 成员 nLength(DWORD 类型):表示当前结构体的字节大小(以字节为单位); 成员 lpSecurityDescriptor(LPVOID 类型):安全描述符用于控制对象访问权限; LPVOID定义: typedef void far *LPVOID; 在现代 32/64 位系统中,far 关键字失效,LPVOID 等价于 void *,作为通用无类型指针使用。 成员 bInheritHandle(BOOL 类型):布尔值,指定通过该结构体创建的句柄(HANDLE)是否可被子进程继承。 总体而言: 定义一个用于描述 “对象安全权限” 和 “句柄继承性” 的结构体,并创建简洁的类型别名。
|
简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| HANDLE hFile = CreateFileW( L"C:\\test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile != INVALID_HANDLE_VALUE) { char buffer[1024]; DWORD bytesRead; ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL); CloseHandle(hFile); }
|
CreateFile2 与 CreateFile3
CreateFile2
Windows 8(及以上)引入的改进版本,通过结构体优化参数传递,增强扩展性:
1 2 3 4 5 6 7
| HANDLE CreateFile2( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, LPCREATEFILE2_EXTENDED_PARAMETERS lpCreateExParams );
|
LPCREATEFILE2_EXTENDED_PARAMETERS定义
1 2 3 4 5 6 7 8
| typedef struct _CREATEFILE2_EXTENDED_PARAMETERS { DWORD dwSize; DWORD dwFileAttributes; DWORD dwFileFlags; DWORD dwSecurityQosFlags; LPSECURITY_ATTRIBUTES lpSecurityAttributes; HANDLE hTemplateFile; } CREATEFILE2_EXTENDED_PARAMETERS, *PCREATEFILE2_EXTENDED_PARAMETERS, *LPCREATEFILE2_EXTENDED_PARAMETERS;
|
减少了直接参数数量,将扩展选项(如安全属性、文件属性、模板句柄等)封装到CREATEFILE2_EXTENDED_PARAMETERS结构体中;
结构体支持新增字段(如dwFileAttributes、hTemplateFile、lpSecurityAttributes等),扩展新功能;
CreateFile3
Windows 10 1709(及以上)引入的更新版本,在CreateFile2基础上进一步扩展;
1 2 3 4 5 6 7
| HANDLE CreateFile3( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, LPCREATEFILE3_EXTENDED_PARAMETERS pCreateExParams );
|
LPCREATEFILE3_EXTENDED_PARAMETERS定义
1 2 3 4 5 6 7 8
| typedef struct _CREATEFILE3_EXTENDED_PARAMETERS { DWORD dwSize; DWORD dwFileAttributes; DWORD dwFileFlags; DWORD dwSecurityQosFlags; LPSECURITY_ATTRIBUTES lpSecurityAttributes; HANDLE hTemplateFile; } CREATEFILE3_EXTENDED_PARAMETERS, *PCREATEFILE3_EXTENDED_PARAMETERS, *LPCREATEFILE3_EXTENDED_PARAMETERS;
|