Discussion:
Get Device IOTarget from GUID in KMDF
(too old to reply)
Mark Scott
2010-07-06 06:51:09 UTC
Permalink
Hi,

In one of my KMDF driver I have exported the interface using
WdfDeviceCreateDeviceInterface.

From another KMDF driver I want to get the IoTarget of the first
driver. The second driver is only aware of the GUID of the first
driver.

I have tried the following approach :

WDFIOTARGET GetIoTarget(GUID Guid)
{
NTSTATUS status = STATUS_SUCCESS;
PWSTR DevName;
PDEVICE_OBJECT OutDevice;
PFILE_OBJECT FileObject;
PUNICODE_STRING Dev = NULL;
WDFDEVICE device;
WDFIOTARGET IoTarget = NULL;

status = IoGetDeviceInterfaces( &Guid, NULL, 0, &DevName);
if (!NT_SUCCESS(status))
{
return NULL;
}
RtlCreateUnicodeString(Dev, DevName);

status = IoGetDeviceObjectPointer( Dev,
GENERIC_ALL,
&FileObject,
&OutDevice);
if (!NT_SUCCESS(status))
{
return NULL;
}

RtlFreeUnicodeString(Dev);
ExFreePool(DevName);

device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
if( device == NULL )
{
return NULL;
}

IoTarget = WdfDeviceGetIoTarget(device);

return IoTarget;
}

However, this function fails to get the Device Name
(IoGetDeviceInterfaces returns success, with NULL in the DevName).

1. Is there anything wrong in the above approach ?
2. Is there any direct KMDF function call sequence that can be used
directly instead of using these WDM functions.

Thanks in Advance,
Mark
Doron Holan [MSFT]
2010-07-06 20:19:34 UTC
Permalink
overall the approach is correct, but there are 2 issues
1) use RtlInitUnicodeString instead of RtlCreateUnicodeString. this means
one less buffer to allocate
2) the symbolic link list returned by IoGetDeviceInterfaces is a multi SZ,
your code assumes only one name is in the string

even more importantly, WDF handles are local to each driver. you cannot go
and get another driver's handle, ie
Post by Mark Scott
device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
is not correct. you communicate with OutDevice using IRPs and you do not
touch it's extension of WDFDEVICE at all (even if the call to
WdfWdmDeviceGetWdfDeviceHandle succeeds, which it may not depending on the
version of KMDF). Once you have the name (Dev in this case), you can
substitute the IoGetDeviceObjectPointer call with a call to WdfIoTargetOpen
(on a WDFIOTARGET you created by calling WdfIoTargetCreate)

also, you are leaking Dev and DevName if IOGetDeviceObjectPointer returns
!NT_SUCCESS.

d

"Mark Scott" wrote in message news:1b501bfa-18e5-493b-ac86-***@y21g2000pro.googlegroups.com...

Hi,

In one of my KMDF driver I have exported the interface using
WdfDeviceCreateDeviceInterface.

From another KMDF driver I want to get the IoTarget of the first
driver. The second driver is only aware of the GUID of the first
driver.

I have tried the following approach :

WDFIOTARGET GetIoTarget(GUID Guid)
{
NTSTATUS status = STATUS_SUCCESS;
PWSTR DevName;
PDEVICE_OBJECT OutDevice;
PFILE_OBJECT FileObject;
PUNICODE_STRING Dev = NULL;
WDFDEVICE device;
WDFIOTARGET IoTarget = NULL;

status = IoGetDeviceInterfaces( &Guid, NULL, 0, &DevName);
if (!NT_SUCCESS(status))
{
return NULL;
}
RtlCreateUnicodeString(Dev, DevName);

status = IoGetDeviceObjectPointer( Dev,
GENERIC_ALL,
&FileObject,
&OutDevice);
if (!NT_SUCCESS(status))
{
return NULL;
}

RtlFreeUnicodeString(Dev);
ExFreePool(DevName);

device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
if( device == NULL )
{
return NULL;
}

IoTarget = WdfDeviceGetIoTarget(device);

return IoTarget;
}

However, this function fails to get the Device Name
(IoGetDeviceInterfaces returns success, with NULL in the DevName).

1. Is there anything wrong in the above approach ?
2. Is there any direct KMDF function call sequence that can be used
directly instead of using these WDM functions.

Thanks in Advance,
Mark
Mark Scott
2010-07-08 05:10:22 UTC
Permalink
Thanks for your suggestions.

I modified the function as follows:

void GetDeviceIoTarget(GUID DevGuid, WDFDEVICE Device, WDFIOTARGET
&IoTarget)
{
NTSTATUS status = STATUS_SUCCESS;
PWSTR DevName;
PUNICODE_STRING Dev = NULL;
WDF_IO_TARGET_OPEN_PARAMS OpenParams;

status = IoGetDeviceInterfaces( &DevGuid, NULL, 0, &DevName);
if (!NT_SUCCESS(status))
{

goto exit ;
}
RtlInitUnicodeString(Dev, DevName);

status = WdfIoTargetCreate( Device, WDF_NO_OBJECT_ATTRIBUTES,
*IoTarget);
if (!NT_SUCCESS(status))
{
goto exit ;
}

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( &OpenParams, Dev,
GENERIC_READ|GENERIC_WRITE);

status = WdfIoTargetOpen( *IoTarget, &OpenParams)
if (!NT_SUCCESS(status))
{
goto exit ;
}


exit:
RtlFreeUnicodeString(Dev);
ExFreePool(DevName);
return ;
}

Now this one also hangs in WdfIoTargetOpen, and the system needs to be
rebooted.
I could check through WinDbg, that the device name gets populated
properly.

Any suggestions, why WdfIoTargetOpen could hang.

Thanks,
Mark
Post by Doron Holan [MSFT]
overall the approach is correct, but there are 2 issues
1) use RtlInitUnicodeString instead of RtlCreateUnicodeString.  this means
one less buffer to allocate
2) the symbolic link list returned by IoGetDeviceInterfaces is a multi SZ,
your code assumes only one name is in the string
even more importantly, WDF handles are local to each driver. you cannot go
and get another driver's handle, ie
Post by Mark Scott
device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
is not correct.  you communicate with OutDevice using IRPs and you do not
touch it's extension of WDFDEVICE at all (even if the call to
WdfWdmDeviceGetWdfDeviceHandle succeeds, which it may not depending on the
version of KMDF). Once you have the name (Dev in this case), you can
substitute the IoGetDeviceObjectPointer call with a call to WdfIoTargetOpen
(on a WDFIOTARGET you created by calling WdfIoTargetCreate)
also, you are leaking Dev and DevName if IOGetDeviceObjectPointer returns
!NT_SUCCESS.
d
Hi,
In one of my KMDF driver  I have exported the interface using
WdfDeviceCreateDeviceInterface.
From another KMDF driver I want to get the IoTarget of the first
driver.  The second driver is only aware of the GUID of the first
driver.
WDFIOTARGET GetIoTarget(GUID Guid)
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR DevName;
    PDEVICE_OBJECT OutDevice;
    PFILE_OBJECT FileObject;
    PUNICODE_STRING Dev = NULL;
    WDFDEVICE device;
    WDFIOTARGET IoTarget = NULL;
    status = IoGetDeviceInterfaces( &Guid, NULL, 0, &DevName);
    if (!NT_SUCCESS(status))
    {
              return NULL;
    }
    RtlCreateUnicodeString(Dev, DevName);
    status =  IoGetDeviceObjectPointer( Dev,
            GENERIC_ALL,
            &FileObject,
            &OutDevice);
    if (!NT_SUCCESS(status))
    {
             return NULL;
    }
    RtlFreeUnicodeString(Dev);
    ExFreePool(DevName);
    device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
    if( device == NULL )
    {
        return NULL;
    }
    IoTarget = WdfDeviceGetIoTarget(device);
   return IoTarget;
}
However, this function fails to get the Device Name
(IoGetDeviceInterfaces returns success, with NULL  in the DevName).
1. Is there anything wrong in the above approach ?
2. Is there any direct KMDF function call sequence that can be used
directly instead of using these WDM functions.
Thanks in Advance,
Mark
Maxim S. Shatskih
2010-07-08 06:51:02 UTC
Permalink
Post by Mark Scott
Any suggestions, why WdfIoTargetOpen could hang.
Look at the stack of the hang.
--
Maxim S. Shatskih
Windows DDK MVP
***@storagecraft.com
http://www.storagecraft.com
Doron Holan [MSFT]
2010-07-08 19:02:06 UTC
Permalink
break into the debugger and dump the stack. that might give you a clue as to
where the hang is occurring and you can debug from there

d

"Mark Scott" wrote in message news:8f81bf84-42c8-475e-9c6c-***@k8g2000prh.googlegroups.com...

Thanks for your suggestions.

I modified the function as follows:

void GetDeviceIoTarget(GUID DevGuid, WDFDEVICE Device, WDFIOTARGET
&IoTarget)
{
NTSTATUS status = STATUS_SUCCESS;
PWSTR DevName;
PUNICODE_STRING Dev = NULL;
WDF_IO_TARGET_OPEN_PARAMS OpenParams;

status = IoGetDeviceInterfaces( &DevGuid, NULL, 0, &DevName);
if (!NT_SUCCESS(status))
{

goto exit ;
}
RtlInitUnicodeString(Dev, DevName);

status = WdfIoTargetCreate( Device, WDF_NO_OBJECT_ATTRIBUTES,
*IoTarget);
if (!NT_SUCCESS(status))
{
goto exit ;
}

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( &OpenParams, Dev,
GENERIC_READ|GENERIC_WRITE);

status = WdfIoTargetOpen( *IoTarget, &OpenParams)
if (!NT_SUCCESS(status))
{
goto exit ;
}


exit:
RtlFreeUnicodeString(Dev);
ExFreePool(DevName);
return ;
}

Now this one also hangs in WdfIoTargetOpen, and the system needs to be
rebooted.
I could check through WinDbg, that the device name gets populated
properly.

Any suggestions, why WdfIoTargetOpen could hang.

Thanks,
Mark
Post by Doron Holan [MSFT]
overall the approach is correct, but there are 2 issues
1) use RtlInitUnicodeString instead of RtlCreateUnicodeString. this means
one less buffer to allocate
2) the symbolic link list returned by IoGetDeviceInterfaces is a multi SZ,
your code assumes only one name is in the string
even more importantly, WDF handles are local to each driver. you cannot go
and get another driver's handle, ie
Post by Mark Scott
device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
is not correct. you communicate with OutDevice using IRPs and you do not
touch it's extension of WDFDEVICE at all (even if the call to
WdfWdmDeviceGetWdfDeviceHandle succeeds, which it may not depending on the
version of KMDF). Once you have the name (Dev in this case), you can
substitute the IoGetDeviceObjectPointer call with a call to
WdfIoTargetOpen
(on a WDFIOTARGET you created by calling WdfIoTargetCreate)
also, you are leaking Dev and DevName if IOGetDeviceObjectPointer returns
!NT_SUCCESS.
d
Hi,
In one of my KMDF driver I have exported the interface using
WdfDeviceCreateDeviceInterface.
From another KMDF driver I want to get the IoTarget of the first
driver. The second driver is only aware of the GUID of the first
driver.
WDFIOTARGET GetIoTarget(GUID Guid)
{
NTSTATUS status = STATUS_SUCCESS;
PWSTR DevName;
PDEVICE_OBJECT OutDevice;
PFILE_OBJECT FileObject;
PUNICODE_STRING Dev = NULL;
WDFDEVICE device;
WDFIOTARGET IoTarget = NULL;
status = IoGetDeviceInterfaces( &Guid, NULL, 0, &DevName);
if (!NT_SUCCESS(status))
{
return NULL;
}
RtlCreateUnicodeString(Dev, DevName);
status = IoGetDeviceObjectPointer( Dev,
GENERIC_ALL,
&FileObject,
&OutDevice);
if (!NT_SUCCESS(status))
{
return NULL;
}
RtlFreeUnicodeString(Dev);
ExFreePool(DevName);
device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
if( device == NULL )
{
return NULL;
}
IoTarget = WdfDeviceGetIoTarget(device);
return IoTarget;
}
However, this function fails to get the Device Name
(IoGetDeviceInterfaces returns success, with NULL in the DevName).
1. Is there anything wrong in the above approach ?
2. Is there any direct KMDF function call sequence that can be used
directly instead of using these WDM functions.
Thanks in Advance,
Mark
Mark Scott
2010-07-13 05:39:34 UTC
Permalink
The issue is now resolved.

WdfIoTargetOpen invokes the EvtDeviceFileCreate routine of the second
driver, where the request needs to be completed. If the request is
not completed, the system hangs.

Thanks for your inputs and suggestions.


-Mark
Post by Doron Holan [MSFT]
break into the debugger and dump the stack. that might give you a clue as to
where the hang is occurring and you can debug from there
d
Thanks for your suggestions.
void GetDeviceIoTarget(GUID DevGuid, WDFDEVICE Device, WDFIOTARGET
&IoTarget)
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR DevName;
    PUNICODE_STRING Dev = NULL;
    WDF_IO_TARGET_OPEN_PARAMS OpenParams;
    status = IoGetDeviceInterfaces( &DevGuid, NULL, 0, &DevName);
    if (!NT_SUCCESS(status))
    {
        goto exit ;
    }
    RtlInitUnicodeString(Dev, DevName);
    status = WdfIoTargetCreate( Device, WDF_NO_OBJECT_ATTRIBUTES,
*IoTarget);
    if (!NT_SUCCESS(status))
    {
              goto exit ;
    }
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( &OpenParams, Dev,
GENERIC_READ|GENERIC_WRITE);
    status = WdfIoTargetOpen( *IoTarget,  &OpenParams)
    if (!NT_SUCCESS(status))
    {
            goto exit ;
    }
    RtlFreeUnicodeString(Dev);
    ExFreePool(DevName);
    return ;
}
Now this one also hangs in WdfIoTargetOpen, and the system needs to be
rebooted.
I could check through WinDbg, that the  device name gets populated
properly.
Any suggestions, why WdfIoTargetOpen could hang.
Thanks,
Mark
Post by Doron Holan [MSFT]
overall the approach is correct, but there are 2 issues
1) use RtlInitUnicodeString instead of RtlCreateUnicodeString.  this means
one less buffer to allocate
2) the symbolic link list returned by IoGetDeviceInterfaces is a multi SZ,
your code assumes only one name is in the string
even more importantly, WDF handles are local to each driver. you cannot go
and get another driver's handle, ie
Post by Mark Scott
device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
is not correct.  you communicate with OutDevice using IRPs and you do not
touch it's extension of WDFDEVICE at all (even if the call to
WdfWdmDeviceGetWdfDeviceHandle succeeds, which it may not depending on the
version of KMDF). Once you have the name (Dev in this case), you can
substitute the IoGetDeviceObjectPointer call with a call to
WdfIoTargetOpen
(on a WDFIOTARGET you created by calling WdfIoTargetCreate)
also, you are leaking Dev and DevName if IOGetDeviceObjectPointer returns
!NT_SUCCESS.
d
Hi,
In one of my KMDF driver  I have exported the interface using
WdfDeviceCreateDeviceInterface.
From another KMDF driver I want to get the IoTarget of the first
driver.  The second driver is only aware of the GUID of the first
driver.
WDFIOTARGET GetIoTarget(GUID Guid)
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR DevName;
    PDEVICE_OBJECT OutDevice;
    PFILE_OBJECT FileObject;
    PUNICODE_STRING Dev = NULL;
    WDFDEVICE device;
    WDFIOTARGET IoTarget = NULL;
    status = IoGetDeviceInterfaces( &Guid, NULL, 0, &DevName);
    if (!NT_SUCCESS(status))
    {
              return NULL;
    }
    RtlCreateUnicodeString(Dev, DevName);
    status =  IoGetDeviceObjectPointer( Dev,
            GENERIC_ALL,
            &FileObject,
            &OutDevice);
    if (!NT_SUCCESS(status))
    {
             return NULL;
    }
    RtlFreeUnicodeString(Dev);
    ExFreePool(DevName);
    device = WdfWdmDeviceGetWdfDeviceHandle(OutDevice);
    if( device == NULL )
    {
        return NULL;
    }
    IoTarget = WdfDeviceGetIoTarget(device);
   return IoTarget;
}
However, this function fails to get the Device Name
(IoGetDeviceInterfaces returns success, with NULL  in the DevName).
1. Is there anything wrong in the above approach ?
2. Is there any direct KMDF function call sequence that can be used
directly instead of using these WDM functions.
Thanks in Advance,
Mark
Loading...