ntdll: Move NtQueryObject/NtSetInformationObject to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
917a206b01
commit
518decf16b
|
@ -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.@]
|
||||
|
|
|
@ -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;
|
||||
|
|
192
dlls/ntdll/om.c
192
dlls/ntdll/om.c
|
@ -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 );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue