Commit 715edfb0 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

mountmgr.sys: Move dhcp lookup to a worker thread.

While this is a reasonable change per se, the motivation is to avoid a deadlock when mountmgr.sys calls into iphlpapi and further into nsiproxy.sys via the nsi device. nsiproxy.sys is hosted by the same process as mountmgr.sys so is unable to handle the request while it is also waiting for that same request to return. The correct long-term solution is for mountmgr.sys to call the netio.sys versions of the iphlpapi functions. These will call the kernel-side versions of the nsi functions without going through the nsi device. Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 34a9d3e4
...@@ -286,32 +286,48 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize ) ...@@ -286,32 +286,48 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize )
} }
/* implementation of IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS */ /* implementation of IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS */
static NTSTATUS query_dhcp_request_params( void *buff, SIZE_T insize, static void WINAPI query_dhcp_request_params( TP_CALLBACK_INSTANCE *instance, void *context )
SIZE_T outsize, IO_STATUS_BLOCK *iosb )
{ {
struct mountmgr_dhcp_request_params *query = buff; IRP *irp = context;
ULONG i, offset; struct mountmgr_dhcp_request_params *query = irp->AssociatedIrp.SystemBuffer;
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
SIZE_T insize = irpsp->Parameters.DeviceIoControl.InputBufferLength;
SIZE_T outsize = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
ULONG i, offset = 0;
/* sanity checks */ /* sanity checks */
if (FIELD_OFFSET(struct mountmgr_dhcp_request_params, params[query->count]) > insize || if (FIELD_OFFSET(struct mountmgr_dhcp_request_params, params[query->count]) > insize ||
!memchrW( query->adapter, 0, ARRAY_SIZE(query->adapter) )) return STATUS_INVALID_PARAMETER; !memchrW( query->adapter, 0, ARRAY_SIZE(query->adapter) ))
{
irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
goto err;
}
for (i = 0; i < query->count; i++) for (i = 0; i < query->count; i++)
if (query->params[i].offset + query->params[i].size > insize) return STATUS_INVALID_PARAMETER; if (query->params[i].offset + query->params[i].size > insize)
{
irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
goto err;
}
offset = FIELD_OFFSET(struct mountmgr_dhcp_request_params, params[query->count]); offset = FIELD_OFFSET(struct mountmgr_dhcp_request_params, params[query->count]);
for (i = 0; i < query->count; i++) for (i = 0; i < query->count; i++)
{ {
offset += get_dhcp_request_param( query->adapter, &query->params[i], buff, offset, outsize - offset ); offset += get_dhcp_request_param( query->adapter, &query->params[i], (char *)query, offset, outsize - offset );
if (offset > outsize) if (offset > outsize)
{ {
if (offset >= sizeof(query->size)) query->size = offset; if (offset >= sizeof(query->size)) query->size = offset;
iosb->Information = sizeof(query->size); offset = sizeof(query->size);
return STATUS_MORE_ENTRIES; irp->IoStatus.u.Status = STATUS_MORE_ENTRIES;
goto err;
} }
} }
irp->IoStatus.u.Status = STATUS_SUCCESS;
iosb->Information = offset; err:
return STATUS_SUCCESS; irp->IoStatus.Information = offset;
IoCompleteRequest( irp, IO_NO_INCREMENT );
} }
/* implementation of Wine extension to use host APIs to find symbol file by GUID */ /* implementation of Wine extension to use host APIs to find symbol file by GUID */
...@@ -929,10 +945,10 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp ) ...@@ -929,10 +945,10 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
break; break;
} }
status = query_dhcp_request_params( irp->AssociatedIrp.SystemBuffer,
irpsp->Parameters.DeviceIoControl.InputBufferLength, if (TrySubmitThreadpoolCallback( query_dhcp_request_params, irp, NULL ))
irpsp->Parameters.DeviceIoControl.OutputBufferLength, return (irp->IoStatus.u.Status = STATUS_PENDING);
&irp->IoStatus ); status = STATUS_NO_MEMORY;
break; break;
#ifdef __APPLE__ #ifdef __APPLE__
case IOCTL_MOUNTMGR_QUERY_SYMBOL_FILE: case IOCTL_MOUNTMGR_QUERY_SYMBOL_FILE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment