ntdll: Implement the FileNameInformation class for NtQueryInformationFile().

This commit is contained in:
Henri Verbeet 2009-11-12 15:10:13 +01:00 committed by Alexandre Julliard
parent 27705d51e1
commit cd6d01ac9d
1 changed files with 70 additions and 0 deletions

View File

@ -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;