mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-25 18:02:24 -05:00
sys: FspFileNodeOpen: refine main file vs stream sharing violations
This commit is contained in:
parent
c6967c737a
commit
27b841faf8
@ -479,9 +479,15 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sharing violations between main file and streams were determined
|
||||||
|
* through experimentation with NTFS. They may be wrong!
|
||||||
|
*/
|
||||||
if (0 < FileNode->MainFileNode->MainFileDenyDeleteCount)
|
if (0 < FileNode->MainFileNode->MainFileDenyDeleteCount)
|
||||||
{
|
{
|
||||||
if (FlagOn(GrantedAccess, DELETE))
|
if (!FlagOn(ShareAccess, FILE_SHARE_DELETE) &&
|
||||||
|
FlagOn(GrantedAccess,
|
||||||
|
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE))
|
||||||
{
|
{
|
||||||
Result = STATUS_SHARING_VIOLATION;
|
Result = STATUS_SHARING_VIOLATION;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -522,7 +528,10 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if this is a main file check whether there is a named stream that denies delete */
|
/*
|
||||||
|
* Sharing violations between main file and streams were determined
|
||||||
|
* through experimentation with NTFS. They may be wrong!
|
||||||
|
*/
|
||||||
if (0 < OpenedFileNode->StreamDenyDeleteCount)
|
if (0 < OpenedFileNode->StreamDenyDeleteCount)
|
||||||
{
|
{
|
||||||
/* we must be the main file! */
|
/* we must be the main file! */
|
||||||
@ -565,11 +574,19 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
* We also updated OpenedFileNode->ShareAccess in IoSetShareAccess/IoCheckShareAccess.
|
* We also updated OpenedFileNode->ShareAccess in IoSetShareAccess/IoCheckShareAccess.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (FileObject->DeleteAccess && !FileObject->SharedDelete)
|
/*
|
||||||
|
* Sharing violations between main file and streams were determined
|
||||||
|
* through experimentation with NTFS. They may be wrong!
|
||||||
|
*/
|
||||||
|
if (0 == OpenedFileNode->MainFileNode)
|
||||||
{
|
{
|
||||||
if (0 == OpenedFileNode->MainFileNode)
|
if (FileObject->DeleteAccess)
|
||||||
OpenedFileNode->MainFileDenyDeleteCount++;
|
OpenedFileNode->MainFileDenyDeleteCount++;
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((FileObject->ReadAccess || FileObject->WriteAccess || FileObject->DeleteAccess) &&
|
||||||
|
!FileObject->SharedDelete)
|
||||||
OpenedFileNode->MainFileNode->StreamDenyDeleteCount++;
|
OpenedFileNode->MainFileNode->StreamDenyDeleteCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,11 +668,19 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
if (FileObject->DeleteAccess && !FileObject->SharedDelete)
|
/*
|
||||||
|
* Sharing violations between main file and streams were determined
|
||||||
|
* through experimentation with NTFS. They may be wrong!
|
||||||
|
*/
|
||||||
|
if (0 == FileNode->MainFileNode)
|
||||||
{
|
{
|
||||||
if (0 == FileNode->MainFileNode)
|
if (FileObject->DeleteAccess)
|
||||||
FileNode->MainFileDenyDeleteCount--;
|
FileNode->MainFileDenyDeleteCount--;
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((FileObject->ReadAccess || FileObject->WriteAccess || FileObject->DeleteAccess) &&
|
||||||
|
!FileObject->SharedDelete)
|
||||||
FileNode->MainFileNode->StreamDenyDeleteCount--;
|
FileNode->MainFileNode->StreamDenyDeleteCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +486,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
@ -505,6 +515,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
@ -524,6 +544,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
|
ASSERT(ERROR_SHARING_VIOLATION == GetLastError());
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
|
ASSERT(ERROR_SHARING_VIOLATION == GetLastError());
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
@ -543,6 +573,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
|
ASSERT(ERROR_SHARING_VIOLATION == GetLastError());
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
|
ASSERT(ERROR_SHARING_VIOLATION == GetLastError());
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
@ -564,6 +604,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
@ -583,6 +633,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
@ -602,6 +662,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
@ -621,6 +691,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_READ_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
|
Handle2 = CreateFileW(FilePath,
|
||||||
|
FILE_WRITE_DATA, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
ASSERT(INVALID_HANDLE_VALUE != Handle2);
|
||||||
|
CloseHandle(Handle2);
|
||||||
|
|
||||||
Handle2 = CreateFileW(FilePath,
|
Handle2 = CreateFileW(FilePath,
|
||||||
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
ASSERT(INVALID_HANDLE_VALUE == Handle2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user