英文:
Meaning of CF_OPEN_FILE_FLAG_FOREGROUND flag with CfOpenFileWithOplock
问题
The flag CF_OPEN_FILE_FLAG_FOREGROUND
在CF_OPEN_FILE_FLAGS和CfOpenFileWithOplock的文档中都没有记录。这个标志的含义是什么?
英文:
The flag CF_OPEN_FILE_FLAG_FOREGROUND
is not documented in either the documentation for CF_OPEN_FILE_FLAGS nor in the documentation for CfOpenFileWithOplock.
What is this flag's meaning?
答案1
得分: 0
以下信息是通过Microsoft Case提供的:
> CF_OPEN_FILE_FLAG_FOREGROUND
未记录,可能是在后期添加的。
>
> 根据代码,如果调用者不想使用Oplocks,他们在调用CfOpenFileWithOplock
时应该使用此标志。
> 这意味着在API调用CreateFile()
时,FILE_OPEN_REQUIRING_OPLOCK
不会被设置。
>
> 默认情况下,未指定FOREGROUND
标志,因此CfOpenFileWithOplock
的默认行为是请求oplock。这将使其与默认背景行为一致。
>
> 在这个上下文中,“foreground”似乎意味着调用者是作为前台应用程序。即,他们不关心此API创建的文件句柄是否会导致其他调用者的共享冲突,也不关心是否会中断文件上可能已存在的任何oplocks,因此他们在不请求oplock的情况下打开句柄。默认的“background”行为在打开文件句柄时请求oplock,以便如果已经存在oplock,则其调用会失败,并且如果需要避免稍后引起共享冲突,可以告诉它们关闭句柄。
>
> 附带说明:除非调用者向CfOpenFileWithOplock
指定了CF_OPEN_FILE_FLAG_EXCLUSIVE
,否则他们获得的oplock将仅为OPLOCK_LEVEL_CACHE_READ
,而不是(OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE
),因此不会有背景应用程序通常需要的共享冲突保护。
注意:微软(自此案例以来)已记录此标志。
在这个案例中提供了更多信息,因为它对这个API总体上是相关的:
> 通常,背景应用程序希望在文件上进行透明操作。特别是,它们希望避免对其他(前台)打开者造成共享冲突。为了做到这一点,它们获取CACHE_READ | CACHE_HANDLE
oplock,例如通过使用CfOpenFileWithOplock
的CF_OPEN_FILE_FLAG_EXCLUSIVE
来授予。然后,如果出现其他打开者的请求共享/访问模式与背景应用程序的冲突,背景应用程序的oplock将中断。这促使背景应用程序关闭其文件句柄(对于Cf
句柄,这使其无效 - 实际底层句柄已关闭)。一旦背景应用程序关闭其句柄,其他打开者的打开将继续进行,而不会发生共享冲突。所有这些都是因为oplock的CACHE_HANDLE
部分。没有CF_OPEN_FILE_FLAG_EXCLUSIVE
,oplock只有CACHE_READ
保护,所以我描述的共享冲突保护就不会发生。
> 1. 如果指定了CF_OPEN_FILE_FLAG_EXCLUSIVE
,则打开是“无共享”的,并获得CACHE_READ | CACHE_HANDLE
oplock。
> a. 通常的CreateFile
调用,打开任何FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE
(或两者都是GENERIC_READ | GENERIC_WRITE
)中的任何一个,都将由于共享冲突而中断oplock,如上所述。oplock所有者将完成并确认。
>
> 2. 如果未指定CF_OPEN_FILE_FLAG_EXCLUSIVE
,则打开是“共享所有”的,并获得CACHE_READ
oplock。
>
> a. 通常的CreateFile
调用将不会中断oplock。
>
> b. 如果普通的CreateFile
指定了与Cf
句柄访问冲突的共享模式(例如,如果普通的CreateFile
未指定FILE_SHARE_READ
),则普通的CreateFile
将以ERROR_SHARING_VIOLATION
失败。
>
> c. 直到其他调用者发出冲突的I/O,如写操作,oplock才会中断。当发生这种情况时,oplock中断仅是建议性的。
> Cf API使用oplocks的方式,“独占” oplock是唯一会中断的方式,就像您期望的那样。
(即不仅仅是建议性的中断)
英文:
The following information was supplied via a Microsoft Case:
> CF_OPEN_FILE_FLAG_FOREGROUND
is not documented, probably it was added
> at a later stage.
>
> Based on the code, it seems that If a caller doesn’t want to use
> Oplocks, they should use this flag when calling CfOpenFileWithOplock
.
> It implies that FILE_OPEN_REQUIRING_OPLOCK
wouldn’t be set when the
> API calls CreateFile()
underneath.
>
> By default, the FOREGROUND
flag is not specified, so the default
> behavior of CfOpenFileWithOplock
is to request an oplock. That would
> make it consistent with defaulting to background behavior.
>
> In this context “foreground” seems to mean that the caller is acting
> as a foreground application. I.e., they don’t care whether the file
> handle created by this API causes sharing violations for other
> callers, and they don’t care about breaking any oplocks that may
> already be on the file, so they open the handle without requesting an
> oplock. The default “background” behavior requests an oplock when
> opening the file handle so that their call fails if there’s already an
> oplock, and they can be told to close their handle if they need to get
> out of the way to avoid causing a sharing violation later.
>
> Side note: unless the caller specifies CF_OPEN_FILE_FLAG_EXCLUSIVE
to
> CfOpenFileWithOplock
, the oplock they get will be only
> OPLOCK_LEVEL_CACHE_READ
, not (OPLOCK_LEVEL_CACHE_READ |
), so there won’t be the sharing violation
> OPLOCK_LEVEL_CACHE_HANDLE
> protection a background app might normally want.
Note: Microsoft has (since this case) has now documented this flag.
Further information was provided in this case, and is shared here as it is relevant in general to this API:
> A background application typically wants to operate transparently on
> files. In particular, they want to avoid causing sharing violations to
> other (foreground) openers. To do that, they take a CACHE_READ | CACHE_HANDLE
oplock, such as would be granted by using
> CF_OPEN_FILE_FLAG_EXCLUSIVE
with CfOpenFileWithOplock
. Then, if some
> other opener comes along whose requested share/access modes conflict
> with the background app’s, the background app’s oplock breaks. This
> prompts the background app to close their file handle (for a Cf
> handle, that causes it to become invalid – the real underlying handle
> has been closed). Once the background app closes their handle, the
> other opener’s open proceeds without hitting the sharing violation.
> That all works because of the CACHE_HANDLE
part of the oplock. Without
> CF_OPEN_FILE_FLAG_EXCLUSIVE
, the oplock only has CACHE_READ
> protection, so that sharing violation protection I described doesn’t
> happen.
> 1. If CF_OPEN_FILE_FLAG_EXCLUSIVE
is specified, the open is “share none” and it gets a CACHE_READ | CACHE_HANDLE
oplock.
> a. A normal
> CreateFile
call that opens for any of FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE
(or either/both of
> GENERIC_READ | GENERIC_WRITE
) will break the oplock due to the sharing
> conflict, as described above. The oplock owner will get to finish and
acknowledge.
>
> 2. If CF_OPEN_FILE_FLAG_EXCLUSIVE
is not specified, the open is “share all” and it gets a CACHE_READ
oplock.
>
> a. A normal CreateFile
call
> will not break the oplock.
>
> b. If the normal CreateFile
specifies a
> sharing mode that conflicts with the Cf
handle’s access (for instance,
> if the normal CreateFile
does not specify FILE_SHARE_READ
), the normal
> CreateFile
will fail with ERROR_SHARING_VIOLATION
.
>
> c. The oplock doesn’t break until the other caller issues a conflicting I/O, such as a write. When that happens the oplock break is advisory only.
> The way the Cf APIs use oplocks, the “exclusive” oplock is the only one that breaks the way you’re expecting.
(i.e. a break that is not just advisory)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论