sys: FspFileNodeOpen: refine main file vs stream sharing violations

This commit is contained in:
Bill Zissimopoulos 2016-10-05 14:55:37 -07:00
parent c6967c737a
commit 27b841faf8
2 changed files with 113 additions and 8 deletions

View File

@ -479,9 +479,15 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
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 (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;
goto exit;
@ -522,7 +528,10 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
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)
{
/* 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.
*/
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++;
else
}
else
{
if ((FileObject->ReadAccess || FileObject->WriteAccess || FileObject->DeleteAccess) &&
!FileObject->SharedDelete)
OpenedFileNode->MainFileNode->StreamDenyDeleteCount++;
}
@ -651,11 +668,19 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
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--;
else
}
else
{
if ((FileObject->ReadAccess || FileObject->WriteAccess || FileObject->DeleteAccess) &&
!FileObject->SharedDelete)
FileNode->MainFileNode->StreamDenyDeleteCount--;
}

View File

@ -486,6 +486,16 @@ static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix)
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo",
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,
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
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",
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,
DELETE, 0, 0, OPEN_EXISTING, 0, 0);
ASSERT(INVALID_HANDLE_VALUE == Handle2);