From: Mark Scott on
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
From: Doron Holan [MSFT] on
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
> 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-d13179987d00(a)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

From: Mark Scott on
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


On Jul 7, 1:19 am, "Doron Holan [MSFT]" <dor...(a)online.microsoft.com>
wrote:
> 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
>
> > 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-d13179987d00(a)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

From: Maxim S. Shatskih on
>Any suggestions, why WdfIoTargetOpen could hang.

Look at the stack of the hang.

--
Maxim S. Shatskih
Windows DDK MVP
maxim(a)storagecraft.com
http://www.storagecraft.com

From: Doron Holan [MSFT] on
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-4da1b804fc8d(a)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


On Jul 7, 1:19 am, "Doron Holan [MSFT]" <dor...(a)online.microsoft.com>
wrote:
> 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
>
> > 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-d13179987d00(a)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