1. VirtualProtectEx 函数
更改指定进程的虚拟地址空间中已提交页面区域的保护。(修改内存值)
(1)语法
BOOL VirtualProtectEx(
[in] HANDLE hProcess,
[in] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flNewProtect,
[out] PDWORD lpflOldProtect
);
(2)参数
[in] hProcess
要更改其内存保护的进程句柄。 句柄必须具有 PROCESS_VM_OPERATION 访问权限。 有关详细信息,请参阅 进程安全和访问权限。
[in] lpAddress
指向要更改其访问保护属性的页区域的基址的指针。
指定区域中的所有页面都必须在使用 MEM_RESERVE 调用 VirtualAlloc 或 VirtualAllocEx 函数时分配 的同一保留区域。 这些页面不能跨通过单独调用 VirtualAlloc 或 VirtualAllocEx(使用 MEM_RESERVE)分配的相邻保留区域。
[in] dwSize
访问保护属性已更改的区域的大小(以字节为单位)。 受影响页面的区域包括从 _lpAddress_ 参数到 (lpAddress+dwSize)
的范围中包含一个或多个字节的所有页面。 这意味着跨页边界的 2 字节范围会导致两个页面的保护属性发生更改。
[in] flNewProtect
内存保护选项。 此参数可以是 内存保护常量之一。
对于映射视图,此值必须与映射视图时指定的访问保护兼容 (请参阅 MapViewOfFile、 MapViewOfFileEx 和 MapViewOfFileExNuma) 。
[out] lpflOldProtect
指向变量的指针,该变量接收指定页区域中第一页的先前访问保护。 如果此参数为 NULL 或未指向有效的变量,则该函数将失败。
(3)返回值
如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。
(4)注解
只能在提交的页面上设置访问保护值。 如果未提交指定区域中任何页面的状态,则函数将失败并返回 ,而不会修改指定区域中任何页面的访问保护。
PAGE_GUARD保护修饰符建立保护页。 保护页充当一次性访问警报。 有关更多信息,请参见创建保护页。
最好避免使用 VirtualProtectEx 更改 GlobalAlloc、HeapAlloc 或 LocalAlloc 分配的内存块上的[](https://learn.microsoft.com/zh-cn/windows/win32/api/heapapi/nf-heapapi-heapalloc)页面保护,因为单个页面上[](https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-localalloc)可能有多个内存块。 堆管理器假定堆中的所有页面至少授予读取和写入访问权限。
保护可执行的区域时,调用程序负责在代码设置到位后通过适当调用 FlushInstructionCache 来确保缓存一致性。 否则,尝试在新可执行区域之外执行代码可能会产生不可预知的结果。
(5)DLL
Kernel32.dll
2.WriteProcessMemory函数
将数据写入到指定进程中的内存区域。 要写入的整个区域必须可访问,否则操作将失败。
(1)语法
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
(2)参数
[in] hProcess
要修改的进程内存的句柄。 句柄必须具有对进程的PROCESS_VM_WRITE和PROCESS_VM_OPERATION访问权限。
[in] lpBaseAddress
指向将数据写入到的指定进程中基址的指针。 在进行数据传输之前,系统会验证指定大小的基址和内存中的所有数据是否可供写入访问,如果无法访问,则函数将失败。
[in] lpBuffer
指向缓冲区的指针,该缓冲区包含要写入指定进程的地址空间中的数据。
[in] nSize
要写入指定进程的字节数。
[out] lpNumberOfBytesWritten
指向变量的指针,该变量接收传输到指定进程的字节数。 此参数是可选的。 如果 _lpNumberOfBytesWritten_ 为 NULL,则忽略参数。
(3)返回值
如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为 0(零)。 要获得更多的错误信息,请调用 GetLastError。 如果请求的写入操作交叉到无法访问的进程区域,函数将失败。
(4)注解
WriteProcessMemory 将数据从当前进程中的指定缓冲区复制到指定进程的地址范围。 任何具有 PROCESS_VM_WRITE 句柄且PROCESS_VM_OPERATION访问要写入的进程的进程都可以调用 函数。 通常(但并非总是)正在调试包含正在写入的地址空间的进程。
要写入到的整个区域必须可访问,如果无法访问,则函数将失败。
(5)DLL
Kernel32.dll
3.GetCurrentProcessId 方法
返回当前进程的引擎进程 ID(获取当前进程一个唯一的标识符(句柄))
4. openProcess 函数
打开现有的本地进程对象,并返回句柄。
(1)语法
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
(2)参数
[in] dwDesiredAccess
对进程对象的访问。 根据进程的安全描述符检查此访问权限。 此参数可以是一个或多个 进程访问权限。
如果调用方已启用 SeDebugPrivilege 特权,则无论安全描述符的内容如何,都会授予请求的访问权限。
[in] bInheritHandle
如果此值为 TRUE,则此进程创建的进程将继承句柄。 否则,进程不会继承此句柄。
[in] dwProcessId
要打开的本地进程的标识符。
如果指定的进程是系统空闲进程 (0x00000000) ,则函数将失败,最后一个错误代码为 ERROR_INVALID_PARAMETER
。 如果指定的进程是系统进程或客户端服务器 Run-Time 子系统 (CSRSS) 进程之一,则此函数将失败,最后一个错误代码是 ERROR_ACCESS_DENIED
因为它们的访问限制阻止用户级代码打开它们。
如果使用 GetCurrentProcessId 作为此函数的参数,请考虑使用 GetCurrentProcess 而不是 OpenProcess 来提高性能。
(3)返回值
如果函数成功,则返回值是指定进程的打开句柄。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
(4)注解
若要打开另一个本地进程的句柄并获取完全访问权限,必须启用 SeDebugPrivilege 特权。 有关详细信息,请参阅 更改令牌中的特权。
OpenProcess 函数返回的句柄可用于需要进程句柄的任何函数(如 wait 函数),前提是请求了适当的访问权限。
完成句柄后,请务必使用 CloseHandle 函数将其关闭。
(5)DLL
Kernel32.dll
5.LoadLibraryA函数
将指定的模块加载到调用进程的地址空间中。(加载指定动态链接库,返回DLL模块句柄)
指定的模块可能会导致加载其他模块。
有关其他加载选项,请使用 LoadLibraryEx 函数。
(1)语法
HMODULE LoadLibraryA(
[in] LPCSTR lpLibFileName
);
(2)参数
[in] lpLibFileName
模块的名称。 可以是库模块 (.dll 文件) ,也可以是可执行模块 (.exe 文件) 。 如果指定的模块是可执行模块,则不会加载静态导入;相反,模块就像由 LoadLibraryEx 使用 标志一 DONT_RESOLVE_DLL_REFERENCES
样加载。
指定的名称是模块的文件名,与库模块本身中存储的名称无关,由 module-definition (.def) 文件中的 LIBRARY 关键字 (keyword) 指定。
如果字符串指定完整路径,则函数仅搜索模块的该路径。
如果字符串指定相对路径或模块名称而不指定路径,则函数使用标准搜索策略来查找模块;有关详细信息,请参阅备注。
如果函数找不到模块,则函数将失败。 指定路径时,请确保使用反斜杠 () ,而不是 (/) 正斜杠。 有关路径的详细信息,请参阅 命名文件或目录。
如果字符串指定模块名称而不指定路径,并且省略了文件扩展名,则函数会将默认库扩展名“.DLL”追加到模块名称。 若要防止函数将“.DLL”追加到模块名称,请在模块名称字符串中包含尾随点字符 (.) 。
(3)返回值
如果函数成功,则返回值是模块的句柄。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
(4)注解
若要启用或禁用加载程序在 DLL 加载期间显示的错误消息,请使用 SetErrorMode 函数。
LoadLibrary 可用于将库模块加载到进程的地址空间中,并返回一个句柄,该句柄可用于 在 GetProcAddress 中 获取 DLL 函数的地址。 LoadLibrary 还可用于加载其他可执行模块。 例如,函数可以指定 .exe 文件以获取可在 FindResource 或 LoadResource 中使用的句柄。 但是,请勿使用 LoadLibrary 运行 .exe 文件。 请改用 CreateProcess 函数。
如果指定的模块是尚未为调用进程加载的 DLL,则系统会使用DLL_PROCESS_ATTACH值调用 DLL 的 DllMain 函数。 如果 DllMain 返回 TRUE, 则 LoadLibrary 将返回模块的句柄。 如果 DllMain 返回 FALSE,则系统会从进程地址空间中卸载 DLL, 而 LoadLibrary 返回 NULL。 从 DllMain 调用 LoadLibrary 是不安全的。 有关详细信息,请参阅 DllMain 中的“备注”部分。
模块句柄不是全局句柄,也不是可继承的。 一个进程调用 LoadLibrary 不会生成另一个进程可以使用的句柄,例如,在调用 GetProcAddress 时。 在调用 GetProcAddress 之前,另一个进程必须自行调用模块的 LoadLibrary。
如果 _lpFileName_ 不包含路径,并且有多个具有相同基名称和扩展名的已加载模块,则函数将返回首先加载的模块的句柄。
如果未在 _lpFileName_ 参数中指定文件扩展名,则会追加默认库扩展名 .dll。 但是,文件名字符串可以包含尾随点字符 (.) 以指示模块名称没有扩展名。 如果未指定路径,函数将搜索其基名称与要加载的模块的基名称匹配的已加载模块。 如果名称匹配,则加载成功。 否则,函数将搜索 文件。
搜索的第一个目录是包含用于创建调用进程 (的图像文件的目录,有关详细信息,请参阅 CreateProcess 函数) 。 这样做可以在不将进程的已安装目录添加到 PATH 环境变量的情况下,找到与进程关联的专用动态链接库 (DLL) 文件。 如果指定了相对路径,则整个相对路径将追加到 DLL 搜索路径列表中的每个标记。 若要从相对路径加载模块而不搜索任何其他路径,请使用 GetFullPathName 获取非关系路径,并使用非关系路径调用 LoadLibrary 。 有关 DLL 搜索顺序的详细信息,请参阅 动态链接库搜索顺序。
可以使用 SetDllDirectory 函数更改搜索路径。 建议使用此解决方案,而不是使用 SetCurrentDirectory 或硬编码 DLL 的完整路径。
如果指定了路径,并且应用程序有重定向文件,则函数在应用程序的目录中搜索模块。 如果模块存在于应用程序的目录中, 则 LoadLibrary 将忽略指定的路径,并从应用程序的目录中加载该模块。 如果应用程序的目录中不存在模块, 则 LoadLibrary 从指定的目录加载模块。 有关详细信息,请参阅 动态链接库重定向。
如果使用程序集的名称调用 LoadLibrary ,但没有路径规范,并且程序集列在系统兼容清单中,则调用会自动重定向到并行程序集。
系统在所有加载的模块上维护每进程引用计数。 调用 LoadLibrary 会递增引用计数。 调用 FreeLibrary 或 FreeLibraryAndExitThread 函数会减少引用计数。 当模块的引用计数达到零或进程终止时,无论引用计数) 如何,系统都会卸载模块 (。
Windows Server 2003 和 Windows XP: Visual C++ 编译器支持用于声明线程局部变量的语法: _declspec (线程) 。 如果在 DLL 中使用此语法,将无法在 Windows Vista 之前的 Windows 版本上使用 LoadLibrary 显式加载 DLL。 如果 DLL 将被显式加载,则必须使用线程本地存储函数,而不是 _declspec (线程) 。 有关示例,请参阅 在动态链接库中使用线程本地存储。
(5)DLL
Kernel32.dll
6. WriteFile 函数
将数据写入指定的文件或输入/输出 (I/O) 设备。
此函数设计用于同步和异步操作。 有关专为异步操作设计的类似函数,请参阅 WriteFileEx。
(1)语法
BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
(2)参数
[in] hFile
文件或 I/O 设备的句柄 (例如文件、文件流、物理磁盘、卷、控制台缓冲区、磁带驱动器、套接字、通信资源、mailslot 或管道) 。
必须已创建具有写入访问权限的 _hFile_ 参数。 有关详细信息,请参阅 通用访问权限 和 文件安全性和访问权限。
对于异步写入操作,_hFile_ 可以是使用 FILE_FLAG_OVERLAPPED 标志的 CreateFile 函数打开的任何句柄,也可以是套接字或 accept 函数返回的套接字句柄。
[in] lpBuffer
指向缓冲区的指针,该缓冲区包含要写入文件或设备的数据。
此缓冲区必须在写入操作期间保持有效。 在完成写入操作之前,调用方不得使用此缓冲区。
[in] nNumberOfBytesToWrite
要写入文件或设备的字节数。
值为零指定 null 写入操作。 null 写入操作的行为取决于基础文件系统或通信技术。
Windows Server 2003 和 Windows XP: 网络上的管道写入操作在每次写入的大小方面受到限制。 金额因平台而异。 对于 x86 平台,为 63.97 MB。 对于 x64 平台,为 31.97 MB。 对于 Itanium,为 63.95 MB。 有关管道的详细信息,请参阅“备注”部分。
[out, optional] lpNumberOfBytesWritten
指向变量的指针,该变量接收使用同步 _hFile_ 参数时写入的字节数。 WriteFile 在执行任何工作或错误检查之前将此值设置为零。 如果这是异步操作,请对此参数使用 NULL ,以避免潜在的错误结果。
仅当 _lpOverlapped_ 参数不为 NULL 时,此参数才能为 NULL。
Windows 7: 此参数不能为 NULL。
有关详细信息,请参见“备注”部分。
[in, out, optional] lpOverlapped
如果使用 FILE_FLAG_OVERLAPPED 打开 _hFile_ 参数,则需要指向 OVERLAPPED 结构的指针,否则此参数可以为 NULL。
对于支持字节偏移量的 _hFile_ ,如果使用此参数,则必须指定开始写入文件或设备的字节偏移量。 此偏移量是通过设置 OVERLAPPED 结构的 Offset 和 OffsetHigh 成员指定的。 对于不支持字节偏移量的 _hFile_ , 将忽略 Offset 和 OffsetHigh 。
若要写入文件末尾,请将 OVERLAPPED 结构的 Offset 和 OffsetHigh 成员指定为0xFFFFFFFF。 这在功能上等效于之前调用 CreateFile 函数以使用FILE_APPEND_DATA访问打开 _hFile_。
有关 _lpOverlapped_ 和 FILE_FLAG_OVERLAPPED的不同组合的详细信息,请参阅“备注”部分和 “同步和文件位置” 部分。
(3)返回值
如果函数成功,则返回值为非零 (TRUE) 。
如果函数失败或正在异步完成,则返回值为零 (FALSE) 。 若要获得更多的错误信息,请调用 GetLastError 函数。
注意GetLastError 代码ERROR_IO_PENDING不是失败;它指定写入操作正在异步等待完成。 有关详细信息,请参阅“备注”。
(4)注解
发生以下情况之一时, WriteFile 函数将返回 :
- 写入请求的字节数。
- 如果写入被阻止) ,读取操作会释放管道 (读取端的缓冲区空间。 有关详细信息,请参阅 管道 部分。
- 正在使用异步句柄,并且写入正在异步进行。
- 发生错误。
每当存在过多的未完成异步 I/O 请求时, WriteFile 函数可能会失败并出现 ERROR_INVALID_USER_BUFFER 或 ERROR_NOT_ENOUGH_MEMORY 。
若要取消所有挂起的异步 I/O 操作,请使用以下任一函数:
- CancelIo - 此函数仅取消由指定文件句柄的调用线程发出的操作。
- CancelIoEx - 此函数取消由指定文件句柄的线程发出的所有操作。
使用 CancelSynchronousIo 函数取消挂起的同步 I/O 操作。
取消的 I/O 操作已完成, ERROR_OPERATION_ABORTED错误。
WriteFile 函数可能会失败并ERROR_NOT_ENOUGH_QUOTA,这意味着调用进程的缓冲区无法锁定页。 有关详细信息,请参阅 SetProcessWorkingSetSize。
如果文件的一部分被另一个进程锁定,并且写入操作与锁定部分重叠, WriteFile 将失败。
写入文件时,在关闭用于写入的所有句柄之前,最后一次写入时间不会完全更新。 因此,若要确保准确的上次写入时间,请在写入文件后立即关闭文件句柄。
在写入操作使用缓冲区时访问输出缓冲区可能会导致从该缓冲区写入的数据损坏。 在写入操作完成之前,应用程序不得写入、重新分配或释放写入操作正在使用的输出缓冲区。 使用异步文件句柄时,这可能会特别出现问题。 稍后可在同步 和文件位置 部分以及 同步和异步 I/O 中找到有关同步文件句柄与异步文件句柄的其他信息。
请注意,可能无法为远程文件正确更新时间戳。 若要确保结果一致,请使用无缓冲区 I/O。
系统将要写入的零个字节解释为指定 null 写入操作, WriteFile 不会截断或扩展文件。 若要截断或扩展文件,请使用 SetEndOfFile 函数。
可以使用具有控制台输出句柄的 WriteFile 将字符写入屏幕缓冲区。 函数的确切行为由控制台模式确定。 数据将写入当前光标位置。 光标位置在写入操作后更新。 有关控制台句柄的详细信息,请参阅 CreateFile。
写入通信设备时,WriteFile 的行为由当前通信超时确定,该超时是使用 SetCommTimeouts 和 GetCommTimeouts 函数设置和检索的。[](https://learn.microsoft.com/zh-cn/windows/desktop/api/winbase/nf-winbase-getcommtimeouts) 如果未能设置超时值,可能会出现不可预知的结果。 有关通信超时的详细信息,请参阅 COMMTIMEOUTS。
尽管单扇区写入是原子性的,但不能保证多扇区写入是原子的,除非使用事务 (即创建的句柄是事务处理句柄;例如,使用 CreateFileTransacted) 创建的句柄。 缓存的多扇区写入可能不会始终立即写入磁盘;因此,请在 CreateFile 中指定FILE_FLAG_WRITE_THROUGH,以确保将整个多扇区写入磁盘,而不会造成潜在的缓存延迟。
如果直接写入具有已装载文件系统的卷,则必须先获取该卷的独占访问权限。 否则,可能会导致数据损坏或系统不稳定,因为应用程序的写入操作可能与来自文件系统的其他更改冲突,并使卷的内容处于不一致状态。 为防止这些问题,Windows Vista 及更高版本中进行了以下更改:
如果卷没有装载的文件系统,或者满足以下条件之一,则对卷句柄的写入将成功:
- 要写入的扇区是启动扇区。
- 要写入的扇区驻留在文件系统空间之外。
- 已使用 FSCTL_LOCK_VOLUME 或 FSCTL_DISMOUNT_VOLUME 显式锁定或卸载卷。
- 该卷没有实际的文件系统。 (换句话说,它具有 RAW 文件系统 mounted.)
如果满足以下条件之一,则磁盘句柄上的写入将成功:
- 要写入的扇区不在卷的范围内。
- 要写入的扇区位于已装载卷内,但已使用 FSCTL_LOCK_VOLUME 或 FSCTL_DISMOUNT_VOLUME 显式锁定或卸载卷。
- 要写入到的扇区位于没有除 RAW 以外的已装载文件系统的卷内。
使用 FILE_FLAG_NO_BUFFERING 成功处理使用 CreateFile 打开的文件有严格的要求。 有关详细信息,请参阅 文件缓冲。
如果使用 FILE_FLAG_OVERLAPPED 打开 _hFile_,则以下条件有效:
- _lpOverlapped_ 参数必须指向有效且唯一的 OVERLAPPED 结构,否则函数可能会错误地报告写入操作已完成。
- _lpNumberOfBytesWritten_ 参数应设置为 NULL。 若要获取写入的字节数,请使用 GetOverlappedResult 函数。 如果 _hFile_ 参数与 I/O 完成端口相关联,则还可以通过调用 GetQueuedCompletionStatus 函数来获取写入的字节数。
在 Windows Server 2012 中,以下技术支持此功能。
(5)DLL
Kernel32.dll
7.CreateFileA函数
创建或者打开文件或 I/O 设备。 最常用的 I/O 设备如下:文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道。 函数返回一个句柄,该句柄可用于访问各种类型的 I/O 的文件或设备,具体取决于文件或设备以及指定的标志和属性。
若要以事务处理操作的形式执行此操作,这会生成可用于事务处理 I/O 的句柄,请使用 CreateFileTransacted 函数。
(1)语法
HANDLE CreateFileA(
[in] LPCSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);
(2)参数
[in] lpFileName
要创建或打开的文件或设备的名称。 可在此名称中使用正斜杠 (/) 或反斜杠 () 。
默认情况下,名称限制为MAX_PATH个字符。 若要将此限制扩展到 32,767 个宽字符,请在路径前面添加“\?\”。 有关详细信息,请参阅命名文件、路径和命名空间。
提示
从 Windows 10 版本 1607 开始,可以选择删除MAX_PATH限制,而无需在前面添加“\?\”。 有关详细信息,请参阅 命名文件、路径和命名空间 的“最大路径长度限制”部分。
有关特殊设备名称的信息,请参阅 定义 MS-DOS 设备名称。
若要创建文件流,请指定文件的名称、冒号,然后指定流的名称。 有关详细信息,请参阅 文件流。
[in] dwDesiredAccess
请求对文件或设备的访问权限,可以汇总为读取、写入或 0,以指示两者都不) 。
最常用的值是 GENERIC_READ、 GENERIC_WRITE或两者 (GENERIC_READ | GENERIC_WRITE
) 。 有关详细信息,请参阅 通用访问权限、 文件安全性和访问权限、 文件访问权限常量和 ACCESS_MASK。
如果此参数为零,则应用程序可以在不访问该文件或设备的情况下查询某些元数据(如文件、目录或设备属性),即使 GENERIC_READ 访问被拒绝也是如此。
不能请求与已打开句柄的打开请求中的 _dwShareMode_ 参数指定的共享模式冲突的访问模式。
有关详细信息,请参阅本主题的“备注”部分和 “创建和打开文件”。
[in] dwShareMode
请求的文件或设备的共享模式(可读取、写入、删除、所有这些共享模式或无 (请参阅下表) 。 对属性或扩展属性的访问请求不受此标志的影响。
如果此参数为零且 CreateFile 成功,则在关闭文件或设备的句柄之前,无法共享文件或设备,并且无法再次打开。 有关详细信息,请参见“备注”部分。
不能请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。 CreateFile 将失败, GetLastError 函数将返回 ERROR_SHARING_VIOLATION。
若要使某个进程能够在另一个进程打开文件或设备时共享文件或设备,请使用以下一个或多个值的兼容组合。 有关此参数与 _dwDesiredAccess_ 参数的有效组合的详细信息,请参阅 创建和打开文件。
注意 每个打开的句柄的共享选项一直有效,直到该句柄关闭,而不考虑进程上下文。
Expand table
值 | 含义 |
---|---|
0 0x00000000 | 阻止其他进程在请求删除、读取或写入访问权限时打开文件或设备。 |
FILE_SHARE_DELETE 0x00000004 | 启用文件或设备上的后续打开操作以请求删除访问权限。 否则,如果其他进程请求删除访问权限,则无法打开文件或设备。 如果未指定此标志,但已打开文件或设备进行删除访问,则函数将失败。 注意 删除访问权限允许删除和重命名操作。 |
FILE_SHARE_READ 0x00000001 | 启用文件或设备上的后续打开操作以请求读取访问权限。 否则,如果其他进程请求读取访问权限,则无法打开文件或设备。 如果未指定此标志,但已打开文件或设备进行读取访问,则函数将失败。 |
FILE_SHARE_WRITE 0x00000002 | 启用文件或设备上的后续打开操作以请求写入访问权限。 否则,如果其他进程请求写入访问权限,则无法打开文件或设备。 如果未指定此标志,但文件或设备已打开进行写入访问,或者具有具有写入访问权限的文件映射,则函数将失败。 |
[in, optional] lpSecurityAttributes
指向 SECURITY_ATTRIBUTES) 结构的指针,该结构包含两个独立但相关的数据成员:可选的安全描述符,以及一个布尔值,用于确定是否可由子进程继承返回的句柄。
此参数可以为 NULL。
如果此参数为 NULL,则应用程序可能创建的任何子进程都不能继承 CreateFile 返回的句柄,并且与返回的句柄关联的文件或设备将获取默认安全描述符。
结构的 lpSecurityDescriptor 成员指定文件或设备的 SECURITY_DESCRIPTOR 。 如果此成员为 NULL,则会为与返回的句柄关联的文件或设备分配默认安全描述符。
CreateFile 在打开现有文件或设备时忽略 lpSecurityDescriptor 成员,但仍继续使用 bInheritHandle 成员。
结构的 bInheritHandle 成员指定是否可以继承返回的句柄。
有关详细信息,请参见“备注”部分。
[in] dwCreationDisposition
要对存在或不存在的文件或设备执行的操作。
对于文件以外的设备,此参数通常设置为 OPEN_EXISTING。
有关详细信息,请参见“备注”部分。
此参数必须是下列值之一,这些值不能合并:
Expand table
值 | 含义 |
---|---|
CREATE_ALWAYS 2 | 始终创建新文件。 如果指定的文件存在且可写,则函数将截断文件,函数成功,最后错误代码设置为 ERROR_ALREADY_EXISTS (183) 。 如果指定的文件不存在并且是有效路径,则创建新文件,函数成功,最后一个错误代码设置为零。 有关详细信息,请参阅本主题的“备注”部分。 |
CREATE_NEW 1 | 仅当文件尚不存在时,才创建新文件。 如果指定的文件存在,则函数将失败,最后一个错误代码设置为 ERROR_FILE_EXISTS (80) 。 如果指定的文件不存在,并且是可写位置的有效路径,则会创建一个新文件。 |
OPEN_ALWAYS 4 | 始终打开文件。 如果指定的文件存在,则函数成功,并将最后一个错误代码设置为 ERROR_ALREADY_EXISTS (183) 。 如果指定的文件不存在,并且是可写位置的有效路径,则函数将创建一个文件,并将最后一个错误代码设置为零。 |
OPEN_EXISTING 3 | 仅当文件或设备存在时才打开它。 如果指定的文件或设备不存在,则函数将失败,并将最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2) 。 有关设备的详细信息,请参阅“备注”部分。 |
TRUNCATE_EXISTING 5 | 打开一个文件并截断它,使其大小为零字节,仅当它存在时。 如果指定的文件不存在,则函数将失败,最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2) 。 调用进程必须打开文件,并将 GENERIC_WRITE 位设置为 _dwDesiredAccess_ 参数的一部分。 |
[in] dwFlagsAndAttributes
文件或设备属性和标志 FILE_ATTRIBUTE_NORMAL 是文件最常见的默认值。
此参数可以包含可用文件属性的任意组合 (FILE_ATTRIBUTE_*) 。 所有其他文件属性都替代 FILE_ATTRIBUTE_NORMAL。
此参数还可以包含用于控制文件或设备缓存行为、访问模式和其他特殊用途标志的标志 (FILE_FLAG_) 的组合。 这些值与任何 FILE_ATTRIBUTE_ 值结合使用。
此参数还可以通过指定 SECURITY_SQOS_PRESENT 标志来包含安全服务质量 (SQOS ) 信息。 属性和标志表后面的表中显示了与 SQOS 相关的其他标志信息。
注意当 CreateFile 打开现有文件时,它通常会将文件标志与现有文件的文件属性组合在一起,并忽略作为 _dwFlagsAndAttributes_ 的一部分提供的任何文件属性。 创建和打开文件中详细介绍了特殊情况。
以下某些文件属性和标志可能仅适用于文件,不一定适用于 CreateFile 可以打开的所有其他类型的设备。 有关其他信息,请参阅本主题的“备注”部分和 创建和打开文件。
有关对文件属性的更高级访问,请参阅 SetFileAttributes。 有关所有文件属性及其值和说明的完整列表,请参阅 文件属性常量。
Expand table
Attribute | 含义 |
---|---|
FILE_ATTRIBUTE_ARCHIVE 32 (0x20) | 文件应存档。 应用程序使用此属性来标记要备份或删除的文件。 |
FILE_ATTRIBUTE_ENCRYPTED 16384 (0x4000) | 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录,这意味着加密是新创建的文件和子目录的默认设置。 有关详细信息,请参阅 文件加密。 如果还指定 了FILE_ATTRIBUTE_SYSTEM ,则此标志无效。 家庭版、家庭高级版、初学者版或 ARM 版本的 Windows 不支持此标志。 |
FILE_ATTRIBUTE_HIDDEN 2 (0x2) | 文件被隐藏。 不要将其包含在普通目录列表中。 |
FILE_ATTRIBUTE_NORMAL 128 (0x80) | 该文件未设置其他属性。 此属性仅在单独使用时有效。 |
FILE_ATTRIBUTE_OFFLINE 4096 (0x1000) | 文件的数据不会立即可用。 此属性指示文件数据以物理方式移动到脱机存储。 远程存储(分层存储管理软件)使用此属性。 应用程序不应随意更改此属性。 |
FILE_ATTRIBUTE_READONLY 1 (0x1) | 文件为只读文件。 应用程序可以读取文件,但不能写入或删除它。 |
FILE_ATTRIBUTE_SYSTEM 4 (0x4) | 该文件是操作系统的一部分或由操作系统独占使用。 |
FILE_ATTRIBUTE_TEMPORARY 256 (0x100) | 该文件用于临时存储。 有关详细信息,请参阅本主题的 缓存行为 部分。 |
Expand table
标志 | 含义 |
---|---|
FILE_FLAG_BACKUP_SEMANTICS 0x02000000 | 正在为备份或还原操作打开或创建文件。 当进程具有 SE_BACKUP_NAME 和 SE_RESTORE_NAME 权限时,系统将确保调用进程替代文件安全检查。 有关详细信息,请参阅 更改令牌中的特权。 必须设置此标志才能获取目录的句柄。 目录句柄可以传递给某些函数,而不是文件句柄。 有关详细信息,请参见“备注”部分。 |
FILE_FLAG_DELETE_ON_CLOSE 0x04000000 | 文件在其所有句柄都关闭后立即被删除,其中包括指定的句柄和任何其他打开或重复的句柄。 如果存在文件的现有打开句柄,则调用会失败,除非它们都以 FILE_SHARE_DELETE 共享模式打开。 针对文件的后续打开请求将失败,除非指定 FILE_SHARE_DELETE 共享模式。 |
FILE_FLAG_NO_BUFFERING 0x20000000 | 正在打开文件或设备,没有系统缓存用于数据读取和写入。 此标志不会影响硬盘缓存或内存映射文件。 使用 FILE_FLAG_NO_BUFFERING 标志成功处理使用 CreateFile 打开的文件有严格的要求,有关详细信息,请参阅文件缓冲。 |
FILE_FLAG_OPEN_NO_RECALL 0x00100000 | 文件数据已请求,但应继续位于远程存储中。 不应将其传输回本地存储。 此标志供远程存储系统使用。 |
FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 | 不会进行正常的 重分析点 处理; CreateFile 将尝试打开重新分析点。 打开文件时,无论控制重分析点的筛选器是否正常运行,都返回文件句柄。 此标志不能与 CREATE_ALWAYS 标志一起使用。 如果文件不是重分析点,则忽略此标志。 有关详细信息,请参见“备注”部分。 |
FILE_FLAG_OVERLAPPED 0x40000000 | 正在为异步 I/O 打开或创建文件或设备。 在此句柄上完成后续 I/O 操作时, OVERLAPPED 结构中指定的事件将设置为信号状态。 如果指定了此标志,则文件可用于同时读取和写入操作。 如果未指定此标志,则 I/O 操作将序列化,即使对读取和写入函数的调用指定 了 OVERLAPPED 结构也是如此。 有关使用此标志创建的文件句柄时的注意事项的信息,请参阅本主题的 同步和异步 I/O 句柄 部分。 |
FILE_FLAG_POSIX_SEMANTICS 0x01000000 | 将根据 POSIX 规则进行访问。 这包括允许多个具有名称的文件(仅在大小写上不同)用于支持该命名的文件系统。 使用此选项时请小心,因为为 MS-DOS 或 16 位 Windows 编写的应用程序可能无法访问使用此标志创建的文件。 |
FILE_FLAG_RANDOM_ACCESS 0x10000000 | 访问应是随机的。 系统可将此选项用作优化文件缓存的提示。 如果文件系统不支持缓存的 I/O 且 FILE_FLAG_NO_BUFFERING,则此标志无效。 有关详细信息,请参阅本主题的 缓存行为 部分。 |
FILE_FLAG_SESSION_AWARE 0x00800000 | 正在使用会话感知打开文件或设备。 如果未指定此标志,则会话 0 中运行的进程无法打开每个会话 (设备,例如使用 RemoteFX USB 重定向) 的设备。 此标志对不在会话 0 中的调用方无效。 此标志仅在服务器版本的 Windows 上受支持。 Windows Server 2008 R2 和 Windows Server 2008: 在Windows Server 2012之前,不支持此标志。 |
FILE_FLAG_SEQUENTIAL_SCAN 0x08000000 | 访问旨在从头到尾按顺序进行。 系统可将此选项用作优化文件缓存的提示。 如果读取隐藏 (即使用反向扫描) ,则不应使用此标志。 如果文件系统不支持缓存的 I/O 且 FILE_FLAG_NO_BUFFERING,则此标志无效。 有关详细信息,请参阅本主题的 缓存行为 部分。 |
FILE_FLAG_WRITE_THROUGH 0x80000000 | 写入操作不会通过任何中间缓存,它们将直接转到磁盘。 有关其他信息,请参阅本主题的 缓存行为 部分。 |
_dwFlagsAndAttributes_ 参数还可以指定 SQOS 信息。 有关详细信息,请参阅 模拟级别。 当调用应用程序将 SECURITY_SQOS_PRESENT 标志指定为 _dwFlagsAndAttributes_ 的一部分时,它还可以包含以下一个或多个值。
Expand table
安全标志 | 含义 |
---|---|
SECURITY_ANONYMOUS | 在匿名模拟级别模拟客户端。 |
SECURITY_CONTEXT_TRACKING | 安全跟踪模式是动态的。 如果未指定此标志,则安全跟踪模式为静态。 |
SECURITY_DELEGATION | 在委派模拟级别模拟客户端。 |
SECURITY_EFFECTIVE_ONLY | 服务器只能使用客户端安全上下文中已启用的方面。 如果未指定此标志,则客户端安全上下文的所有方面都可用。 这允许客户端限制服务器在模拟客户端时可以使用的组和权限。 |
SECURITY_IDENTIFICATION | 在标识模拟级别模拟客户端。 |
SECURITY_IMPERSONATION | 在模拟级别模拟客户端。 如果未将其他标志与 SECURITY_SQOS_PRESENT 标志一起指定,则这是默认行为。 |
[in, optional] hTemplateFile
具有 GENERIC_READ 访问权限的模板文件的有效句柄。 模板文件为正在创建的文件提供文件属性和扩展属性。
此参数可以为 NULL。
打开现有文件时, CreateFile 将忽略此参数。
打开新的加密文件时,该文件会从其父目录继承自由访问控制列表。 有关详细信息,请参阅 文件加密。
(3)返回值
如果函数成功,则返回值是指定文件、设备、命名管道或邮件槽的打开句柄。
如果函数失败,则返回值为 INVALID_HANDLE_VALUE。 要获得更多的错误信息,请调用 GetLastError。
(4)DLL
kernel32.dll