From 5c42377c1b1fa967284b33d736709ddabdd2e334 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 18 Mar 2019 18:43:18 -0700 Subject: [PATCH] tst: memfs-dotnet: ea support --- tst/winfsp-tests/ea-test.c | 186 +++++++++++++++++++++++++++++++------ 1 file changed, 156 insertions(+), 30 deletions(-) diff --git a/tst/winfsp-tests/ea-test.c b/tst/winfsp-tests/ea-test.c index 5fa4d8d4..09868e7d 100644 --- a/tst/winfsp-tests/ea-test.c +++ b/tst/winfsp-tests/ea-test.c @@ -49,6 +49,36 @@ NTSYSAPI NTSTATUS NTAPI NtSetEaFile( IN PVOID EaBuffer, IN ULONG EaBufferSize); +BOOLEAN AddGetEa(PFILE_GET_EA_INFORMATION SingleEa, + PFILE_GET_EA_INFORMATION Ea, ULONG Length, PULONG PBytesTransferred) +{ + if (0 != SingleEa) + { + PUINT8 EaPtr = (PUINT8)Ea + FSP_FSCTL_ALIGN_UP(*PBytesTransferred, sizeof(ULONG)); + PUINT8 EaEnd = (PUINT8)Ea + Length; + ULONG EaLen = FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + + SingleEa->EaNameLength + 1; + + if (EaEnd < EaPtr + EaLen) + return FALSE; + + memcpy(EaPtr, SingleEa, EaLen); + ((PFILE_GET_EA_INFORMATION)EaPtr)->NextEntryOffset = FSP_FSCTL_ALIGN_UP(EaLen, sizeof(ULONG)); + *PBytesTransferred = (ULONG)(EaPtr + EaLen - (PUINT8)Ea); + } + else if ((ULONG)FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) <= *PBytesTransferred) + { + PUINT8 EaEnd = (PUINT8)Ea + *PBytesTransferred; + + while (EaEnd > (PUINT8)Ea + Ea->NextEntryOffset) + Ea = (PVOID)((PUINT8)Ea + Ea->NextEntryOffset); + + Ea->NextEntryOffset = 0; + } + + return TRUE; +} + static void ea_init_ea( PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred) { @@ -117,36 +147,6 @@ static void ea_init_bad_ea( FspFileSystemAddEa(0, Ea, EaLength, PBytesTransferred); } -BOOLEAN AddGetEa(PFILE_GET_EA_INFORMATION SingleEa, - PFILE_GET_EA_INFORMATION Ea, ULONG Length, PULONG PBytesTransferred) -{ - if (0 != SingleEa) - { - PUINT8 EaPtr = (PUINT8)Ea + FSP_FSCTL_ALIGN_UP(*PBytesTransferred, sizeof(ULONG)); - PUINT8 EaEnd = (PUINT8)Ea + Length; - ULONG EaLen = FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + - SingleEa->EaNameLength + 1; - - if (EaEnd < EaPtr + EaLen) - return FALSE; - - memcpy(EaPtr, SingleEa, EaLen); - ((PFILE_GET_EA_INFORMATION)EaPtr)->NextEntryOffset = FSP_FSCTL_ALIGN_UP(EaLen, sizeof(ULONG)); - *PBytesTransferred = (ULONG)(EaPtr + EaLen - (PUINT8)Ea); - } - else if ((ULONG)FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) <= *PBytesTransferred) - { - PUINT8 EaEnd = (PUINT8)Ea + *PBytesTransferred; - - while (EaEnd > (PUINT8)Ea + Ea->NextEntryOffset) - Ea = (PVOID)((PUINT8)Ea + Ea->NextEntryOffset); - - Ea->NextEntryOffset = 0; - } - - return TRUE; -} - struct ea_check_ea_context { ULONG Count; @@ -161,6 +161,7 @@ static NTSTATUS ea_check_ea_enumerate( if (0 == strcmp(SingleEa->EaName, "ANAME1")) { + ASSERT(0 == SingleEa->Flags); ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("ANAME1")); ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("first")); ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "first", SingleEa->EaValueLength)); @@ -169,6 +170,7 @@ static NTSTATUS ea_check_ea_enumerate( if (0 == strcmp(SingleEa->EaName, "BNAMETWO")) { + ASSERT(FILE_NEED_EA == SingleEa->Flags); ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("BNAMETWO")); ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("second")); ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "second", SingleEa->EaValueLength)); @@ -177,6 +179,7 @@ static NTSTATUS ea_check_ea_enumerate( if (0 == strcmp(SingleEa->EaName, "CN3")) { + ASSERT(0 == SingleEa->Flags); ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("CN3")); ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("third")); ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "third", SingleEa->EaValueLength)); @@ -185,6 +188,7 @@ static NTSTATUS ea_check_ea_enumerate( if (0 == strcmp(SingleEa->EaName, "NONEXISTENT")) { + ASSERT(0 == SingleEa->Flags); ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("NONEXISTENT")); ASSERT(SingleEa->EaValueLength == 0); Context->EaCount[3]++; @@ -545,6 +549,114 @@ static void ea_check_ea(HANDLE Handle) ASSERT(STATUS_NONEXISTENT_EA_ENTRY == Result); } +static void ea_init_ea2( + PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred) +{ + union + { + FILE_FULL_EA_INFORMATION V; + UINT8 B[128]; + } SingleEa; + + memset(&SingleEa, 0, sizeof SingleEa); + SingleEa.V.EaNameLength = (UCHAR)strlen("Aname1"); + SingleEa.V.EaValueLength = (USHORT)strlen("ValueForAname1"); + lstrcpyA(SingleEa.V.EaName, "Aname1"); + memcpy(SingleEa.V.EaName + SingleEa.V.EaNameLength + 1, "ValueForAname1", SingleEa.V.EaValueLength); + FspFileSystemAddEa(&SingleEa.V, Ea, EaLength, PBytesTransferred); + + memset(&SingleEa, 0, sizeof SingleEa); + SingleEa.V.EaNameLength = (UCHAR)strlen("bnameTwo"); + SingleEa.V.EaValueLength = (USHORT)strlen("ValueForBNameTwo"); + lstrcpyA(SingleEa.V.EaName, "bnameTwo"); + memcpy(SingleEa.V.EaName + SingleEa.V.EaNameLength + 1, "ValueForBNameTwo", SingleEa.V.EaValueLength); + FspFileSystemAddEa(&SingleEa.V, Ea, EaLength, PBytesTransferred); + + memset(&SingleEa, 0, sizeof SingleEa); + SingleEa.V.EaNameLength = (UCHAR)strlen("Cn3"); + SingleEa.V.EaValueLength = 0; + lstrcpyA(SingleEa.V.EaName, "Cn3"); + FspFileSystemAddEa(&SingleEa.V, Ea, EaLength, PBytesTransferred); + + memset(&SingleEa, 0, sizeof SingleEa); + SingleEa.V.EaNameLength = (UCHAR)strlen("dn4"); + SingleEa.V.EaValueLength = (USHORT)strlen("ValueForDn4"); + lstrcpyA(SingleEa.V.EaName, "dn4"); + memcpy(SingleEa.V.EaName + SingleEa.V.EaNameLength + 1, "ValueForDn4", SingleEa.V.EaValueLength); + FspFileSystemAddEa(&SingleEa.V, Ea, EaLength, PBytesTransferred); + + FspFileSystemAddEa(0, Ea, EaLength, PBytesTransferred); +} + +static NTSTATUS ea_check_ea2_enumerate( + FSP_FILE_SYSTEM *FileSystem, PVOID Context0, + PFILE_FULL_EA_INFORMATION SingleEa) +{ + struct ea_check_ea_context *Context = Context0; + + if (0 == strcmp(SingleEa->EaName, "ANAME1")) + { + ASSERT(0 == SingleEa->Flags); + ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("ANAME1")); + ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("ValueForAname1")); + ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "ValueForAname1", SingleEa->EaValueLength)); + Context->EaCount[0]++; + } + + if (0 == strcmp(SingleEa->EaName, "BNAMETWO")) + { + ASSERT(0 == SingleEa->Flags); + ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("BNAMETWO")); + ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("ValueForBNameTwo")); + ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "ValueForBNameTwo", SingleEa->EaValueLength)); + Context->EaCount[1]++; + } + + if (0 == strcmp(SingleEa->EaName, "CN3")) + { + ASSERT(0 == SingleEa->Flags); + ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("CN3")); + ASSERT(SingleEa->EaValueLength == 0); + Context->EaCount[2]++; + } + + if (0 == strcmp(SingleEa->EaName, "DN4")) + { + ASSERT(0 == SingleEa->Flags); + ASSERT(SingleEa->EaNameLength == (UCHAR)strlen("DN4")); + ASSERT(SingleEa->EaValueLength == (UCHAR)strlen("ValueForDn4")); + ASSERT(0 == memcmp(SingleEa->EaName + SingleEa->EaNameLength + 1, "ValueForDn4", SingleEa->EaValueLength)); + Context->EaCount[3]++; + } + + Context->Count++; + + return STATUS_SUCCESS; +} + +static void ea_check_ea2(HANDLE Handle) +{ + NTSTATUS Result; + IO_STATUS_BLOCK Iosb; + union + { + FILE_FULL_EA_INFORMATION V; + UINT8 B[512]; + } Ea; + struct ea_check_ea_context Context; + + memset(&Context, 0, sizeof Context); + Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, TRUE); + ASSERT(STATUS_SUCCESS == Result); + Result = FspFileSystemEnumerateEa(0, ea_check_ea2_enumerate, &Context, &Ea.V, (ULONG)Iosb.Information); + ASSERT(STATUS_SUCCESS == Result); + ASSERT(3 == Context.Count); + ASSERT(1 == Context.EaCount[0]); + ASSERT(1 == Context.EaCount[1]); + ASSERT(0 == Context.EaCount[2]); + ASSERT(1 == Context.EaCount[3]); +} + static void ea_create_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) { void *memfs = memfs_start_ex(Flags, FileInfoTimeout); @@ -694,6 +806,13 @@ static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ASSERT(0 == Iosb.Information); ea_check_ea(DirHandle); + EaLength = 0; + ea_init_ea2(&Ea.V, sizeof Ea, &EaLength); + Result = NtSetEaFile(DirHandle, &Iosb, &Ea, EaLength); + ASSERT(STATUS_SUCCESS == Result); + ASSERT(0 == Iosb.Information); + ea_check_ea2(DirHandle); + CloseHandle(DirHandle); DirHandle = CreateFileW(FilePath, @@ -722,6 +841,13 @@ static void ea_getset_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ASSERT(0 == Iosb.Information); ea_check_ea(FileHandle); + EaLength = 0; + ea_init_ea2(&Ea.V, sizeof Ea, &EaLength); + Result = NtSetEaFile(FileHandle, &Iosb, &Ea, EaLength); + ASSERT(STATUS_SUCCESS == Result); + ASSERT(0 == Iosb.Information); + ea_check_ea2(FileHandle); + CloseHandle(FileHandle); FileHandle = CreateFileW(FilePath,