Henri Verbeet : ntdll: Implement the FileNameInformation class for NtQueryInformationFile().
Alexandre Julliard
julliard at winehq.org
Thu Nov 12 10:22:12 CST 2009
Module: wine
Branch: master
Commit: cd6d01ac9d969c1473e86d7faac6ef5ac38a4156
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cd6d01ac9d969c1473e86d7faac6ef5ac38a4156
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Thu Nov 12 15:10:13 2009 +0100
ntdll: Implement the FileNameInformation class for NtQueryInformationFile().
---
dlls/ntdll/file.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 228646f..3b132ff 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1486,6 +1486,40 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
return 0;
}
+static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
+{
+ data_size_t size = 1024;
+ NTSTATUS ret;
+ char *name;
+
+ for (;;)
+ {
+ name = RtlAllocateHeap( GetProcessHeap(), 0, size + 1 );
+ if (!name) return STATUS_NO_MEMORY;
+ unix_name->MaximumLength = size + 1;
+
+ SERVER_START_REQ( get_handle_unix_name )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ wine_server_set_reply( req, name, size );
+ ret = wine_server_call( req );
+ size = reply->name_len;
+ }
+ SERVER_END_REQ;
+
+ if (!ret)
+ {
+ name[size] = 0;
+ unix_name->Buffer = name;
+ unix_name->Length = size;
+ break;
+ }
+ RtlFreeHeap( GetProcessHeap(), 0, name );
+ if (ret != STATUS_BUFFER_OVERFLOW) break;
+ }
+ return ret;
+}
+
/******************************************************************************
* NtQueryInformationFile [NTDLL.@]
* ZwQueryInformationFile [NTDLL.@]
@@ -1774,6 +1808,42 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
SERVER_END_REQ;
}
break;
+ case FileNameInformation:
+ {
+ FILE_NAME_INFORMATION *info = ptr;
+ ANSI_STRING unix_name;
+
+ if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
+ {
+ LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+ UNICODE_STRING nt_name;
+
+ io->u.Status = wine_unix_to_nt_file_name( &unix_name, &nt_name );
+ RtlFreeAnsiString( &unix_name );
+
+ if (!io->u.Status)
+ {
+ const WCHAR *ptr = nt_name.Buffer;
+ const WCHAR *end = ptr + (nt_name.Length / sizeof(WCHAR));
+
+ /* Skip the volume mount point. */
+ while (ptr != end && *ptr == '\\') ++ptr;
+ while (ptr != end && *ptr != '\\') ++ptr;
+ while (ptr != end && *ptr == '\\') ++ptr;
+ while (ptr != end && *ptr != '\\') ++ptr;
+
+ info->FileNameLength = (end - ptr) * sizeof(WCHAR);
+ if (name_len < info->FileNameLength) io->u.Status = STATUS_BUFFER_OVERFLOW;
+ else name_len = info->FileNameLength;
+
+ memcpy( info->FileName, ptr, name_len );
+ RtlFreeUnicodeString( &nt_name );
+
+ io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len;
+ }
+ }
+ }
+ break;
default:
FIXME("Unsupported class (%d)\n", class);
io->u.Status = STATUS_NOT_IMPLEMENTED;
More information about the wine-cvs
mailing list