Eryk Sun added the comment:
Richard wrote:
> while a handle is open with share mode X, you can only reopen
> the file if you also use share mode X
To clarify, the share mode is not a property of a handle. It's a property of a
File object. A handle is a generic reference to any kind of kernel object, not
just a File.
The following is a brief discussion about access sharing and the way file
deletion works in Windows. Both of these tend to frustrate Unix programmers who
end up supporting Windows. In this discussion, a "File", with an uppercase 'F',
is the Windows kernel object type that references an open device or file-system
directory, file, or stream. A "file", with a lowercase 'f', is a data file.
Shared access is implemented for File objects [1] and tracked in a SHARE_ACCESS
record. When opening a file or directory, its shared access state is updated by
the kernel function IoCheckShareAccess [2]. Discretionary shared access is
primarily a concern for file systems, but volume devices and disk devices (e.g.
\\.\C: and \\.\PhysicalDrive0) also use it. Devices that are flagged for
mandatory exclusive access [3] (e.g. \\.\COM1) generally ignore the share mode.
Some non-exclusive devices also ignore the share mode (e.g. \\.NUL and \\.CON).
If it's not ignored, the share mode affects delete, write, read, and execute
access. The following File access rights are affected: DELETE, FILE_WRITE_DATA,
FILE_APPEND_DATA, FILE_READ_DATA, and FILE_EXECUTE. The share mode thus affects
any combination of generic access -- GENERIC_ALL, GENERIC_WRITE, GENERIC_READ,
GENERIC_EXECUTE.
A File object's requested sharing is stored in its SharedDelete, SharedWrite,
and SharedRead members. The granted access that's relevant to the share mode is
stored in the DeleteAccess, WriteAccess (write/append), and ReadAccess
(read/execute) members. Given these values, checking for a sharing violation
and updating the shared access counts uses the following logic:
RequireSharedDelete = DeleteAccessCount > 0;
RequireSharedWrite = WriteAccessCount > 0;
RequireSharedRead = ReadAccessCount > 0;
DenyDeleteAccess = SharedDeleteCount < OpenCount;
DenyWriteAccess = SharedWriteCount < OpenCount;
DenyReadAccess = SharedReadCount < OpenCount;
if (RequireSharedDelete && !SharedDelete ||
RequireSharedWrite && !SharedWrite ||
RequireSharedRead && !SharedRead ||
DenyDeleteAccess && DeleteAccess ||
DenyWriteAccess && WriteAccess ||
DenyReadAccess && ReadAccess)
{
return STATUS_SHARING_VIOLATION;
}
OpenCount++;
DeleteAccessCount += DeleteAccess;
WriteAccessCount += WriteAccess;
ReadAccessCount += ReadAccess;
SharedDeleteCount += SharedDelete;
SharedWriteCount += SharedWrite;
SharedReadCount += SharedRead;
For example, to be granted delete access, all existing File object references
must share delete access. However, if a file is opened with delete sharing but
delete access hasn't been granted, then it can be opened again without delete
sharing.
The SHARE_ACCESS structure is usually stored in a file (or stream) control
block (FCB/SCB), which is a structure that coordinates access to a file or
directory across multiple File objects. The FsContext member of a File object
points at the FCB.
A file system stores its private state for a File in a context control block
(CCB), to which the File's FsContext2 member points. The CCB is where a file
system tracks, for example, whether the file should be deleted when the object
is closed.
Deleting a file sets a delete disposition in the FCB/SCB (or LCB if hard links
are supported). The file can't be unlinked until all referencing File objects
have been closed and the underlying FCB/SCB/LCB is closing. Until then a
'deleted' file is still linked in the parent directory and prevents the
directory from being deleted.
A deleted but still referenced file is in a semi-zombie state. Windows file
systems don't allow opening such a file for any access, but it can still be
accessed via existing objects. If one of these File objects has delete access,
it can be used to unset the delete disposition (e.g. via
SetFileInformationByHandle) to make the file accessible again.
[1]: https://msdn.microsoft.com/en-us/library/ff545834
[2]: https://msdn.microsoft.com/en-us/library/ff548341
[3]: https://msdn.microsoft.com/en-us/library/ff563827
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue14243>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com