[PATCH v2 1/2] ntoskrnl.exe: Implement IoRegisterDeviceInterface

Zebediah Figura z.figura12 at gmail.com
Wed Oct 3 22:24:13 CDT 2018


On 03/10/18 10:02, Aric Stewart wrote:
> +static NTSTATUS get_instance_id(DEVICE_OBJECT *device, WCHAR
**instance_id)
> +{
> +    WCHAR *id, *ptr;
> +    NTSTATUS status;
> +
> +    status = get_device_id( device, BusQueryInstanceID, &id );
> +    if (status != STATUS_SUCCESS)
> +    {
> +        FIXME( "failed to get device ID\n" );
> +        return status;
> +    }

Would ERR be more appropriate?

> +
> +    struprW( id );
> +    ptr = strchrW( id, '\\' );
> +
> +    while (ptr)
> +    {
> +        *ptr = '#';
> +        ptr = strchrW( id,'\\' );
> +    }

Stylistic choice, perhaps, but maybe this would be simpler?

while ((ptr = strchrW( id, '\\' )))
    *ptr = '#';

> +
> +    *instance_id = id;
> +    return STATUS_SUCCESS;
> +}
> +
> +
> +/*****************************************************
> + *           IoRegisterDeviceInterface(NTOSKRNL.EXE.@)
> + */
> +NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device,
const GUID *class_guid, UNICODE_STRING *reference_string, UNICODE_STRING
*symbolic_link)
> +{
> +    WCHAR *instance_id;
> +    NTSTATUS status = STATUS_SUCCESS;
> +    HDEVINFO infoset;
> +    WCHAR *referenceW = NULL;
> +    SP_DEVINFO_DATA devInfo;
> +    SP_DEVICE_INTERFACE_DATA infoData;
> +    SP_DEVICE_INTERFACE_DETAIL_DATA_W *data;
> +    BOOL rc;
> +
> +    TRACE( "(%p, %s, %s, %p)\n", device, debugstr_guid(class_guid),
debugstr_us(reference_string), symbolic_link );
> +
> +    if (reference_string != NULL)
> +        referenceW = reference_string->Buffer;
> +
> +    infoset = SetupDiGetClassDevsW(class_guid, referenceW, NULL,
DIGCF_DEVICEINTERFACE);
> +
> +    status = get_instance_id( device, &instance_id );
> +    if (status != STATUS_SUCCESS)
> +    {
> +        ERR( "Failed to generate Instance ID\n" );
> +        return status;
> +    }
> +
> +    devInfo.cbSize = sizeof(devInfo);
> +    rc = SetupDiCreateDeviceInfoW( infoset, instance_id, class_guid,
NULL, NULL, 0, &devInfo );
> +    if (rc == 0)
> +    {
> +        if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS)
> +        {
> +            DWORD required;
> +            DWORD index = 0;
> +            DWORD size = strlenW(instance_id) + 2;
> +            WCHAR *id = HeapAlloc(GetProcessHeap(), 0, size *
sizeof(WCHAR));
> +            do
> +            {
> +                rc = SetupDiEnumDeviceInfo( infoset, index, &devInfo );
> +                if (IsEqualGUID(&devInfo.ClassGuid, class_guid))
> +                {
> +                    BOOL check;
> +                    check = SetupDiGetDeviceInstanceIdW(infoset,
&devInfo, id, size, &required);
> +                    if (check && strcmpW(id, instance_id) == 0)
> +                        break;
> +                }
> +                index++;
> +            } while (rc);

I guess it maybe shouldn't block this patch, but it would be good to
implement SetupDiOpenDeviceInfo() at some point; it would result in much
cleaner code on both sides.

> +
> +            HeapFree(GetProcessHeap(), 0, id);
> +            if (!rc)
> +            {
> +                ERR( "Failed to find Device\n" );
> +                HeapFree( GetProcessHeap(), 0, instance_id );
> +                return STATUS_UNSUCCESSFUL;
> +            }
> +        }
> +        else
> +        {
> +            ERR( "Failed to Create Device\n" );
> +            HeapFree( GetProcessHeap(), 0, instance_id );
> +            return STATUS_UNSUCCESSFUL;
> +        }
> +    }
> +    HeapFree( GetProcessHeap(), 0, instance_id );
> +
> +    infoData.cbSize = sizeof(infoData);
> +    rc = SetupDiCreateDeviceInterfaceW(infoset, &devInfo, class_guid,
NULL, 0, &infoData);
> +    if (!rc)
> +    {
> +        ERR("Failed to create device interface\n");
> +        return STATUS_UNSUCCESSFUL;
> +    }
> +
> +    data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY ,
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 1000);

This seems kind of ugly; can't we just call it twice?

> +    data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
> +
> +    rc = SetupDiGetDeviceInterfaceDetailW(infoset, &infoData, data,
500, NULL, NULL);
> +    if (!rc)
> +    {
> +        ERR("Failed Get device details\n");
> +        return STATUS_UNSUCCESSFUL;
> +    }
> +
> +    data->DevicePath[1] = '?';
> +    ERR("Device path %s\n",debugstr_w(data->DevicePath));

Leftover debug string?

> +
> +    if (symbolic_link)
> +        RtlCreateUnicodeString( symbolic_link, data->DevicePath);
> +
> +    HeapFree( GetProcessHeap(), 0, data );
> +
> +    return status;
> +}
> +
> +
>  /***********************************************************************
>   *           IoRegisterDriverReinitialization    (NTOSKRNL.EXE.@)
>   */
> diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
> index 422d575926..1a6139de61 100644
> --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
> +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
> @@ -428,7 +428,7 @@
>  @ stub IoReadPartitionTableEx
>  @ stub IoReadTransferCount
>  @ stub IoRegisterBootDriverReinitialization
> -@ stub IoRegisterDeviceInterface
> +@ stdcall IoRegisterDeviceInterface(ptr ptr ptr ptr)
>  @ stdcall IoRegisterDriverReinitialization(ptr ptr ptr)
>  @ stdcall IoRegisterFileSystem(ptr)
>  @ stub IoRegisterFsRegistrationChange
> diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
> index 0cd1673dbe..cd057d5a9f 100644
> --- a/include/ddk/wdm.h
> +++ b/include/ddk/wdm.h
> @@ -1405,6 +1405,7 @@ PDEVICE_OBJECT WINAPI
IoGetRelatedDeviceObject(PFILE_OBJECT);
>  void      WINAPI IoInitializeIrp(IRP*,USHORT,CCHAR);
>  VOID      WINAPI
IoInitializeRemoveLockEx(PIO_REMOVE_LOCK,ULONG,ULONG,ULONG,ULONG);
>  void      WINAPI
IoInvalidateDeviceRelations(PDEVICE_OBJECT,DEVICE_RELATION_TYPE);
> +NTSTATUS  WINAPI IoRegisterDeviceInterface(PDEVICE_OBJECT,const
GUID*,PUNICODE_STRING,PUNICODE_STRING);
>  void      WINAPI IoReleaseCancelSpinLock(KIRQL);
>  NTSTATUS  WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN);
>  NTSTATUS  WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);



More information about the wine-devel mailing list