mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	tst: winfsp-tests: Overwrite: EA support
This commit is contained in:
		| @@ -914,9 +914,13 @@ namespace Fsp.Interop | |||||||
|                     EndP) |                     EndP) | ||||||
|             { |             { | ||||||
|                 String EaName = Marshal.PtrToStringAnsi((IntPtr)P->EaName, P->EaNameLength); |                 String EaName = Marshal.PtrToStringAnsi((IntPtr)P->EaName, P->EaNameLength); | ||||||
|                 Byte[] EaValue = new Byte[P->EaValueLength]; |                 Byte[] EaValue = null; | ||||||
|  |                 if (0 != P->EaValueLength) | ||||||
|  |                 { | ||||||
|  |                     EaValue = new Byte[P->EaValueLength]; | ||||||
|                     Marshal.Copy((IntPtr)(((IntPtr)P->EaName).ToInt64() + P->EaNameLength + 1), |                     Marshal.Copy((IntPtr)(((IntPtr)P->EaName).ToInt64() + P->EaNameLength + 1), | ||||||
|                         EaValue, 0, P->EaValueLength); |                         EaValue, 0, P->EaValueLength); | ||||||
|  |                 } | ||||||
|                 Boolean NeedEa = 0 != (0x80/*FILE_NEED_EA*/ & P->Flags); |                 Boolean NeedEa = 0 != (0x80/*FILE_NEED_EA*/ & P->Flags); | ||||||
|                 Result = EnumerateEa(FileNode, FileDesc, ref Context, EaName, EaValue, NeedEa); |                 Result = EnumerateEa(FileNode, FileDesc, ref Context, EaName, EaValue, NeedEa); | ||||||
|                 if (0 > Result) |                 if (0 > Result) | ||||||
|   | |||||||
| @@ -1115,10 +1115,15 @@ namespace memfs | |||||||
|         { |         { | ||||||
|             FileNode FileNode = (FileNode)FileNode0; |             FileNode FileNode = (FileNode)FileNode0; | ||||||
|             SortedDictionary<String, EaValueData> EaMap = FileNode.GetEaMap(true); |             SortedDictionary<String, EaValueData> EaMap = FileNode.GetEaMap(true); | ||||||
|  |             if (null != EaValue) | ||||||
|  |             { | ||||||
|                 EaValueData Data; |                 EaValueData Data; | ||||||
|                 Data.EaValue = EaValue; |                 Data.EaValue = EaValue; | ||||||
|                 Data.NeedEa = NeedEa; |                 Data.NeedEa = NeedEa; | ||||||
|                 EaMap[EaName] = Data; |                 EaMap[EaName] = Data; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |                 EaMap.Remove(EaName); | ||||||
|             return STATUS_SUCCESS; |             return STATUS_SUCCESS; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -348,7 +348,7 @@ NTSTATUS MemfsFileNodeCreate(PWSTR FileName, MEMFS_FILE_NODE **PFileNode) | |||||||
|  |  | ||||||
| #if defined(MEMFS_EA) | #if defined(MEMFS_EA) | ||||||
| static inline | static inline | ||||||
| VOID MemfsFileNodeDeleteAllEa(MEMFS_FILE_NODE *FileNode) | VOID MemfsFileNodeDeleteEaMap(MEMFS_FILE_NODE *FileNode) | ||||||
| { | { | ||||||
|     if (0 != FileNode->EaMap) |     if (0 != FileNode->EaMap) | ||||||
|     { |     { | ||||||
| @@ -356,6 +356,7 @@ VOID MemfsFileNodeDeleteAllEa(MEMFS_FILE_NODE *FileNode) | |||||||
|             p != q; ++p) |             p != q; ++p) | ||||||
|             free(p->second); |             free(p->second); | ||||||
|         delete FileNode->EaMap; |         delete FileNode->EaMap; | ||||||
|  |         FileNode->EaMap = 0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| @@ -364,7 +365,7 @@ static inline | |||||||
| VOID MemfsFileNodeDelete(MEMFS_FILE_NODE *FileNode) | VOID MemfsFileNodeDelete(MEMFS_FILE_NODE *FileNode) | ||||||
| { | { | ||||||
| #if defined(MEMFS_EA) | #if defined(MEMFS_EA) | ||||||
|     MemfsFileNodeDeleteAllEa(FileNode); |     MemfsFileNodeDeleteEaMap(FileNode); | ||||||
| #endif | #endif | ||||||
| #if defined(MEMFS_REPARSE_POINTS) | #if defined(MEMFS_REPARSE_POINTS) | ||||||
|     free(FileNode->ReparseData); |     free(FileNode->ReparseData); | ||||||
| @@ -1252,7 +1253,7 @@ static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem, | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if defined(MEMFS_EA) | #if defined(MEMFS_EA) | ||||||
|     MemfsFileNodeDeleteAllEa(FileNode); |     MemfsFileNodeDeleteEaMap(FileNode); | ||||||
|     if (0 != Ea) |     if (0 != Ea) | ||||||
|     { |     { | ||||||
|         Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength); |         Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength); | ||||||
|   | |||||||
| @@ -645,10 +645,6 @@ static void ea_check_ea2(HANDLE Handle) | |||||||
|     } Ea; |     } Ea; | ||||||
|     struct ea_check_ea_context Context; |     struct ea_check_ea_context Context; | ||||||
|  |  | ||||||
|     memset(&Context, 0, sizeof Context); |  | ||||||
|     Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, FALSE); |  | ||||||
|     ASSERT(STATUS_EA_CORRUPT_ERROR == Result); |  | ||||||
|  |  | ||||||
|     memset(&Context, 0, sizeof Context); |     memset(&Context, 0, sizeof Context); | ||||||
|     Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, TRUE); |     Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, TRUE); | ||||||
|     ASSERT(STATUS_SUCCESS == Result); |     ASSERT(STATUS_SUCCESS == Result); | ||||||
| @@ -771,6 +767,103 @@ static void ea_create_test(void) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void ea_overwrite_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) | ||||||
|  | { | ||||||
|  |     void *memfs = memfs_start_ex(Flags, FileInfoTimeout); | ||||||
|  |  | ||||||
|  |     HANDLE DirHandle, FileHandle; | ||||||
|  |     NTSTATUS Result; | ||||||
|  |     BOOLEAN Success; | ||||||
|  |     WCHAR FilePath[MAX_PATH]; | ||||||
|  |     WCHAR UnicodePathBuf[MAX_PATH] = L"file2"; | ||||||
|  |     UNICODE_STRING UnicodePath; | ||||||
|  |     OBJECT_ATTRIBUTES Obja; | ||||||
|  |     IO_STATUS_BLOCK Iosb; | ||||||
|  |     LARGE_INTEGER LargeZero = { 0 }; | ||||||
|  |     union | ||||||
|  |     { | ||||||
|  |         FILE_FULL_EA_INFORMATION V; | ||||||
|  |         UINT8 B[512]; | ||||||
|  |     } Ea; | ||||||
|  |     ULONG EaLength; | ||||||
|  |  | ||||||
|  |     StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", | ||||||
|  |         Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); | ||||||
|  |  | ||||||
|  |     Success = CreateDirectoryW(FilePath, 0); | ||||||
|  |     ASSERT(Success); | ||||||
|  |  | ||||||
|  |     DirHandle = 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 != DirHandle); | ||||||
|  |  | ||||||
|  |     UnicodePath.Length = (USHORT)wcslen(UnicodePathBuf) * sizeof(WCHAR); | ||||||
|  |     UnicodePath.MaximumLength = sizeof UnicodePathBuf; | ||||||
|  |     UnicodePath.Buffer = UnicodePathBuf; | ||||||
|  |     InitializeObjectAttributes(&Obja, &UnicodePath, 0, DirHandle, 0); | ||||||
|  |  | ||||||
|  |     Result = NtCreateFile(&FileHandle, | ||||||
|  |         FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb, | ||||||
|  |         &LargeZero, FILE_ATTRIBUTE_NORMAL, 0, | ||||||
|  |         FILE_CREATE, 0, | ||||||
|  |         0, 0); | ||||||
|  |     ASSERT(STATUS_SUCCESS == Result); | ||||||
|  |     CloseHandle(FileHandle); | ||||||
|  |  | ||||||
|  |     EaLength = 0; | ||||||
|  |     ea_init_ea(&Ea.V, sizeof Ea, &EaLength); | ||||||
|  |     Result = NtCreateFile(&FileHandle, | ||||||
|  |         FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb, | ||||||
|  |         &LargeZero, FILE_ATTRIBUTE_NORMAL, 0, | ||||||
|  |         FILE_OVERWRITE, 0, | ||||||
|  |         &Ea, EaLength); | ||||||
|  |     ASSERT(STATUS_SUCCESS == Result); | ||||||
|  |     ea_check_ea(FileHandle); | ||||||
|  |     CloseHandle(FileHandle); | ||||||
|  |  | ||||||
|  |     EaLength = 0; | ||||||
|  |     ea_init_ea2(&Ea.V, sizeof Ea, &EaLength); | ||||||
|  |     Result = NtCreateFile(&FileHandle, | ||||||
|  |         FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE, &Obja, &Iosb, | ||||||
|  |         &LargeZero, FILE_ATTRIBUTE_NORMAL, 0, | ||||||
|  |         FILE_OVERWRITE, FILE_DELETE_ON_CLOSE, | ||||||
|  |         &Ea, EaLength); | ||||||
|  |     ASSERT(STATUS_SUCCESS == Result); | ||||||
|  |     ea_check_ea2(FileHandle); | ||||||
|  |     CloseHandle(FileHandle); | ||||||
|  |  | ||||||
|  |     CloseHandle(DirHandle); | ||||||
|  |  | ||||||
|  |     DirHandle = 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 == DirHandle); | ||||||
|  |     ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); | ||||||
|  |  | ||||||
|  |     memfs_stop(memfs); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ea_overwrite_test(void) | ||||||
|  | { | ||||||
|  |     if (NtfsTests) | ||||||
|  |     { | ||||||
|  |         WCHAR DirBuf[MAX_PATH]; | ||||||
|  |         GetTestDirectory(DirBuf); | ||||||
|  |         ea_overwrite_dotest(-1, DirBuf, 0); | ||||||
|  |     } | ||||||
|  |     if (WinFspDiskTests) | ||||||
|  |     { | ||||||
|  |         ea_overwrite_dotest(MemfsDisk, 0, 0); | ||||||
|  |         ea_overwrite_dotest(MemfsDisk, 0, 1000); | ||||||
|  |     } | ||||||
|  |     if (WinFspNetTests) | ||||||
|  |     { | ||||||
|  |         ea_overwrite_dotest(MemfsNet, L"\\\\memfs\\share", 0); | ||||||
|  |         ea_overwrite_dotest(MemfsNet, L"\\\\memfs\\share", 1000); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) | static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) | ||||||
| { | { | ||||||
|     void *memfs = memfs_start_ex(Flags, FileInfoTimeout); |     void *memfs = memfs_start_ex(Flags, FileInfoTimeout); | ||||||
| @@ -815,6 +908,8 @@ static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) | |||||||
|     Result = NtSetEaFile(DirHandle, &Iosb, &Ea, EaLength); |     Result = NtSetEaFile(DirHandle, &Iosb, &Ea, EaLength); | ||||||
|     ASSERT(STATUS_SUCCESS == Result); |     ASSERT(STATUS_SUCCESS == Result); | ||||||
|     ASSERT(0 == Iosb.Information); |     ASSERT(0 == Iosb.Information); | ||||||
|  |     Result = NtQueryEaFile(DirHandle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, FALSE); | ||||||
|  |     ASSERT(STATUS_EA_CORRUPT_ERROR == Result); | ||||||
|     ea_check_ea2(DirHandle); |     ea_check_ea2(DirHandle); | ||||||
|  |  | ||||||
|     CloseHandle(DirHandle); |     CloseHandle(DirHandle); | ||||||
| @@ -850,6 +945,8 @@ static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) | |||||||
|     Result = NtSetEaFile(FileHandle, &Iosb, &Ea, EaLength); |     Result = NtSetEaFile(FileHandle, &Iosb, &Ea, EaLength); | ||||||
|     ASSERT(STATUS_SUCCESS == Result); |     ASSERT(STATUS_SUCCESS == Result); | ||||||
|     ASSERT(0 == Iosb.Information); |     ASSERT(0 == Iosb.Information); | ||||||
|  |     Result = NtQueryEaFile(FileHandle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, FALSE); | ||||||
|  |     ASSERT(STATUS_EA_CORRUPT_ERROR == Result); | ||||||
|     ea_check_ea2(FileHandle); |     ea_check_ea2(FileHandle); | ||||||
|  |  | ||||||
|     CloseHandle(FileHandle); |     CloseHandle(FileHandle); | ||||||
| @@ -886,5 +983,6 @@ static void ea_getset_test(void) | |||||||
| void ea_tests(void) | void ea_tests(void) | ||||||
| { | { | ||||||
|     TEST_OPT(ea_create_test); |     TEST_OPT(ea_create_test); | ||||||
|  |     TEST_OPT(ea_overwrite_test); | ||||||
|     TEST_OPT(ea_getset_test); |     TEST_OPT(ea_getset_test); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user