Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NetworkAccessProtectionExtensions SHV will not load? #2

Closed
yaplej opened this issue Jan 14, 2016 · 1 comment
Closed

NetworkAccessProtectionExtensions SHV will not load? #2

yaplej opened this issue Jan 14, 2016 · 1 comment

Comments

@yaplej
Copy link

yaplej commented Jan 14, 2016

Hello,

I downloaded the latest version of Visual Studio and copied the entire NetworkAccessProtectionExtensions solution. I was able to open and build the solution without any problems but the resulting SdkShv.dll will not load on my 2012 R2 server.

@yaplej
Copy link
Author

yaplej commented Jan 14, 2016

I got it to work by changing the Active config of the solution to Debug|x64 and rebuilding.

@yaplej yaplej closed this as completed Jan 14, 2016
jameshfisher added a commit to jameshfisher/Windows-classic-samples that referenced this issue May 2, 2020
Initially, this sample works as expected.
However, pressing Ctrl+Alt+Del causes the process to show a message box with the error `0x88760868`,
after which it stops displaying new frames.
The same behavior can be invoked by locking the screen (Windows+L),
or by putting the computer to sleep briefly.
This is apparently a bug in the official example.
I found at least 3 underlying bugs causing it,
which this patch resolves.

The error `0x88760868` is `D3DERR_DEVICELOST`,
returned by [`IDirect3DDevice9::Present`](https://docs.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9-present)
on [this line](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L478).
That error is documented as:

> The device has been lost but cannot be reset at this time.
> Therefore, rendering is not possible.
> A Direct3D device object other than the one that returned this code
> caused the hardware adapter to be reset by the OS.
> Delete all video memory objects (surfaces, textures, state blocks)
> and call Reset() to return the device to a default state.
> If the application continues rendering without a reset, the rendering calls will succeed.

This sample has [`DrawDevice::ResetDevice()`](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L532),
which appears to follow these reset instructions.
But `DrawDevice::ResetDevice()` is never called!

The program works with an `OnReadSample` callback,
which calls `ReadSample` to get the next sample.
However, [if drawing the frame fails, then it never requests the next frame](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/preview.cpp#L207-L215).
I believe this is a bug.
This leads to change microsoft#1 in this patch:

    Always request another frame,
    even if drawing failed (e.g. with `D3DERR_DEVICELOST`).

However, this alone doesn't resolve the issue.
After ensuring that the `OnReadSample` loop continues,
then [it does attempt to reset the device on the next sample](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L514).
And this does successfully recover --
as long as it calls it after the user has exited the lock screen and came back to their desktop.
One can see this by adding a `Sleep(3000)` before resetting,
then doing Ctrl+Alt+Delete,
then hitting Esc within less than 3 seconds.

But if it tries to reset the device while the user is still on the lock screen
(which is the ordinary case since it's on the very next sample),
then it fails forever.
ResetDevice first destroys the device, which succeeds; but then fails to recreate it.
The program fails to recreate the device when on the lock screen because
[`m_pD3D->CheckDeviceType`](https://docs.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3d9-checkdevicetype) fails with `0x8876086a`,
i.e. `D3DERR_NOTAVAILABLE`,
[at this point](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L197-L205).
According to the docs, this means
"the requested back buffer format is not supported, or hardware acceleration is not available for the specified formats."
I guess the process doesn't have access to the display while the lock screen is displayed?

From that point on,
we [repeatedly hit this condition](https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L414-L417)
where `DrawFrame` returns early without doing anything
if the device is not initialized.
This, I believe, is another bug,
and leads to change microsoft#2 in this patch:

    If `DrawFrame` finds that the device is not initialized,
    it should call `ResetDevice` to re-initialize it.

Effectively, it should repeatedly try to reset the device.
Eventually, when the user exits the lock screen,
it should succeed.
However, this is still not what happens!
What happens instead is that,
if resetting the device has previously failed with `D3DERR_NOTAVAILABLE`,
then resetting the device will always fail with `D3DERR_NOTAVAILABLE` forever more.

The reason, it turns out, is that `ResetDevice` does not clean up after itself properly.
There are at least two places where `ResetDevice` exits early,
but without cleaning up its partially-reset state:

    https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L552
    https://github.com/microsoft/Windows-classic-samples/blob/b89b2cd2a0b05bc393a5f21a9d39cadc9bbb6e2e/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureD3D/device.cpp#L559

This leads to change microsoft#3 in this patch:

    If ResetDevice fails for some reason,
    it should call DestroyDevice to clean up its partial state.

This finally leads to correct behavior:
after exiting the lock screen and returning to the desktop,
the process recreates the device and continues showing new samples.

(Also, this patch fixes an unrelated compile-time error
due to a narrowing warning being treated as an error.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant