Wddm filter driver problem[Extension of Desktop Win7]

I have modified based on this site’s code framework.[http://www.justkernel.com/Blogs/?p=149#comment-19684],this is the wddm filter driver!
enumerate, add source and destination to VidPn, I can see more monitors at the screen resolution of the desktop properties!

  1. the virtual monitor cannot modify the resolution
  2. he virtual monitor When the device settings extension or copy function is saved.there is a problem that the settings cannot be saved!

I have already referenced the Microsoft official VIDPN information.[https://docs.microsoft.com/en-us/windows-hardware/drivers/display/multiple-monitors-and-video-present-networks]
I don’t know where something went wrong, please help me, thanks!

I support the virtual child device and video source associated paths in the DxgkDdiIsSupportedVidPn function, such as Paths(source->target):(0 <-> 0), (1 <-> 4),

DxgkDdiEnumVidPnCofuncModality function specifies the target ID = 4, other target IDs are omitted, in Here I add source mode and target mode to this ID=4 path.

First about DxgkDdiIsSupportedVidPn:
DirectX graphics kernel expects that every Video Present Source can drive every Video Present Target. The description above looks wrong when source 0 can only drive target 0 and source 1 can only drive target 4.

Second about DxgkDdiEnumVidPnCofuncModality:
The correct implementation in a WDDM filter hook driver is extremely difficult.
The question above indicates that even the problem is not yet fully understood.
Only after understanding the problem, it makes sense to start thinking about a solution.

Here is the problem of implementing DxgkDdiEnumVidPnCofuncModality:
DxgkDdiEnumVidPnCofuncModality only gets ONE video Present Network as a parameter.
In a hook driver, this ONE Video Present Network can have Video Present Paths of TWO kinds:

  1. Paths containing only ORIGINAL targets and sources created by the hooked original display driver.
  2. Paths containing targets and sources ADDED by the hook driver.

A Video Present Network containing ADDED paths can not be handed to the hooked original display driver as a function parameter!

The problem: How can the hooked original display driver handle his ORIGINAL Video Present Paths without being confused by the ADDED paths?

Two approaches:

  1. Only hook the Video Present network callback interface (hook DxgkCbQueryVidPnInterface including all the subsequent callbacks handed out by this interface). Then hide/skip paths when the hooked original driver is enumerating them.
  2. Implement your own Video Present Network logic and delegate an own newly created Video Present Network handle to the hooked original display driver.
    The easier one of the two approaches usually takes in between half a year and a year of development and testing on all different graphics adapters.

Just to limit the frustration in case of failure: This approach is completely unsupported by Microsoft Windows. I have seen many developers and companies who tried this and failed (including the website mentioned above - announcing a solution since 2011 but never succeeded). Worldwide, only a very small (single digit) number of developers/companies succeeded.

Marcel Ruedinger

datronicsoft

Thank you, Marcel

I asked the following questions:

  1. [Paths contains targets and sources ADDED by the hook driver], the hook driver must add the path containing the target and the source by itself? In DxgkDdiEnumVidPnCofuncModality function, enumerate all the paths, I can see the path (1<->4) by printing the log, but I did not take the initiative to add this path,
  2. [Only hook the Video Present network callback interface (hook
    DxgkCbQueryVidPnInterface including all the subsequent callbacks handed out by
    This interface). Then hide/skip paths when the hooked original driver is
    Enumering them.] Yes, I am currently doing this, I can clearly see the following sequence according to the print path information: 0<->0.
    ?Step 1 - Pivot = D3DKMDT_EPT_NOPIVOT
    ???Paths: (0 <-> 0)
    ???Source: N/A
    ???Target: N/A

???Step 2 - Pivot = D3DKMDT_EPT_VIDPNSOURCE
???Paths: (0 <-> 0)
???Source: (0 => xxxxx@A8R8G8B8)
???Target: N/A

???Step 3 - Pivot = D3DKMDT_EPT_VIDPNTARGET
???Paths: (0 <-> 0)
???Source: (0 => xxxxx@A8R8G8B8)
???Target: (0 => xxxxx@75Hx)

???Step 4 - Pivot = D3DKMDT_EPT_SCALING
???Paths: (0 <-> 0) (IdentityScaling)
???Source: (0 => xxxxx@A8R8G8B8)
???Target: (0 => xxxxx@75Hz)

???Step 5 - Pivot = D3DKMDT_EPT_ROTATION
???Paths: (0 <-> 0) (IdentityScaling,UnRotated)
???Source: (0 => xxxxx@A8R8G8B8)
???Target: (0 => xxxxx@75Hz)
?
But what I am wondering is, according to the above steps, the source pattern set and the target pattern set are added, and the rotation and zoom functions are supported. The result is not expected.

DHui Luo

  1. You DID take the initiative. This additional path was added by dxgkrnl.sys as a result of:
  • Incrementing the returned variable NumberOfChildren in DxgkDdiStartDevice.
  • Giving additional child information in DxgkddiQueryChildRelations.
  • Allowing the additional path in DxgkDdiIsSupportedVidPn (otherwise it would never get to EnumVidPnCofuncModality).
  1. Why would the result not be expected? The hooked driver is adding information to the path containing his known source and his known target.

Marcel Ruedinger

datronicsoft

Thank you, Marcel.

In DxgkDdiIsSupportedVidPn, I enumerate all paths. When the target ID of the path is the new child ID in DxgkddiQueryChildRelations, the hook driver sets IsVidPnSupported=true and returns STATUS_SUCCESS.
but in DxgkDdiEnumVidPnCofuncModality, I don’t see the corresponding path. Is my practice in DxgkDdiIsSupportedVidPn correct or does it need to change the system environment?

In DxgkDdiIsSupportedVidPn, is it necessary to check the ID (eg targetID=4) the source and destination of the path have a fixed mode, if there is no pinned modes, return STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY?

Maybe still confused by the “code framework” initially mentioned above?
I already commented on it here in this forum in November/December 2011.
Ever since it has always remained a piece of messed up botch without any chance to operate properly.

If you want to start turning it into something reasonable, then at first you have to remove the worst piece of junk code below:




pIrp = IoBuildDeviceIoControlRequest(IOCTL_VIDEO_CREATE_CHILD,DeviceObject, NULL, 0, &m_Buffer, sizeof(m_Buffer), TRUE, &evt, &ios);

PIO_STACK_LOCATION pIrpStack =
IoGetCurrentIrpStackLocation( pIrp ); //debug

if (pIrp != NULL)
{
status = IoCallDriver(DeviceObject, pIrp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL);
status = ios.Status;
}
}

Did you already remove this?
Do you already expose your Video Present Child the correct way instead (calling DxgkcbIndicateChildStatus and implementing DxgkDdiQueryChildStatus)?

Marcel Ruedinger

datronicsoft

Hi,Thanks.

I have implemented DxgkDdiQueryChildStatus, how to call DxgkcbIndicateChildStatus, where to call?

DHui Luo

DxgkCbIndicateChildStatus is called whenever the WDDM driver has detected that a new monitor is plugged or a plugged monitor is unplugged. It can be called any time after the three steps below have completed:

  • DxgkDdiStartDevice has received the function pointer for DxgkCbIndicateChildStatus.
  • DxgkDdiStartDevice has returned the number ouf VidPn Sources and Targets.
  • DxgkDdiQueryChildRelations has returned information about Children/Video Present Targets.

PS: You might as well try if it can already be called in DxgkDdiStartDevice. I don’t remember the result of trying if that worked or if that was too early.

Marcel Ruedinger

datronicsoft