From 9b3593fa8fd314cfed362318927450d9d14359e0 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 6 Jun 2015 07:03:33 +0800 Subject: ntdll: Improve stub of NtQueryEaFile. Based on a patch by Qian Hong. --- dlls/ntdll/file.c | 19 ++++++++--- dlls/ntdll/tests/file.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index f75463a..d1a7c4c 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -3324,14 +3324,25 @@ NTSTATUS WINAPI SYSCALL(NtQueryVolumeInformationFile)( HANDLE handle, PIO_STATUS * Failure: An NTSTATUS error code describing the error. */ DEFINE_SYSCALL_ENTRYPOINT( NtQueryEaFile, 9 ); -NTSTATUS WINAPI SYSCALL(NtQueryEaFile)( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, ULONG length, +NTSTATUS WINAPI SYSCALL(NtQueryEaFile)( HANDLE handle, PIO_STATUS_BLOCK iosb, PVOID buffer, ULONG length, BOOLEAN single_entry, PVOID ea_list, ULONG ea_list_len, PULONG ea_index, BOOLEAN restart ) { - FIXME("(%p,%p,%p,%d,%d,%p,%d,%p,%d) stub\n", - hFile, iosb, buffer, length, single_entry, ea_list, + int fd, needs_close; + NTSTATUS status; + + FIXME("(%p,%p,%p,%d,%d,%p,%d,%p,%d) semi-stub\n", + handle, iosb, buffer, length, single_entry, ea_list, ea_list_len, ea_index, restart); - return STATUS_ACCESS_DENIED; + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS) + return status; + + if (buffer && length) + memset( buffer, 0, length ); + + if (needs_close) close( fd ); + return STATUS_NO_EAS_ON_FILE; } diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index b8f1847..55e34ad 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -79,6 +79,7 @@ static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PV PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN); static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS); static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(const OBJECT_ATTRIBUTES*, FILE_NETWORK_OPEN_INFORMATION*); +static NTSTATUS (WINAPI *pNtQueryEaFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,BOOLEAN,PVOID,ULONG,PULONG,BOOLEAN); static inline BOOL is_signaled( HANDLE obj ) { @@ -4192,6 +4193,86 @@ static void test_read_write(void) CloseHandle(hfile); } +static void test_query_ea(void) +{ + #define EA_BUFFER_SIZE 4097 + unsigned char data[EA_BUFFER_SIZE + 8]; + unsigned char *buffer = (void *)(((DWORD_PTR)data + 7) & ~7); + DWORD buffer_len, i; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE handle; + + if (!(handle = create_temp_file(0))) return; + + /* test with INVALID_HANDLE_VALUE */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + memset(buffer, 0xcc, EA_BUFFER_SIZE); + buffer_len = EA_BUFFER_SIZE - 1; + status = pNtQueryEaFile(INVALID_HANDLE_VALUE, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + ok(buffer[0] == 0xcc, "data at position 0 overwritten\n"); + + /* test with 0xdeadbeef */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + memset(buffer, 0xcc, EA_BUFFER_SIZE); + buffer_len = EA_BUFFER_SIZE - 1; + status = pNtQueryEaFile((void *)0xdeadbeef, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + ok(buffer[0] == 0xcc, "data at position 0 overwritten\n"); + + /* test without buffer */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + status = pNtQueryEaFile(handle, &io, NULL, 0, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + + /* test with zero buffer */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + status = pNtQueryEaFile(handle, &io, buffer, 0, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + + /* test with very small buffer */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + memset(buffer, 0xcc, EA_BUFFER_SIZE); + buffer_len = 4; + status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + for (i = 0; i < buffer_len && !buffer[i]; i++); + ok(i == buffer_len, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len, i); + ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]); + + /* test with very big buffer */ + U(io).Status = 0xdeadbeef; + io.Information = 0xdeadbeef; + memset(buffer, 0xcc, EA_BUFFER_SIZE); + buffer_len = EA_BUFFER_SIZE - 1; + status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); + ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); + ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); + ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); + for (i = 0; i < buffer_len && !buffer[i]; i++); + ok(i == buffer_len, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len, i); + ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]); + + CloseHandle(handle); + #undef EA_BUFFER_SIZE +} + START_TEST(file) { HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); @@ -4228,6 +4309,7 @@ START_TEST(file) pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile"); pNtQueryFullAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryFullAttributesFile"); + pNtQueryEaFile = (void *)GetProcAddress(hntdll, "NtQueryEaFile"); test_read_write(); test_NtCreateFile(); @@ -4249,4 +4331,5 @@ START_TEST(file) test_file_disposition_information(); test_query_volume_information_file(); test_query_attribute_information_file(); + test_query_ea(); } -- 2.6.1