diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index b81d38ce602..741395ddbd2 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1633,7 +1633,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS return STATUS_SUCCESS; } -static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) +NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) { data_size_t size = 1024; NTSTATUS ret; diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index e1e67ead9de..32966b75ed9 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -142,6 +142,7 @@ extern NTSTATUS TAPE_DeviceIoControl(HANDLE hDevice, struct stat; extern NTSTATUS FILE_GetNtStatus(void); extern NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ); +extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ); extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ); extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ); extern NTSTATUS DIR_unmount_device( HANDLE handle ); diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index e9677d0c18f..c5d9b84ccab 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -88,6 +88,34 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle, case ObjectNameInformation: { OBJECT_NAME_INFORMATION* p = ptr; + ANSI_STRING unix_name; + + /* first try as a file object */ + + if (!(status = server_get_unix_name( handle, &unix_name ))) + { + UNICODE_STRING nt_name; + NTSTATUS status; + + if (!(status = wine_unix_to_nt_file_name( &unix_name, &nt_name ))) + { + if (sizeof(*p) + nt_name.MaximumLength <= len) + { + p->Name.Buffer = (WCHAR *)(p + 1); + p->Name.Length = nt_name.Length; + p->Name.MaximumLength = nt_name.MaximumLength; + memcpy( p->Name.Buffer, nt_name.Buffer, nt_name.MaximumLength ); + } + else status = STATUS_INFO_LENGTH_MISMATCH; + if (used_len) *used_len = sizeof(*p) + nt_name.MaximumLength; + RtlFreeUnicodeString( &nt_name ); + } + RtlFreeAnsiString( &unix_name ); + break; + } + else if (status != STATUS_OBJECT_TYPE_MISMATCH) break; + + /* not a file, treat as a generic object */ SERVER_START_REQ( get_object_info ) { diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index cf9a1a54757..1bab21d9805 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -627,6 +627,7 @@ static void test_query_object(void) NTSTATUS status; ULONG len; UNICODE_STRING *str; + char dir[MAX_PATH]; handle = CreateEventA( NULL, FALSE, FALSE, "test_event" ); @@ -667,6 +668,18 @@ static void test_query_object(void) ok( str->Length == 0, "unexpected len %u\n", len ); ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer ); pNtClose( handle ); + + GetWindowsDirectoryA( dir, MAX_PATH ); + handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0 ); + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); } START_TEST(om)