ntdll: Move NtQueryObject/NtSetInformationObject to the Unix library.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-08 12:21:38 +02:00
parent 917a206b01
commit 518decf16b
6 changed files with 219 additions and 227 deletions

View File

@ -214,40 +214,6 @@ NTSTATUS WINAPI NtSetVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
return unix_funcs->NtSetVolumeInformationFile( handle, io, info, length, class );
}
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.@]

View File

@ -89,8 +89,6 @@ extern const WCHAR syswow64_dir[] DECLSPEC_HIDDEN;
extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
/* file I/O */
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void init_directories(void) DECLSPEC_HIDDEN;
extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;

View File

@ -47,166 +47,7 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
IN OBJECT_INFORMATION_CLASS info_class,
OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
{
NTSTATUS status;
TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", handle, info_class, ptr, len, used_len);
if (used_len) *used_len = 0;
switch (info_class)
{
case ObjectBasicInformation:
{
POBJECT_BASIC_INFORMATION p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( get_object_info )
{
req->handle = wine_server_obj_handle( handle );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
memset( p, 0, sizeof(*p) );
p->GrantedAccess = reply->access;
p->PointerCount = reply->ref_count;
p->HandleCount = reply->handle_count;
if (used_len) *used_len = sizeof(*p);
}
}
SERVER_END_REQ;
}
break;
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;
if (!(status = wine_unix_to_nt_file_name( &unix_name, &nt_name )))
{
if (len < sizeof(*p))
status = STATUS_INFO_LENGTH_MISMATCH;
else if (len < sizeof(*p) + nt_name.MaximumLength)
status = STATUS_BUFFER_OVERFLOW;
else
{
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 );
}
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 )
{
req->handle = wine_server_obj_handle( handle );
if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
if (!reply->total) /* no name */
{
if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
else memset( p, 0, sizeof(*p) );
if (used_len) *used_len = sizeof(*p);
}
else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
{
if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
ULONG res = wine_server_reply_size( reply );
p->Name.Buffer = (WCHAR *)(p + 1);
p->Name.Length = res;
p->Name.MaximumLength = res + sizeof(WCHAR);
p->Name.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->Name.MaximumLength;
}
}
}
SERVER_END_REQ;
}
break;
case ObjectTypeInformation:
{
OBJECT_TYPE_INFORMATION *p = ptr;
SERVER_START_REQ( get_object_type )
{
req->handle = wine_server_obj_handle( handle );
if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
if (!reply->total) /* no name */
{
if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
else memset( p, 0, sizeof(*p) );
if (used_len) *used_len = sizeof(*p);
}
else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
{
if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
ULONG res = wine_server_reply_size( reply );
p->TypeName.Buffer = (WCHAR *)(p + 1);
p->TypeName.Length = res;
p->TypeName.MaximumLength = res + sizeof(WCHAR);
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
}
}
SERVER_END_REQ;
}
break;
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( set_handle_info )
{
req->handle = wine_server_obj_handle( handle );
req->flags = 0;
req->mask = 0;
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) != 0;
p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
if (used_len) *used_len = sizeof(*p);
}
}
SERVER_END_REQ;
}
break;
default:
FIXME("Unsupported information class %u\n", info_class);
status = STATUS_NOT_IMPLEMENTED;
break;
}
return status;
return unix_funcs->NtQueryObject( handle, info_class, ptr, len, used_len );
}
/******************************************************************
@ -218,36 +59,7 @@ NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
IN OBJECT_INFORMATION_CLASS info_class,
IN PVOID ptr, IN ULONG len)
{
NTSTATUS status;
TRACE("(%p,0x%08x,%p,0x%08x)\n", handle, info_class, ptr, len);
switch (info_class)
{
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( set_handle_info )
{
req->handle = wine_server_obj_handle( handle );
req->flags = 0;
req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
status = wine_server_call( req );
}
SERVER_END_REQ;
}
break;
default:
FIXME("Unsupported information class %u\n", info_class);
status = STATUS_NOT_IMPLEMENTED;
break;
}
return status;
return unix_funcs->NtSetInformationObject( handle, info_class, ptr, len );
}
/******************************************************************************

View File

@ -6323,3 +6323,213 @@ NTSTATUS WINAPI NtSetVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
FIXME( "(%p,%p,%p,0x%08x,0x%08x) stub\n", handle, io, info, length, class );
return STATUS_SUCCESS;
}
/**************************************************************************
* NtQueryObject
*/
NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_class,
void *ptr, ULONG len, ULONG *used_len )
{
NTSTATUS status;
TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", handle, info_class, ptr, len, used_len);
if (used_len) *used_len = 0;
switch (info_class)
{
case ObjectBasicInformation:
{
OBJECT_BASIC_INFORMATION *p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( get_object_info )
{
req->handle = wine_server_obj_handle( handle );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
memset( p, 0, sizeof(*p) );
p->GrantedAccess = reply->access;
p->PointerCount = reply->ref_count;
p->HandleCount = reply->handle_count;
if (used_len) *used_len = sizeof(*p);
}
}
SERVER_END_REQ;
break;
}
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;
if (!(status = unix_to_nt_file_name( &unix_name, &nt_name )))
{
if (len < sizeof(*p)) status = STATUS_INFO_LENGTH_MISMATCH;
else if (len < sizeof(*p) + nt_name.MaximumLength) status = STATUS_BUFFER_OVERFLOW;
else
{
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 );
}
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 )
{
req->handle = wine_server_obj_handle( handle );
if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
if (!reply->total) /* no name */
{
if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
else memset( p, 0, sizeof(*p) );
if (used_len) *used_len = sizeof(*p);
}
else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
{
if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
ULONG res = wine_server_reply_size( reply );
p->Name.Buffer = (WCHAR *)(p + 1);
p->Name.Length = res;
p->Name.MaximumLength = res + sizeof(WCHAR);
p->Name.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->Name.MaximumLength;
}
}
}
SERVER_END_REQ;
break;
}
case ObjectTypeInformation:
{
OBJECT_TYPE_INFORMATION *p = ptr;
SERVER_START_REQ( get_object_type )
{
req->handle = wine_server_obj_handle( handle );
if (len > sizeof(*p)) wine_server_set_reply( req, p + 1, len - sizeof(*p) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
if (!reply->total) /* no name */
{
if (sizeof(*p) > len) status = STATUS_INFO_LENGTH_MISMATCH;
else memset( p, 0, sizeof(*p) );
if (used_len) *used_len = sizeof(*p);
}
else if (sizeof(*p) + reply->total + sizeof(WCHAR) > len)
{
if (used_len) *used_len = sizeof(*p) + reply->total + sizeof(WCHAR);
status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
ULONG res = wine_server_reply_size( reply );
p->TypeName.Buffer = (WCHAR *)(p + 1);
p->TypeName.Length = res;
p->TypeName.MaximumLength = res + sizeof(WCHAR);
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
}
}
SERVER_END_REQ;
break;
}
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( set_handle_info )
{
req->handle = wine_server_obj_handle( handle );
req->flags = 0;
req->mask = 0;
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) != 0;
p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) != 0;
if (used_len) *used_len = sizeof(*p);
}
}
SERVER_END_REQ;
break;
}
default:
FIXME("Unsupported information class %u\n", info_class);
status = STATUS_NOT_IMPLEMENTED;
break;
}
return status;
}
/**************************************************************************
* NtSetInformationObject
*/
NTSTATUS WINAPI NtSetInformationObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_class,
void *ptr, ULONG len )
{
NTSTATUS status;
TRACE("(%p,0x%08x,%p,0x%08x)\n", handle, info_class, ptr, len);
switch (info_class)
{
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
SERVER_START_REQ( set_handle_info )
{
req->handle = wine_server_obj_handle( handle );
req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
status = wine_server_call( req );
}
SERVER_END_REQ;
break;
}
default:
FIXME("Unsupported information class %u\n", info_class);
status = STATUS_NOT_IMPLEMENTED;
break;
}
return status;
}

View File

@ -1431,6 +1431,7 @@ static struct unix_funcs unix_funcs =
NtQueryInformationThread,
NtQueryIoCompletion,
NtQueryMutant,
NtQueryObject,
NtQueryPerformanceCounter,
NtQuerySection,
NtQuerySemaphore,
@ -1458,6 +1459,7 @@ static struct unix_funcs unix_funcs =
NtSetEvent,
NtSetInformationFile,
NtSetInformationJobObject,
NtSetInformationObject,
NtSetInformationProcess,
NtSetInformationThread,
NtSetIoCompletion,

View File

@ -28,7 +28,7 @@ struct msghdr;
struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 72
#define NTDLL_UNIXLIB_VERSION 73
struct unix_funcs
{
@ -161,6 +161,8 @@ struct unix_funcs
void *buffer, ULONG len, ULONG *ret_len );
NTSTATUS (WINAPI *NtQueryMutant)( HANDLE handle, MUTANT_INFORMATION_CLASS class,
void *info, ULONG len, ULONG *ret_len );
NTSTATUS (WINAPI *NtQueryObject)( HANDLE handle, OBJECT_INFORMATION_CLASS info_class,
void *ptr, ULONG len, ULONG *used_len );
NTSTATUS (WINAPI *NtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency );
NTSTATUS (WINAPI *NtQuerySection)( HANDLE handle, SECTION_INFORMATION_CLASS class,
void *ptr, SIZE_T size, SIZE_T *ret_size );
@ -211,6 +213,8 @@ struct unix_funcs
void *ptr, ULONG len, FILE_INFORMATION_CLASS class );
NTSTATUS (WINAPI *NtSetInformationJobObject)( HANDLE handle, JOBOBJECTINFOCLASS class,
void *info, ULONG len );
NTSTATUS (WINAPI *NtSetInformationObject)( HANDLE handle, OBJECT_INFORMATION_CLASS info_class,
void *ptr, ULONG len );
NTSTATUS (WINAPI *NtSetInformationProcess)( HANDLE handle, PROCESSINFOCLASS class,
void *info, ULONG size );
NTSTATUS (WINAPI *NtSetInformationThread)( HANDLE handle, THREADINFOCLASS class,