diff --git a/ext/test b/ext/test index 2d629a42..feb55438 160000 --- a/ext/test +++ b/ext/test @@ -1 +1 @@ -Subproject commit 2d629a427ff1d0f04d2117a414cd7b385ae8b95f +Subproject commit feb554380e6daf45fe859789cff62f90eff962df diff --git a/src/dll/fsop.c b/src/dll/fsop.c index 2605ddc3..aafa0f0c 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -626,9 +626,10 @@ static NTSTATUS FspFileSystemOpCreate_NotFoundCheck(FSP_FILE_SYSTEM *FileSystem, Result = FileSystem->Interface->GetSecurityByName( FileSystem, (PWSTR)Request->Buffer, &FileAttributes, 0, 0); ((PWSTR)Request->Buffer)[Request->Req.Create.NamedStream / sizeof(WCHAR)] = L':'; + if (STATUS_SUCCESS != Result) + return STATUS_OBJECT_NAME_NOT_FOUND; - if (STATUS_SUCCESS != Result || - FILE_ATTRIBUTE_REPARSE_POINT != (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + if (0 == (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) return STATUS_OBJECT_NAME_NOT_FOUND; FileAttributes = FspPathSuffixIndex((PWSTR)Request->Buffer); @@ -644,26 +645,38 @@ static NTSTATUS FspFileSystemOpCreate_CollisionCheck(FSP_FILE_SYSTEM *FileSystem FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) { /* - * This handles a Create done via a symlink. The file system has returned - * STATUS_OBJECT_NAME_COLLISION, but we check to see if the collision is - * due to a reparse point that can be resolved. + * This handles a Create that resulted in STATUS_OBJECT_NAME_COLLISION. We + * handle two separate cases: + * + * 1) A Create colliding with a directory and the FILE_NON_DIRECTORY_FILE + * flag set. We then change the result code to STATUS_FILE_IS_A_DIRECTORY. + * + * 2) A Create colliding with a symlink (reparse point) that can be resolved. + * In this case we resolve the reparse point and return STATUS_REPARSE. */ NTSTATUS Result; UINT32 FileAttributes; - if (0 == FileSystem->Interface->GetSecurityByName || - 0 == FileSystem->Interface->ResolveReparsePoints) + if (0 == FileSystem->Interface->GetSecurityByName) + return STATUS_OBJECT_NAME_COLLISION; + + Result = FileSystem->Interface->GetSecurityByName( + FileSystem, (PWSTR)Request->Buffer, &FileAttributes, 0, 0); + if (STATUS_SUCCESS != Result) + return STATUS_OBJECT_NAME_COLLISION; + + if ((Request->Req.Create.CreateOptions & FILE_NON_DIRECTORY_FILE) && + (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return STATUS_FILE_IS_A_DIRECTORY; + + if (0 == FileSystem->Interface->ResolveReparsePoints) return STATUS_OBJECT_NAME_COLLISION; if (Request->Req.Create.CreateOptions & FILE_OPEN_REPARSE_POINT) return STATUS_OBJECT_NAME_COLLISION; - Result = FileSystem->Interface->GetSecurityByName( - FileSystem, (PWSTR)Request->Buffer, &FileAttributes, 0, 0); - if (STATUS_SUCCESS != Result || - FILE_ATTRIBUTE_REPARSE_POINT != - (FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))) + if (0 == (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) return STATUS_OBJECT_NAME_COLLISION; FileAttributes = FspPathSuffixIndex((PWSTR)Request->Buffer); diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index 70cbf7ec..636bfbac 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -470,13 +470,7 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem, FileNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, FileName); if (0 != FileNode) - { - if ((CreateOptions & FILE_NON_DIRECTORY_FILE) && - 0 != (FileNode->FileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - return STATUS_FILE_IS_A_DIRECTORY; - else - return STATUS_OBJECT_NAME_COLLISION; - } + return STATUS_OBJECT_NAME_COLLISION; if (!MemfsFileNodeMapGetParent(Memfs->FileNodeMap, FileName, &Result)) return Result;