wine-staging/patches/ntdll-NtQueryEaFile/0001-ntdll-Improve-stub-of-NtQueryEaFile.patch

162 lines
7.2 KiB
Diff

From 4a7559e041d5f83e57368a21caf0237f6a24a380 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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 be6b591..8c8e976 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -3293,14 +3293,25 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
* Success: 0. Atrributes read into buffer
* Failure: An NTSTATUS error code describing the error.
*/
-NTSTATUS WINAPI NtQueryEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, ULONG length,
+NTSTATUS WINAPI 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 70c7a55..ad27906 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)(POBJECT_ATTRIBUTES, PFILE_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 )
{
@@ -4161,6 +4162,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");
@@ -4197,6 +4278,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();
@@ -4218,4 +4300,5 @@ START_TEST(file)
test_file_disposition_information();
test_query_volume_information_file();
test_query_attribute_information_file();
+ test_query_ea();
}
--
2.5.0