[PATCH v2 1/6] mountmgr.sys: Move dhcp lookup to a worker thread.

Huw Davies huw at codeweavers.com
Tue Jul 6 04:11:47 CDT 2021


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: Huw Davies <huw at codeweavers.com>
---
 dlls/mountmgr.sys/mountmgr.c | 46 ++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 61d51d8e61d..b94944a350c 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -286,32 +286,48 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize )
 }
 
 /* implementation of IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS */
-static NTSTATUS query_dhcp_request_params( void *buff, SIZE_T insize,
-                                           SIZE_T outsize, IO_STATUS_BLOCK *iosb )
+static void WINAPI query_dhcp_request_params( TP_CALLBACK_INSTANCE *instance, void *context )
 {
-    struct mountmgr_dhcp_request_params *query = buff;
-    ULONG i, offset;
+    IRP *irp = context;
+    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 */
     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++)
-        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]);
     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 >= sizeof(query->size)) query->size = offset;
-            iosb->Information = sizeof(query->size);
-            return STATUS_MORE_ENTRIES;
+            offset = sizeof(query->size);
+            irp->IoStatus.u.Status = STATUS_MORE_ENTRIES;
+            goto err;
         }
     }
+    irp->IoStatus.u.Status = STATUS_SUCCESS;
 
-    iosb->Information = offset;
-    return STATUS_SUCCESS;
+err:
+    irp->IoStatus.Information = offset;
+    IoCompleteRequest( irp, IO_NO_INCREMENT );
 }
 
 /* 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 )
             status = STATUS_INVALID_PARAMETER;
             break;
         }
-        status = query_dhcp_request_params( irp->AssociatedIrp.SystemBuffer,
-                                            irpsp->Parameters.DeviceIoControl.InputBufferLength,
-                                            irpsp->Parameters.DeviceIoControl.OutputBufferLength,
-                                            &irp->IoStatus );
+
+        if (TrySubmitThreadpoolCallback( query_dhcp_request_params, irp, NULL ))
+            return (irp->IoStatus.u.Status = STATUS_PENDING);
+        status = STATUS_NO_MEMORY;
         break;
 #ifdef __APPLE__
     case IOCTL_MOUNTMGR_QUERY_SYMBOL_FILE:
-- 
2.23.0




More information about the wine-devel mailing list