[PATCH v3] ntoskrnl.exe: Create the device interface symlink in IoSetDeviceInterfaceState

Zebediah Figura z.figura12 at gmail.com
Mon Nov 19 11:37:50 CST 2018


Well, if we're really sure this is how Windows does it...

On 11/16/2018 07:40 AM, Aric Stewart wrote:
 >  static CRITICAL_SECTION drivers_cs;
 >  static CRITICAL_SECTION_DEBUG critsect_debug =
 >  {
 > @@ -1346,9 +1366,27 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( 
UNICODE_STRING *name, BOOLEAN enable
 >      NTSTATUS ret;
 >      size_t len;
 >      GUID class;
 > +    struct wine_rb_entry *entry;
 > +    struct device_interface *iface;
 > +    UNICODE_STRING device_name;
 > +    WCHAR *nameW;
 > +    ULONG length;
 > +
 >
 >      TRACE("(%s, %d)\n", debugstr_us(name), enable);
 >
 > +    entry = wine_rb_get( &device_interfaces, name );
 > +    if (!entry)
 > +        return STATUS_OBJECT_NAME_NOT_FOUND;
 > +
 > +    iface = WINE_RB_ENTRY_VALUE( entry, struct device_interface, 
entry );
 > +
 > +    if (!enable && !iface->enabled)
 > +        return STATUS_OBJECT_NAME_NOT_FOUND;
 > +
 > +    if (enable && iface->enabled)
 > +        return STATUS_OBJECT_NAME_EXISTS;
 > +
 >      refstr = memrchrW(name->Buffer + 4, '\\', namelen - 4);
 >
 >      if (!guid_from_string( (refstr ? refstr : name->Buffer + 
namelen) - 38, &class ))
 > @@ -1391,6 +1429,37 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( 
UNICODE_STRING *name, BOOLEAN enable
 >
 >      heap_free( path );
 >
 > +    if (enable)
 > +    {
 > +        length = 0;
 > +        ret = IoGetDeviceProperty( iface->device, 
DevicePropertyPhysicalDeviceObjectName, 0, NULL, &length );
 > +        if (ret != STATUS_BUFFER_TOO_SMALL)
 > +            return ret;
 > +
 > +        nameW = HeapAlloc(GetProcessHeap(), 0, length);
 > +        ret = IoGetDeviceProperty( iface->device, 
DevicePropertyPhysicalDeviceObjectName, length, nameW, &length );
 > +        if (ret != STATUS_SUCCESS)
 > +        {
 > +            HeapFree(GetProcessHeap(), 0, nameW);
 > +            return ret;
 > +        }
 > +        RtlInitUnicodeString( &device_name, nameW );

On error paths we still leave the "Linked" state in the registry as 1, 
which seems undesirable. (Probably we should create the symlink first, 
as it'd be easier to clean it up than the registry key.)

 > +
 > +        TRACE( "Create link %s -> %s\n",debugstr_us(name), 
debugstr_us(&device_name) );
 > +
 > +        ret = IoCreateSymbolicLink( name, &device_name );

This trace seems superfluous; we have the same thing in 
IoCreateSymbolicLink().

 > +        if (ret == STATUS_SUCCESS)
 > +            iface->enabled = TRUE;
 > +
 > +        HeapFree(GetProcessHeap(), 0, nameW);
 > +    }
 > +    else
 > +    {
 > +        ret = IoDeleteSymbolicLink( name );
 > +        if (ret == STATUS_SUCCESS)
 > +            iface->enabled = FALSE;
 > +    }
 > +
 >      len = offsetof(DEV_BROADCAST_DEVICEINTERFACE_W, 
dbcc_name[namelen + 1]);
 >
 >      if ((broadcast = heap_alloc( len )))
 > @@ -1696,6 +1765,7 @@ NTSTATUS WINAPI 
IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla
 >      SP_DEVICE_INTERFACE_DETAIL_DATA_W *data;
 >      DWORD required;
 >      BOOL rc;
 > +    struct device_interface *iface;
 >
 >      TRACE( "(%p, %s, %s, %p)\n", device, debugstr_guid(class_guid), 
debugstr_us(reference_string), symbolic_link );
 >
 > @@ -1766,9 +1836,16 @@ NTSTATUS WINAPI 
IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla
 >      data->DevicePath[1] = '?';
 >      TRACE( "Device path %s\n",debugstr_w(data->DevicePath) );
 >
 > +    iface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
sizeof(struct device_interface));
 > +    iface->device = device;
 > +    iface->interface_class = *class_guid;
 > +    RtlCreateUnicodeString(&iface->symbolic_link, data->DevicePath);
 >      if (symbolic_link)
 >          RtlCreateUnicodeString( symbolic_link, data->DevicePath);
 >
 > +    if (wine_rb_put( &device_interfaces, &iface->symbolic_link, 
&iface->entry ))
 > +        ERR( "failed to insert interface %s into tree\n", 
debugstr_us(&iface->symbolic_link) );
 > +
 >      HeapFree( GetProcessHeap(), 0, data );
 >
 >      return status;



More information about the wine-devel mailing list