鱼C论坛

 找回密码
 立即注册
查看: 5926|回复: 0

[API档案] CreateFileTransacted

[复制链接]
发表于 2016-7-27 22:00:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
注:本文档由 vcvycy 翻译,小甲鱼校对。

原文链接 -> 传送门

函数功能:

【微软强烈建议开发人员利用替代的手段来实现您的应用程序的需求。很多情况下,TxF 的开发可以通过更简单和更容易获得的技术实现。此外,TxF 可能无法在微软 Windows 的未来版本中使用。更多信息和替代 TxF,请参见 Alternatives to using Transactional NTFS

CreateFileTransacted 函数用于以事务性操作创建或者打开一个文件、文件流或者文件夹。此函数返回一个可以用于访问此对象的句柄。

为了将此操作实现为非事务性操作,或者想要访问对象而非访问文件(例如命名管道、物理设备、邮槽),请调用 CreateFile 函数。

想了解更多关于事务性操作的信息,请参见备注。


API 函数原型:

注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选的
  1. HANDLE WINAPI CreateFileTransacted(
  2.   _In_       LPCTSTR               lpFileName,
  3.   _In_       DWORD                 dwDesiredAccess,
  4.   _In_       DWORD                 dwShareMode,
  5.   _In_opt_   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  6.   _In_       DWORD                 dwCreationDisposition,
  7.   _In_       DWORD                 dwFlagsAndAttributes,
  8.   _In_opt_   HANDLE                hTemplateFile,
  9.   _In_       HANDLE                hTransaction,
  10.   _In_opt_   PUSHORT               pusMiniVersion,
  11.   _Reserved_ PVOID                 pExtendedParameter
  12. );
复制代码


参数解析:

参数 含义
lpFileName1. 想创建或者打开的对象的名字

2. 此对象必须保存在本地计算机;否则,此函数执行失败,且 last error 代码被设置为 ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE

3. 此函数的 ANSI 版本中,对象名的长度被限制不大于 MAX_PATH 个字符。为了拓展到 32767 个宽字符,请调用此函数的 Unicode 版本,且在路径名中添加前缀 "\\?\"。更多信息,见 Naming a File。有关特殊设备的名字,见 Defining an MS-DOS Device Name

4. 如果想创建一个文件流,要先指定文件名,其后是一个冒号,然后添加流文件名字。更多信息,见 File Streams
dwDesiredAccess1. 对象访问权限,可以被归纳为读、写、读写或者非读非写。最常用的值为 GENERIC_READ,GENERIC_WRITE 或(GENERIC_READ | GENERIC_WRITE)。更多新建,见 Generic Access RightsFile Security and Access Rights

2. 如果此参数为 0,则程序在不访问文件或者设备的情况下,询问文件、文件夹或者设备的属性。更多信息,见备注

3. 你无法请求一种与共享模式(指定的拥有打开句柄的打开请求)相冲突的访问模式,更多信息,见 Creating and Opening Files
dwShareMode1. 对象的共享模式,包括读、写、读写、删除、所有权限或者不共享

2. 如果此参数为 0 且 CreateFileTransacted 函数执行成功,则此对象无法被共享,且在其句柄被关闭之前,无法被再次打开。更多信息,参见备注

3. 你无法请求一个与访问权限相冲突的共享模式,因为这会导致以下的共享冲突:ERROR_SHARING_VIOLATION。更多信息,见 Creating and Opening Files

4. 在某个进程已经打开一个对象时,为了使另一个进程共享此对象,你可以使用以下值中的一个或多个设置打开此对象所需的权限

5. 注意:对于每一个句柄来说,共享模式直到此句柄被关闭之后才会失效,而与进程上下文无关。

含义
0
(0x00000000)
防止其他进程以删除、读取或写入权限打开一个文件或者设备
FILE_SHARE_DELETE
(0x00000004)
1. 允许随后的对文件或设备的打开操作获取删除权限

2. 否则,其他进程无法以删除权限打开一个文件或设备

3. 如果此标记位没有指定,但文件或设备已经打开并且获取了删除权限,则此函数执行失败

4. 注意:删除权限运行删除操作和重命名操作
FILE_SHARE_READ
(0x00000001)
1. 允许后续对文件或设备的读权限打开请求

2. 否则,其他进程无法以读权限打开此文件

3. 如果此处标记位未被指定,但是文件或设备被以读权限打开,则函数执行失败
FILE_SHARE_WRITE
(0x00000002)
1. 允许后续对文件或设备的写权限打开请求

2. 否则,其他进程无法以写权限打开此文件

3. 如果此标记位未被设置,但是文件或设备被以写权限被打开或者有一个拥有写权限的文件映射,则函数执行失败
lpSecurityAttributes1. 指向 SECURITY_ATTRIBUTES 结构体的指针。此结构体拥有两个分开但是相关的数据成员:一个是可选的安全描述符,另一个是决定返回的句柄是否可以被子进程继承的 Boolean 值

2. 此参数可以设置为 NULL

3. 如果参数为 NULL,那么 CreateFileTransacted 函数返回的句柄无法被任意此进程的子进程所继承,且与返回的句柄所对应的文件或句柄拥有一个默认的安全描述符

4. 该结构体的 lpSecurityDescriptor 成员为文件或设备指定一个安全描述符(SECURITY_DESCRIPTOR)。如果此成员取值为 NULL,那么与返回的句柄所对应的文件或句柄拥有一个默认的安全描述符

5. 结构体的 bInheritHandle 成员用于设置返回的句柄是否可以被继承

6. 结构体的 lpSecurityDescriptor 成员指定了对象的安全描述符,可以为 NULL

7. 如果 lpSecurityDescriptor 成员为NULL,则与返回的句柄关联的句柄被设置以默认的安全描述符

8. 当打开一个已经存在的文件时,CreateFileTransacted 函数忽略 lpSecurityDescriptor 成员,但 bInheritHandle 成员仍然起作用

9. 更多信息,见备注
dwCreationDisposition1. 此参数用于设置在文件存在或不存在时所要采取的操作

2. 更多信息,参见本文备注

3. 这个参数的值必须为以下值之一,且只能选择一个而不能组合多个:

含义
CREATE_ALWAYS(2)1. 总是创建一个新文件

2. 如果指定的文件已经存在而且是可写的,此时函数重写(overwrite)这个文件,函数为执行成功、且将 last-error code 设置为 ERROR_ALREADY_EXISTS(183)

3. 如果指定的文件不存在且其路径名合法,那么会创建一个新文件,函数为执行成功、且将 last-error code 设为 0

4. 更多信息,参见本文备注
CREATE_NEW(1)1. 仅当文件不存在时,才创建一个新文件

2. 如果指定文件已存在,函数执行失败且将 last-error code 设为 ERROR_FILE_EXISTS(80)

3. 如果指定文件不存在,当路径名合法而且可写时,则创建一个新文件
OPEN_ALWAYS(4)1. 总是打开一个文件

2. 如果指定的文件存在,函数执行成功,且 last-error code 设置为 ERROR_ALREADY_EXISTS(183)

3. 如果指定文件不存在,当路径名合法而且可写时,则创建一个新文件,last-error code 设置为 0
OPEN_EXISTING(3)1. 仅当文件或设备存在时,才打开它

2. 如果指定的文件或设备不存在,函数执行失败且 last-error code 设置为 ERROR_FILE_NOT_FOUND(2)

3. 更多信息,参见本文备注
TRUNCATE_EXISTING(5)1. 仅当文件存在时,才打开一个文件并且将其大小截取到 0 字节

2. 如果指定的文件不存在,函数执行失败且 last-error code 设置为 ERROR_FILE_NOT_FOUND(2)

3. 调用方需要设置 dwDesiredAccess 参数的 GENERIC_WRITE 位
dwFlagsAndAttributes1. 文件或设备的属性值和标记位,对于文件来说,FILE_ATTRIBUTE_NORMAL 是最常用的默认值

2. 此参数可以是任意文件属性值(FILE_ATTRIBUTE_*)的组合。所有其他的文件属性值会覆盖 FILE_ATTRIBUTE_NORMAL

3. 此参数也可以包含任意标记位(FILE_FLAG_*)的组合以控制文件或设备的行为、权限设置和其他目的。此外,还可以与任意 FILE_ATTRIBUTE_* 进行组合

4. 在指定了 SECURITY_SQOS_PRESENT 标记位时,此参数则包含了 Security Quality of Service (SQOS) 信息

5. 其他与 SQOS 相关标记位的信息在属性和标记位表的下面那个表格中有描述

6. 注意:当 CreateFileTransacted 函数打开一个已存在的文件时,它通常将文件标记位和已存在文件的属性值组合在一起,而忽略任意在 dwFlagsAndAttributes 参数中指定的文件属性值。特殊例子在 Creating and Opening Files 中有详细描述

7. 以下的文件属性值和标记位只用于文件对象,而在 CreateFileTransacted 函数打开的其他类型的对象中无效(进一步信息见备注)。关于文件属性的更多信息,见 SetFileAttributes 函数。而在 File Attribute Constants 中有一个关于文件属性值和其描述的完整的表格

属性 含义
FILE_ATTRIBUTE_ARCHIVE
32 (0x20)
文件为存档未见。程序使用此属性来备份或移除标记文件。当使用 CreateFile 函数创建一个新文件时,会自动设置这个标记
FILE_ATTRIBUTE_ENCRYPTED
16384 (0x4000)
1. 文件或目录被加密。对于文件来说,这意味着文件中所有数据都被加密了;对于目录来说,这意味着加密新创建的文件和子文件夹是默认选项。更多信息,参见 File Encryption

2. 如果指定了 FILE_ATTRIBUTE_SYSTEM 标记位,则这个标记位不起作用
FILE_ATTRIBUTE_HIDDEN
2 (0x2)
文件被隐藏。即在普通文件夹中不被显示
FILE_ATTRIBUTE_NORMAL
128 (0x80)
这个文件不包含其他属性。只有当它单独使用时,这个属性值才是合法的
FILE_ATTRIBUTE_OFFLINE
4096 (0x1000)
文件的数据无法直接访问。这个属性表示文件数据在物理设备中被移动到一个离线存储器。这个属性被远程存储(Remote Storage)—— 即分级存储管理软件 —— 所使用。我们的程序不能随意改变这个属性值
FILE_ATTRIBUTE_READONLY
1 (0x1)
文件只读。程序可以读取文件,但无法写入或删除文件
FILE_ATTRIBUTE_SYSTEM
4 (0x4)
文件是操作系统的的一部分或者专门为操作系统所使用
FILE_ATTRIBUTE_TEMPORARY
256 (0x100)
1. 文件为临时文件

2. 如果拥有足够的缓冲内存,文件系统会避免将数据写入大容量存储器,因为当句柄被关闭后,程序会删除临时文件。否则,在句柄被关闭后,数据会被写回磁盘

标志位 含义
FILE_FLAG_BACKUP_SEMANTICS
(0x02000000)
1. 此文件已经被打开或者创建以用于备份或者恢复操作。当调用进程拥有 SE_BACKUP_NAME 和 SE_RESTORE_NAME 权限时,系统保证调用进程覆盖文件安全检测。更多信息,参见 Changing Privileges in a Token

2. 若要取一个文件夹句柄,你必须设置这个标记位。某些函数只能接受文件夹句柄而非文件句柄。更多信息,参见 Directory Handles
FILE_FLAG_DELETE_ON_CLOSE
(0x04000000)
1. 如果事务仍然处于激活状态,那么在最后指向此文件的事务性写者句柄被关闭后,此文件将马上被删除

2. 如果一个文件有删除标记,且一个事务性写者句柄在事务完成后仍然打开,则文件将不会被删除

3. 如果存在指向某文件的句柄,除非这些句柄都以 FILE_SHARE_DELETE 共享模式打开,否则函数调用失败

4. 后续对此文件的打开操作将会失败,除非指定了 FILE_SHARE_DELETE 共享模式
FILE_FLAG_NO_BUFFERING
(0x20000000)
1. 文件被以不使用系统缓存的方式打开。此标记位不会影响硬盘缓存或内存映射文件。当和标记位 FILE_FLAG_OVERLAPPED 共同使用,此标记位则会有最好的异步操作表现,因为这些 I/O 并不依赖于内存管理器的同步操作。然而,一些 I/O 操作花费更多的时间,因为数据并不保存在缓存中。另一方面,文件的元数据仍然被缓存。若要马上将元数据写入硬盘中,需调用 FlushFileBuffers 函数

2. 当文件被以 FILE_FLAG_NO_BUFFERING 方式打开时,程序必须满足如下要求:
  • 文件访问时,文件字节偏移必须是磁盘扇区大小的整数倍
  • 文件访问时,读、写的字节数必须时磁盘扇区大小的整数倍。例如,如果扇区大小为512字节,则程序可以申请读取或写入 512,1024,1536 或 2048 字节,但不能是 335,981 或 7171 字节
  • 用于读写操作的缓存地址应该与扇区大小对齐,这意味着一个对齐的内存地址必须时磁盘扇区大小的整数倍。在不同磁盘中,此要求可能并不一定是强制的

3. 一个使得缓冲内存对齐的方法是调用 VirtualAlloc 函数去分配缓冲区。此函数分配得到的内存与操作系统内存页大小对齐。因为内存页面和扇区大小都是 2 的幂,且内存页面大小是扇区大小的整数倍。内存页的大小是 4KB 或 8KB;扇区大小在硬盘中是 512B 或 4096B,在 CD 中是 2048B,因此磁盘扇区的大小无论如何都不会大于内存页面大小

4. 程序可以通过调用 GetDiskFreeSpace 函数获取磁盘扇区大小
FILE_FLAG_OPEN_NO_RECALL
(0x00100000)
文件数据被请求,但数据应该继续存放在远程存储器中。文件数据不被传输回本地存储器。此标记位被用于远程存储系统
FILE_FLAG_OPEN_REPARSE_POINT
(0x00200000)
正常的 reparse point 过程将不会发生,CreateFileTransacted 函数将会试图打开 reparse point。当文件被打开,无论控制此 reparse point 的过滤器是否可操作,都会返回文件句柄。此标记位不能与 CREATE_ALWAYS 标记位一起使用。如果此文件不是一个 reparse point,那么此标记位无效
FILE_FLAG_OVERLAPPED
(0x40000000)
1. 此文件被打开或创建用于异步 I/O。当操作完成后,在 OVERLAPPED 结构体中指定的事件会被设置为受信状态。此时在进程中消费大量 CPU 时间的 I/O 操作将会返回 ERROR_IO_PENDING

2. 如果此标记位被指定,文件可同时用于读写操作。系统并不会保留文件指针,因此你必须将文件位置参数传到读写函数的 OVERLAPPED 结构体上,或者更新文件指针

3. 如果此标记位未被指定,那么 I/O 操作不能同时执行,即使我们在调用读写函数时,传入了一个不为 NULL 的 OVERLAPPED 结构体
FILE_FLAG_POSIX_SEMANTICS
(0x0100000)
1. 文件使用 POSIX 规则访问。这包括允许不同的文件使用除了大小写外,其他都相同的文件名

2. 当使用此标记位时要小心,因为使用此标记位创建的文件可能无法被为 MS-DOS 或 16 位 Windows 所编写的程序所访问
FILE_FLAG_RANDOM_ACCESS
(0x10000000)
文件的访问是随机的。系统通过此标记位去优化文件缓存
FILE_FLAG_SESSION_AWARE
(0x00800000)
1. 文件或设备带 session awareness 打开。如果此标记位没有被指定,则 per-session 设备(一个使用 RemoteFX USB 重定向的设备)无法被运行在 session 0 的进程所打开。如果调用进程没有运行在 session 0,则此标记位无效。此标记位只支持在 server 版本的 Windows 系统

2. Windows Server 2008 R2 和 Windows Server 2008:此标记位不支持 Windows Server 2012 之前的版本
FILE_FLAG_SEQUENTIAL_SCAN
(0x08000000)
1. 文件访问的顺序为顺序从文件头访问到文件尾。系统使用此标记位优化文件缓存。如果程序随机移动文件指针访问文件,那么将不会有最好的缓存效果;但是仍然可以保证 I/O 操作正确执行

2. 在程序读取大型文件并且顺序访问时,使用此标记位将会更快速。当程序在读取大型文件,且大部分数据都是顺序读取,只是偶尔跳过少数的字节时,会有更可观的优化效果

3. 当文件系统不支持 I/O 缓存和 FILE_FLAG_NO_BUFFERING 时,此标记位无效

4. 写操作将不会经过任何中间缓存,而是直接写回磁盘
FILE_FLAG_WRITE_THROUGH
(0x80000000)
1. 如果 FILE_FLAG_NO_BUFFERING 标记位没有一起指定,即系统缓存仍在工作,那么数据会写入系统缓存,但接着会马上写入磁盘

2. 如果 FILE_FLAG_NO_BUFFERING 标记位也被指定,即系统缓存不工作,那么数据会绕过系统缓存,直接写入磁盘中

8. dwFlagsAndAttributes 参数还可以指定 SQOS 信息。更多信息,参见 Impersonation Levels。当程序在 dwFlagsAndAttribbutes 指定了 SECURITY_SQOS_PRESENT 标记位,它还可以包含下表一个或多个值:

安全标志 含义
SECURITY_ANONYMOUS将客户端模拟在匿名级别
SECURITY_CONTEXT_TRACKING指定安全跟踪模式是动态的。 如果此标记位未被指定,则安全跟踪模式为静态的
SECURITY_DELEGATION将客户端模拟在授权级别
SECURITY_EFFECTIVE_ONLY1. 服务器只能访问到客户端安全配置中被允许的数据。如果此标记位未被指定,则客户端安全配置中所有数据都能访问

2. 当模拟一个客户端时,此标记位允许客户端去限制服务端可以使用的组和权限
SECURITY_IDENTIFICATION将客户端模拟在身份认证级别
SECURITY_IMPERSONATION1. 将客户端模拟在伪装级别

2. 如果没有其他标记位和 SECURITY_SQOS_PRESENT 标记位共同被指定,则当前标记位是默认标记
hTemplateFile1. 指向一个拥有 GENERIC_READ 访问权限的的模板文件的合法句柄

2. 此模板文件为即将创建的文件提供属性和扩展属性

3. 参数值可以为 NULL

4. 如果打开一个已存在的文件,则 CreateFileTransacted 函数忽略这个参数

5. 当打开一个在被 EFS 文件系统加密的文件时,此文件从它的父目录中继承 DACL
hTransaction1. 指向事务的句柄

2. 此句柄为 CreateTransaction 函数所返回
pusMiniVersion如果在参数 hTransaction 中指定的事务并不是修改此文件的事务,则此参数应该为 NULL。否则,此参数可以是一个由 FSCTL_TXFS_CREATE_MINIVERSION 控制码返回的 miniversion 标识器,或是以下的值:
含义
TXFS_MINIVERSION_COMMITTED_VIEW
(0x0000)
文件的视图为其最后一次提交的结果
TXFS_MINIVERSION_DIRTY_VIEW
(0xFFFF)
文件的视图为其被事务修改的结果
TXFS_MINIVERSION_DEFAULT_VIEW
(0xFFFE)
文件为 committed view 或是 dirty view,取决于上下文。若事务修改了文件则为 dirty view,而不修改文件的为 committed view
pExtendedParameter 此参数被保留,必须为 NULL


返回值:

1. 如果函数调用成功,返回指向指定文件的句柄、设备、命名管道或者邮槽;

2. 如果函数调用失败,返回值为 INVALID_HANDLE_VALUE。

想获取具体错误信息,调用 GetLastError 函数。


备注:

1. 当我们使用的句柄是由 CreateFileTransacted 函数返回时,调用事务性版本的文件 I/O 函数会比调用标准文件 I/O 函数更精确。更多信息,参见 Programming Considerations for Transactional NTFS

2. 当打开一个指向目录的事务性句柄时,此句柄必须拥有 FILE_WRITE_DATA (FILE_ADD_FILE) 和 FILE_APPEND_DATA (FILE_ADD_SUBDIRECTORY) 权限。这些权限都包含在 FILE_GENERIC_WRITE 权限里。如果你打开此目录句柄仅仅是为了创建文件或子目录,你应该申请更少的权限;否则,会发生共享冲突。

3. 当文件是另一个事务的一部分时(即另一个程序已经通过调用 CreateFileTransacted 函数打开了此文件),你无法以 FILE_EXECUTE 权限打开此文件。这意味着当访问权限为 FILE_EXECUTE 或者指定了 FILE_ALL_ACCESS 权限时,如果一个非事务性的程序调用 CreateFileTransacted 函数、并且在 lpSecurityAttributes 参数中指定了 MAXIMUM_ALLOWED,那么 CreateFileTransacted 函数执行失败。一个句柄每次总是被以相同的权限打开。当一个事务性程序调用 CreateFileTransacted 函数,并且在 lpSecurityAttributes 参数中指定了 MAXIMUM_ALLOWED ,那么文件将被以不同的权限打开,这取决于文件是否被一个事务锁定。例如,如果程序对文件拥有 FILE_EXECUTE 访问权限,那么当被打开的文件没有被事务锁定或者被一个事务锁定且程序已经是该文件的事务性读者程序时,此程序只拥有此权限。

4. Transactional NTFS 中对事务性操作有完整的描述。

5. 使用 CloseHandle 函数可以关闭 CreateFileTransacted 函数创建的句柄,且此操作优先于事务提交和回滚。

6. 一些文件系统,如NTFS文件系统,支持单独文件或目录的压缩或加密。磁盘分区中的文件系统决定如何压缩和加密。且新创建的文件将继承其父目录的压缩和加密属性。

7.你无法通过 CreateFileTransacted 函数来控制文件和目录的压缩。更多信息,参见 File Compression and DecompressionFile Encryption

8. 符号链接 —— 如果此函数的调用最终创建了一个新文件,那么不考虑符号链接。

9. 如果 FILE_FLAG_OPEN_REPARSE_POINT 被指定:
  • 如果打开一个文件且它为符号链接,则返回的句柄指向这个符号链接
  • 如果制定了 TRUNCATE_EXISTING 或 FILE_FLAG_DELETE_ON_CLOSE,则被影响的文件为符号链接

10. 如果 FILE_FLAG_OPEN_REPARSE_POINT未被指定:
  • 如果打开一个文件且它为符号链接,则返回的句柄指向符号链接指向的文件
  • 如果指定了 CREATE_ALWAYS,TRUNCATE_EXISTING 或 FILE_FLAG_DELETE_ON_CLOSE 标记位,那么受影响的是符号链接指向的文件

11. 除非你使用一个事务(这意味着句柄是一个事务性句柄),否则一个多扇区的写操作并不能保证是原子性的。一个单扇区的写操作时原子性的。多扇区的写操作由于缓存可能并不总是写到磁盘中;因此指定 FILE_FLAG_WRITE_THROUGH 标记位可以确保多扇区的写操作会直接写回磁盘

12. 如前所述,如果 lpSecurityAttributes 参数为 NULL,那么 CreateFileTransacted 函数返回的句柄无法被进程所创建的任何一个子进程所继承。以下为与此参数相关的信息:
  • 如果 bInheritHandle 不为 FALSE,即为任意非 0 值,那么此句柄可以被继承。因此如果你并不想句柄被继承,需要确保此结构体的成员被正确初始化为 FALSE。
  • 文件或目录默认安全描述符中的访问控制列表(ACL)继承自其父目录。
  • 目标文件系统必须支持文件目录安全功能,以令 lpSecurityDescriptor 能起到作用,我们可以通过调用 GetVolumeInformation 函数确定文件系统是否有此功能

13. 在 Windows 8 和 Windows Server 2012 中,此函数由以下技术支持:

技术 是否支持
Server Message Block (SMB) 3.0 protocol 不支持
SMB 3.0 Transparent Failover (TFO) 不支持
SMB 3.0 with Scale-out File Shares (SO) 不支持
Cluster Shared Volume File System (CsvFS) 不支持
Resilient File System (ReFS) 不支持

注意:SMB 3.0 不支持 TxF。

14. 文件

如果你试图在没有放软盘的软盘驱动器或没有放 CD 的 CD-ROM 驱动器中创建文件,那么系统会提示用户插入一张软盘或 CD。如果想禁止系统出现此提示,需调用 SetErrorMode 函数并传入 SEM_FAILCRITICALERRORS 参数。

更多信息,参见 Creating and Opening Files

如果你重命名或删除一个文件,然后很快又恢复它,则系统会搜寻文件缓存系统去执行恢复操作。被缓存的信息包括文件的短/长文件名和创建时间。

如果文件已经调用了 DeleteFile 函数正在等待删除,此时如果你对此文件又调用CreateFileTransacted 函数,则函数执行失败。操作系统会延迟文件删除操作直到所有指向此文件的句柄都被关闭。GetLastError 返回 ERROR_ACCESS_DENIED。

参数 dwDesiredAccess 可以为 0,这会允许程序询问文件属性而不直接访问文件。这在你试图检查一个文件存不存在或者试图获取文件其他一些信息而不直接读写文件时,是很有用的。参见 Obtaining and Setting File InformationGetFileInformationByHandle 函数。

当程序通过网络去创建一个文件时,使用 GENERIC_READ | GENERIC_WRITE 会比单独使用 GENERIC_WRITE 更好。这会让代码更快,因为重定位器可以使用缓存管理器,发送更少的 SMB 而传送更多的数据。这个权限的组合还可以避免通过网络写入文件时偶尔会发送的 ERROR_ACCESS_DENIED 错误。

15. 文件流

在 NTFS 文件系统中,你可以调用 CreateFileTransacted 函数在一个文件中创建不同的流。

更多信息,参见 File Streams

16. 目录

程序无法通过调用 CreateFileTransacted 函数来创建一个目录,因此在此例中,参数 dwCreationDisposition 只有取值为 OPEN_EXISTING 时,才是合法的。若要创建一个目录,程序必须调用 CreateDirectoryTransacted 函数,CreateDirectory 函数或 CreateDirectoryEx 函数。

若要使用 CreateFileTransacted 函数打开一个目录文件,需在 dwFlagsAndAttributes 参数中指定 FILE_FLAG_BACKUP_SEMANTICS 标记位。当此标记位没有指定 SE_BACKUP_NAME 和 SE_RESTORE_NAME 权限,则适当的安全检查仍然会进行。

在 FAT 或 FAT32 文件系统中,当调用 CreateFileTransacted 函数去打开一个目录时,如果此时正在进行磁盘碎片整理,那么不要指定 MAXIMUM_ALLOWED 访问权限。否则,对目录的访问将被拒绝。此时应指定 GENERIC_READ 权限。

更多信息,参见 About Directory Management


需求:

Minimum supported client Windows XP [仅桌面应用程序]
Minimum supported server Windows 2003 服务器版 [仅桌面应用程序]
Header FileAPI.h (包含于 Windows.h)
在 Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 和 Windows XP 系统上的 WinBase.h (包含于 Windows.h)
LibraryKernel32.lib
DLL Kernel32.dll
Unicode and ANSI namesCreateFileTransactedW (Unicode) 和 CreateFileTransactedA (ANSI)


【API档案】版权归鱼C工作室(www.fishc.com)所有,转载请注明来源。




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 13:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表