#include #include #include #include #include "memfs.h" #include "winfsp-tests.h" static void stream_create_dotest(ULONG Flags, PWSTR Prefix) { void *memfs = memfs_start(Flags); HANDLE Handle; BOOLEAN Success; WCHAR FilePath[MAX_PATH]; /* single stream */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); /* multiple streams */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:baz", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:baz", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:baz", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); /* directory streams */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Success = CreateDirectory(FilePath, 0); ASSERT(Success); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1:bar", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE == Handle); ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); memfs_stop(memfs); } static void stream_create_test(void) { if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; GetCurrentDirectoryW(MAX_PATH - 4, DirBuf + 4); stream_create_dotest(-1, DirBuf); } if (WinFspDiskTests) stream_create_dotest(MemfsDisk, 0); if (WinFspNetTests) stream_create_dotest(MemfsNet, L"\\\\memfs\\share"); } static void stream_create_sd_dotest(ULONG Flags, PWSTR Prefix) { void *memfs = memfs_start(Flags); static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; UINT8 AbsoluteSecurityDescriptorBuf[SECURITY_DESCRIPTOR_MIN_LENGTH]; PSECURITY_DESCRIPTOR SecurityDescriptor, AbsoluteSecurityDescriptor = AbsoluteSecurityDescriptorBuf; PSID Owner; PACL Dacl; BOOL OwnerDefaulted, DaclDefaulted, DaclPresent; SECURITY_ATTRIBUTES SecurityAttributes = { 0 }; HANDLE Handle; BOOLEAN Success; WCHAR FilePath[MAX_PATH]; Success = ConvertStringSecurityDescriptorToSecurityDescriptorW(Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0); ASSERT(Success); SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &SecurityAttributes, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); Success = InitializeSecurityDescriptor(AbsoluteSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); ASSERT(Success); Success = GetSecurityDescriptorOwner(SecurityDescriptor, &Owner, &OwnerDefaulted); ASSERT(Success); Success = SetSecurityDescriptorOwner(AbsoluteSecurityDescriptor, Owner, OwnerDefaulted); ASSERT(Success); Success = GetSecurityDescriptorGroup(SecurityDescriptor, &Owner, &OwnerDefaulted); ASSERT(Success); Success = SetSecurityDescriptorGroup(AbsoluteSecurityDescriptor, Owner, OwnerDefaulted); ASSERT(Success); Success = GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted); ASSERT(Success); Success = SetSecurityDescriptorDacl(AbsoluteSecurityDescriptor, DaclPresent, Dacl, DaclDefaulted); ASSERT(Success); SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.lpSecurityDescriptor = AbsoluteSecurityDescriptor; Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &SecurityAttributes, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); LocalFree(SecurityDescriptor); memfs_stop(memfs); } static void stream_create_sd_test(void) { if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; GetCurrentDirectoryW(MAX_PATH - 4, DirBuf + 4); stream_create_sd_dotest(-1, DirBuf); } if (WinFspDiskTests) stream_create_sd_dotest(MemfsDisk, 0); if (WinFspNetTests) stream_create_sd_dotest(MemfsNet, L"\\\\memfs\\share"); } static void stream_create_share_dotest(ULONG Flags, PWSTR Prefix) { void *memfs = memfs_start(Flags); HANDLE Handle1, Handle2; WCHAR FilePath[MAX_PATH]; StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); CloseHandle(Handle1); { /* share test */ Handle1 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); Handle2 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle2); CloseHandle(Handle1); CloseHandle(Handle2); Handle1 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); Handle2 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); Handle1 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); Handle2 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); } { /* main file deny delete test #1 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle2); CloseHandle(Handle1); CloseHandle(Handle2); /* main file deny delete test #2 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle2); CloseHandle(Handle1); CloseHandle(Handle2); /* main file deny delete test #3 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); /* main file deny delete test #4 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); } { /* stream deny delete test #1 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle2); CloseHandle(Handle1); CloseHandle(Handle2); /* stream deny delete test #2 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle2); CloseHandle(Handle1); CloseHandle(Handle2); /* stream deny delete test #3 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); /* stream deny delete test #4 */ StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle2 = CreateFileW(FilePath, DELETE, 0, 0, OPEN_EXISTING, 0, 0); ASSERT(INVALID_HANDLE_VALUE == Handle2); ASSERT(ERROR_SHARING_VIOLATION == GetLastError()); CloseHandle(Handle1); } StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle1 = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle1); CloseHandle(Handle1); memfs_stop(memfs); } static void stream_create_share_test(void) { if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; GetCurrentDirectoryW(MAX_PATH - 4, DirBuf + 4); stream_create_share_dotest(-1, DirBuf); } if (WinFspDiskTests) stream_create_share_dotest(MemfsDisk, 0); if (WinFspNetTests) stream_create_share_dotest(MemfsNet, L"\\\\memfs\\share"); } static void stream_getsecurity_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) { void *memfs = memfs_start_ex(Flags, FileInfoTimeout); static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; PSECURITY_DESCRIPTOR SecurityDescriptor, FileSecurityDescriptor; SECURITY_ATTRIBUTES SecurityAttributes = { 0 }; PSID Owner, Group; PACL Dacl, Sacl; BOOL OwnerDefaulted, GroupDefaulted, DaclDefaulted, DaclPresent, SaclDefaulted, SaclPresent; DWORD Length; HANDLE Handle; BOOLEAN Success; WCHAR FilePath[MAX_PATH]; Success = ConvertStringSecurityDescriptorToSecurityDescriptorW(Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0); ASSERT(Success); SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &SecurityAttributes, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); CloseHandle(Handle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, 0, 0, &Length); ASSERT(!Success); ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError()); FileSecurityDescriptor = malloc(Length); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, FileSecurityDescriptor, Length, &Length); ASSERT(Success); Success = GetSecurityDescriptorOwner(FileSecurityDescriptor, &Owner, &OwnerDefaulted); ASSERT(Success); ASSERT(0 != Owner); Success = GetSecurityDescriptorGroup(FileSecurityDescriptor, &Group, &GroupDefaulted); ASSERT(Success); ASSERT(0 != Group); Success = GetSecurityDescriptorDacl(FileSecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted); ASSERT(Success); ASSERT(!DaclPresent); Success = GetSecurityDescriptorSacl(FileSecurityDescriptor, &SaclPresent, &Sacl, &SaclDefaulted); ASSERT(Success); ASSERT(!SaclPresent); free(FileSecurityDescriptor); Success = GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, 0, 0, &Length); ASSERT(!Success); ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError()); FileSecurityDescriptor = malloc(Length); Success = GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, FileSecurityDescriptor, Length, &Length); ASSERT(Success); Success = GetSecurityDescriptorOwner(FileSecurityDescriptor, &Owner, &OwnerDefaulted); ASSERT(Success); ASSERT(0 == Owner); Success = GetSecurityDescriptorGroup(FileSecurityDescriptor, &Group, &GroupDefaulted); ASSERT(Success); ASSERT(0 == Group); Success = GetSecurityDescriptorDacl(FileSecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted); ASSERT(Success); ASSERT(DaclPresent); ASSERT(0 != Dacl); Success = GetSecurityDescriptorSacl(FileSecurityDescriptor, &SaclPresent, &Sacl, &SaclDefaulted); ASSERT(Success); ASSERT(!SaclPresent); free(FileSecurityDescriptor); CloseHandle(Handle); LocalFree(SecurityDescriptor); memfs_stop(memfs); } static void stream_getsecurity_test(void) { if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; GetCurrentDirectoryW(MAX_PATH - 4, DirBuf + 4); stream_getsecurity_dotest(-1, DirBuf, 0); } if (WinFspDiskTests) { stream_getsecurity_dotest(MemfsDisk, 0, 0); stream_getsecurity_dotest(MemfsDisk, 0, 1000); } if (WinFspNetTests) { stream_getsecurity_dotest(MemfsNet, L"\\\\memfs\\share", 0); stream_getsecurity_dotest(MemfsNet, L"\\\\memfs\\share", 1000); } } static void stream_setsecurity_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) { void *memfs = memfs_start_ex(Flags, FileInfoTimeout); static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; static PWSTR Sddl2 = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"; PWSTR ConvertedSddl; PSECURITY_DESCRIPTOR SecurityDescriptor, FileSecurityDescriptor, FileSecurityDescriptor2; SECURITY_ATTRIBUTES SecurityAttributes = { 0 }; PSID Owner, Owner2, Group, Group2; PACL Dacl, Dacl2, Sacl, Sacl2; BOOL OwnerDefaulted, GroupDefaulted, DaclDefaulted, DaclPresent, SaclDefaulted, SaclPresent; DWORD Length; HANDLE Handle, StreamHandle; BOOLEAN Success; WCHAR FilePath[MAX_PATH], StreamPath[MAX_PATH]; Success = ConvertStringSecurityDescriptorToSecurityDescriptorW(Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0); ASSERT(Success); SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; StringCbPrintfW(StreamPath, sizeof StreamPath, L"%s%s\\file0:foo", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); StreamHandle = CreateFileW(StreamPath, GENERIC_READ | GENERIC_WRITE | WRITE_DAC, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SecurityAttributes, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != StreamHandle); StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); Handle = CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 0, 0, &Length); ASSERT(!Success); ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError()); FileSecurityDescriptor = malloc(Length); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, FileSecurityDescriptor, Length, &Length); ASSERT(Success); Success = GetSecurityDescriptorOwner(FileSecurityDescriptor, &Owner, &OwnerDefaulted); ASSERT(Success); ASSERT(0 != Owner); Success = GetSecurityDescriptorGroup(FileSecurityDescriptor, &Group, &GroupDefaulted); ASSERT(Success); ASSERT(0 != Group); Success = GetSecurityDescriptorDacl(FileSecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted); ASSERT(Success); ASSERT(DaclPresent); ASSERT(0 != Dacl); Success = GetSecurityDescriptorSacl(FileSecurityDescriptor, &SaclPresent, &Sacl, &SaclDefaulted); ASSERT(Success); ASSERT(!SaclPresent); LocalFree(SecurityDescriptor); Success = ConvertStringSecurityDescriptorToSecurityDescriptorW(Sddl2, SDDL_REVISION_1, &SecurityDescriptor, 0); ASSERT(Success); Success = SetKernelObjectSecurity(StreamHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor); ASSERT(Success); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 0, 0, &Length); ASSERT(!Success); ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError()); FileSecurityDescriptor2 = malloc(Length); Success = GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, FileSecurityDescriptor2, Length, &Length); ASSERT(Success); Success = GetSecurityDescriptorOwner(FileSecurityDescriptor2, &Owner2, &OwnerDefaulted); ASSERT(Success); ASSERT(0 != Owner2); Success = GetSecurityDescriptorGroup(FileSecurityDescriptor2, &Group2, &GroupDefaulted); ASSERT(Success); ASSERT(0 != Group2); Success = GetSecurityDescriptorDacl(FileSecurityDescriptor2, &DaclPresent, &Dacl2, &DaclDefaulted); ASSERT(Success); ASSERT(DaclPresent); ASSERT(0 != Dacl2); Success = GetSecurityDescriptorSacl(FileSecurityDescriptor2, &SaclPresent, &Sacl2, &SaclDefaulted); ASSERT(Success); ASSERT(!SaclPresent); ASSERT(EqualSid(Owner, Owner2)); ASSERT(EqualSid(Group, Group2)); ASSERT(ConvertSecurityDescriptorToStringSecurityDescriptorW(FileSecurityDescriptor2, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &ConvertedSddl, 0)); ASSERT(0 == wcscmp(L"D:P(A;;FA;;;SY)(A;;FA;;;BA)", ConvertedSddl)); LocalFree(ConvertedSddl); free(FileSecurityDescriptor); free(FileSecurityDescriptor2); CloseHandle(StreamHandle); CloseHandle(Handle); LocalFree(SecurityDescriptor); memfs_stop(memfs); } static void stream_setsecurity_test(void) { if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; GetCurrentDirectoryW(MAX_PATH - 4, DirBuf + 4); stream_setsecurity_dotest(-1, DirBuf, 0); } if (WinFspDiskTests) { stream_setsecurity_dotest(MemfsDisk, 0, 0); stream_setsecurity_dotest(MemfsDisk, 0, 1000); } if (WinFspNetTests) { stream_setsecurity_dotest(MemfsNet, L"\\\\memfs\\share", 0); stream_setsecurity_dotest(MemfsNet, L"\\\\memfs\\share", 1000); } } void stream_tests(void) { TEST(stream_create_test); TEST(stream_create_sd_test); TEST(stream_create_share_test); TEST(stream_getsecurity_test); TEST(stream_setsecurity_test); }