19#include <freerdp/config.h> 
   22#include <winpr/print.h> 
   23#include <winpr/library.h> 
   24#include <freerdp/log.h> 
   28#define TAG SERVER_TAG("shadow.win") 
   32static D3D_DRIVER_TYPE DriverTypes[] = {
 
   33  D3D_DRIVER_TYPE_HARDWARE,
 
   35  D3D_DRIVER_TYPE_REFERENCE,
 
   38static UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
 
   40static D3D_FEATURE_LEVEL FeatureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1,
 
   41                                           D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_1 };
 
   43static UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
 
   45static HMODULE d3d11_module = NULL;
 
   47typedef HRESULT(WINAPI* fnD3D11CreateDevice)(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType,
 
   48                                             HMODULE Software, UINT Flags,
 
   49                                             CONST D3D_FEATURE_LEVEL* pFeatureLevels,
 
   50                                             UINT FeatureLevels, UINT SDKVersion,
 
   51                                             ID3D11Device** ppDevice,
 
   52                                             D3D_FEATURE_LEVEL* pFeatureLevel,
 
   53                                             ID3D11DeviceContext** ppImmediateContext);
 
   55static fnD3D11CreateDevice pfnD3D11CreateDevice = NULL;
 
   64DEFINE_GUID(IID_ID3D11DeviceChild, 0x1841e5c8, 0x16b0, 0x489b, 0xbc, 0xc8, 0x44, 0xcf, 0xb0, 0xd5,
 
   66DEFINE_GUID(IID_ID3D11DepthStencilState, 0x03823efb, 0x8d8f, 0x4e1c, 0x9a, 0xa2, 0xf6, 0x4b, 0xb2,
 
   68DEFINE_GUID(IID_ID3D11BlendState, 0x75b68faa, 0x347d, 0x4159, 0x8f, 0x45, 0xa0, 0x64, 0x0f, 0x01,
 
   70DEFINE_GUID(IID_ID3D11RasterizerState, 0x9bb4ab81, 0xab1a, 0x4d8f, 0xb5, 0x06, 0xfc, 0x04, 0x20,
 
   72DEFINE_GUID(IID_ID3D11Resource, 0xdc8e63f3, 0xd12b, 0x4952, 0xb4, 0x7b, 0x5e, 0x45, 0x02, 0x6a,
 
   74DEFINE_GUID(IID_ID3D11Buffer, 0x48570b85, 0xd1ee, 0x4fcd, 0xa2, 0x50, 0xeb, 0x35, 0x07, 0x22, 0xb0,
 
   76DEFINE_GUID(IID_ID3D11Texture1D, 0xf8fb5c27, 0xc6b3, 0x4f75, 0xa4, 0xc8, 0x43, 0x9a, 0xf2, 0xef,
 
   78DEFINE_GUID(IID_ID3D11Texture2D, 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3,
 
   80DEFINE_GUID(IID_ID3D11Texture3D, 0x037e866e, 0xf56d, 0x4357, 0xa8, 0xaf, 0x9d, 0xab, 0xbe, 0x6e,
 
   82DEFINE_GUID(IID_ID3D11View, 0x839d1216, 0xbb2e, 0x412b, 0xb7, 0xf4, 0xa9, 0xdb, 0xeb, 0xe0, 0x8e,
 
   84DEFINE_GUID(IID_ID3D11ShaderResourceView, 0xb0e06fe0, 0x8192, 0x4e1a, 0xb1, 0xca, 0x36, 0xd7, 0x41,
 
   86DEFINE_GUID(IID_ID3D11RenderTargetView, 0xdfdba067, 0x0b8d, 0x4865, 0x87, 0x5b, 0xd7, 0xb4, 0x51,
 
   88DEFINE_GUID(IID_ID3D11DepthStencilView, 0x9fdac92a, 0x1876, 0x48c3, 0xaf, 0xad, 0x25, 0xb9, 0x4f,
 
   90DEFINE_GUID(IID_ID3D11UnorderedAccessView, 0x28acf509, 0x7f5c, 0x48f6, 0x86, 0x11, 0xf3, 0x16, 0x01,
 
   92DEFINE_GUID(IID_ID3D11VertexShader, 0x3b301d64, 0xd678, 0x4289, 0x88, 0x97, 0x22, 0xf8, 0x92, 0x8b,
 
   94DEFINE_GUID(IID_ID3D11HullShader, 0x8e5c6061, 0x628a, 0x4c8e, 0x82, 0x64, 0xbb, 0xe4, 0x5c, 0xb3,
 
   96DEFINE_GUID(IID_ID3D11DomainShader, 0xf582c508, 0x0f36, 0x490c, 0x99, 0x77, 0x31, 0xee, 0xce, 0x26,
 
   98DEFINE_GUID(IID_ID3D11GeometryShader, 0x38325b96, 0xeffb, 0x4022, 0xba, 0x02, 0x2e, 0x79, 0x5b,
 
  100DEFINE_GUID(IID_ID3D11PixelShader, 0xea82e40d, 0x51dc, 0x4f33, 0x93, 0xd4, 0xdb, 0x7c, 0x91, 0x25,
 
  102DEFINE_GUID(IID_ID3D11ComputeShader, 0x4f5b196e, 0xc2bd, 0x495e, 0xbd, 0x01, 0x1f, 0xde, 0xd3, 0x8e,
 
  104DEFINE_GUID(IID_ID3D11InputLayout, 0xe4819ddc, 0x4cf0, 0x4025, 0xbd, 0x26, 0x5d, 0xe8, 0x2a, 0x3e,
 
  106DEFINE_GUID(IID_ID3D11SamplerState, 0xda6fea51, 0x564c, 0x4487, 0x98, 0x10, 0xf0, 0xd0, 0xf9, 0xb4,
 
  108DEFINE_GUID(IID_ID3D11Asynchronous, 0x4b35d0cd, 0x1e15, 0x4258, 0x9c, 0x98, 0x1b, 0x13, 0x33, 0xf6,
 
  110DEFINE_GUID(IID_ID3D11Query, 0xd6c00747, 0x87b7, 0x425e, 0xb8, 0x4d, 0x44, 0xd1, 0x08, 0x56, 0x0a,
 
  112DEFINE_GUID(IID_ID3D11Predicate, 0x9eb576dd, 0x9f77, 0x4d86, 0x81, 0xaa, 0x8b, 0xab, 0x5f, 0xe4,
 
  114DEFINE_GUID(IID_ID3D11Counter, 0x6e8c49fb, 0xa371, 0x4770, 0xb4, 0x40, 0x29, 0x08, 0x60, 0x22, 0xb7,
 
  116DEFINE_GUID(IID_ID3D11ClassInstance, 0xa6cd7faa, 0xb0b7, 0x4a2f, 0x94, 0x36, 0x86, 0x62, 0xa6, 0x57,
 
  118DEFINE_GUID(IID_ID3D11ClassLinkage, 0xddf57cba, 0x9543, 0x46e4, 0xa1, 0x2b, 0xf2, 0x07, 0xa0, 0xfe,
 
  120DEFINE_GUID(IID_ID3D11CommandList, 0xa24bc4d1, 0x769e, 0x43f7, 0x80, 0x13, 0x98, 0xff, 0x56, 0x6c,
 
  122DEFINE_GUID(IID_ID3D11DeviceContext, 0xc0bfa96c, 0xe089, 0x44fb, 0x8e, 0xaf, 0x26, 0xf8, 0x79, 0x61,
 
  124DEFINE_GUID(IID_ID3D11VideoDecoder, 0x3C9C5B51, 0x995D, 0x48d1, 0x9B, 0x8D, 0xFA, 0x5C, 0xAE, 0xDE,
 
  126DEFINE_GUID(IID_ID3D11VideoProcessorEnumerator, 0x31627037, 0x53AB, 0x4200, 0x90, 0x61, 0x05, 0xFA,
 
  127            0xA9, 0xAB, 0x45, 0xF9);
 
  128DEFINE_GUID(IID_ID3D11VideoProcessor, 0x1D7B0652, 0x185F, 0x41c6, 0x85, 0xCE, 0x0C, 0x5B, 0xE3,
 
  130DEFINE_GUID(IID_ID3D11AuthenticatedChannel, 0x3015A308, 0xDCBD, 0x47aa, 0xA7, 0x47, 0x19, 0x24,
 
  131            0x86, 0xD1, 0x4D, 0x4A);
 
  132DEFINE_GUID(IID_ID3D11CryptoSession, 0x9B32F9AD, 0xBDCC, 0x40a6, 0xA3, 0x9D, 0xD5, 0xC8, 0x65, 0x84,
 
  134DEFINE_GUID(IID_ID3D11VideoDecoderOutputView, 0xC2931AEA, 0x2A85, 0x4f20, 0x86, 0x0F, 0xFB, 0xA1,
 
  135            0xFD, 0x25, 0x6E, 0x18);
 
  136DEFINE_GUID(IID_ID3D11VideoProcessorInputView, 0x11EC5A5F, 0x51DC, 0x4945, 0xAB, 0x34, 0x6E, 0x8C,
 
  137            0x21, 0x30, 0x0E, 0xA5);
 
  138DEFINE_GUID(IID_ID3D11VideoProcessorOutputView, 0xA048285E, 0x25A9, 0x4527, 0xBD, 0x93, 0xD6, 0x8B,
 
  139            0x68, 0xC4, 0x42, 0x54);
 
  140DEFINE_GUID(IID_ID3D11VideoContext, 0x61F21C45, 0x3C0E, 0x4a74, 0x9C, 0xEA, 0x67, 0x10, 0x0D, 0x9A,
 
  142DEFINE_GUID(IID_ID3D11VideoDevice, 0x10EC4D5B, 0x975A, 0x4689, 0xB9, 0xE4, 0xD0, 0xAA, 0xC3, 0x0F,
 
  144DEFINE_GUID(IID_ID3D11Device, 0xdb6f6ddb, 0xac77, 0x4e88, 0x82, 0x53, 0x81, 0x9d, 0xf9, 0xbb, 0xf1,
 
  149DEFINE_GUID(IID_IDXGIObject, 0xaec22fb8, 0x76f3, 0x4639, 0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a,
 
  151DEFINE_GUID(IID_IDXGIDeviceSubObject, 0x3d3e0379, 0xf9de, 0x4d58, 0xbb, 0x6c, 0x18, 0xd6, 0x29,
 
  153DEFINE_GUID(IID_IDXGIResource, 0x035f3ab4, 0x482e, 0x4e50, 0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96,
 
  155DEFINE_GUID(IID_IDXGIKeyedMutex, 0x9d8e1289, 0xd7b3, 0x465f, 0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a,
 
  157DEFINE_GUID(IID_IDXGISurface, 0xcafcb56c, 0x6ac3, 0x4889, 0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60,
 
  159DEFINE_GUID(IID_IDXGISurface1, 0x4AE63092, 0x6327, 0x4c1b, 0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B,
 
  161DEFINE_GUID(IID_IDXGIAdapter, 0x2411e7e1, 0x12ac, 0x4ccf, 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d,
 
  163DEFINE_GUID(IID_IDXGIOutput, 0xae02eedb, 0xc735, 0x4690, 0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13,
 
  165DEFINE_GUID(IID_IDXGISwapChain, 0x310d36a0, 0xd2e7, 0x4c0a, 0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8,
 
  167DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3,
 
  169DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8,
 
  171DEFINE_GUID(IID_IDXGIFactory1, 0x770aae78, 0xf26f, 0x4dba, 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3,
 
  173DEFINE_GUID(IID_IDXGIAdapter1, 0x29038f61, 0x3839, 0x4626, 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a,
 
  175DEFINE_GUID(IID_IDXGIDevice1, 0x77db970f, 0x6276, 0x48ba, 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39,
 
  180DEFINE_GUID(IID_IDXGIDisplayControl, 0xea9dbf1a, 0xc88e, 0x4486, 0x85, 0x4a, 0x98, 0xaa, 0x01, 0x38,
 
  182DEFINE_GUID(IID_IDXGIOutputDuplication, 0x191cfac3, 0xa341, 0x470d, 0xb2, 0x6e, 0xa8, 0x64, 0xf4,
 
  184DEFINE_GUID(IID_IDXGISurface2, 0xaba496dd, 0xb617, 0x4cb8, 0xa8, 0x66, 0xbc, 0x44, 0xd7, 0xeb, 0x1f,
 
  186DEFINE_GUID(IID_IDXGIResource1, 0x30961379, 0x4609, 0x4a41, 0x99, 0x8e, 0x54, 0xfe, 0x56, 0x7e,
 
  188DEFINE_GUID(IID_IDXGIDevice2, 0x05008617, 0xfbfd, 0x4051, 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6,
 
  190DEFINE_GUID(IID_IDXGISwapChain1, 0x790a45f7, 0x0d42, 0x4876, 0x98, 0x3a, 0x0a, 0x55, 0xcf, 0xe6,
 
  192DEFINE_GUID(IID_IDXGIFactory2, 0x50c83a1c, 0xe072, 0x4c48, 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6,
 
  194DEFINE_GUID(IID_IDXGIAdapter2, 0x0AA1AE0A, 0xFA0E, 0x4B84, 0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC,
 
  196DEFINE_GUID(IID_IDXGIOutput1, 0x00cddea8, 0x939b, 0x4b83, 0xa3, 0x40, 0xa6, 0x85, 0x22, 0x66, 0x66,
 
  199const char* GetDxgiErrorString(HRESULT hr)
 
  203    case DXGI_STATUS_OCCLUDED:
 
  204      return "DXGI_STATUS_OCCLUDED";
 
  205    case DXGI_STATUS_CLIPPED:
 
  206      return "DXGI_STATUS_CLIPPED";
 
  207    case DXGI_STATUS_NO_REDIRECTION:
 
  208      return "DXGI_STATUS_NO_REDIRECTION";
 
  209    case DXGI_STATUS_NO_DESKTOP_ACCESS:
 
  210      return "DXGI_STATUS_NO_DESKTOP_ACCESS";
 
  211    case DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE:
 
  212      return "DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE";
 
  213    case DXGI_STATUS_MODE_CHANGED:
 
  214      return "DXGI_STATUS_MODE_CHANGED";
 
  215    case DXGI_STATUS_MODE_CHANGE_IN_PROGRESS:
 
  216      return "DXGI_STATUS_MODE_CHANGE_IN_PROGRESS";
 
  217    case DXGI_ERROR_INVALID_CALL:
 
  218      return "DXGI_ERROR_INVALID_CALL";
 
  219    case DXGI_ERROR_NOT_FOUND:
 
  220      return "DXGI_ERROR_NOT_FOUND";
 
  221    case DXGI_ERROR_MORE_DATA:
 
  222      return "DXGI_ERROR_MORE_DATA";
 
  223    case DXGI_ERROR_UNSUPPORTED:
 
  224      return "DXGI_ERROR_UNSUPPORTED";
 
  225    case DXGI_ERROR_DEVICE_REMOVED:
 
  226      return "DXGI_ERROR_DEVICE_REMOVED";
 
  227    case DXGI_ERROR_DEVICE_HUNG:
 
  228      return "DXGI_ERROR_DEVICE_HUNG";
 
  229    case DXGI_ERROR_DEVICE_RESET:
 
  230      return "DXGI_ERROR_DEVICE_RESET";
 
  231    case DXGI_ERROR_WAS_STILL_DRAWING:
 
  232      return "DXGI_ERROR_WAS_STILL_DRAWING";
 
  233    case DXGI_ERROR_FRAME_STATISTICS_DISJOINT:
 
  234      return "DXGI_ERROR_FRAME_STATISTICS_DISJOINT";
 
  235    case DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE:
 
  236      return "DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE";
 
  237    case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
 
  238      return "DXGI_ERROR_DRIVER_INTERNAL_ERROR";
 
  239    case DXGI_ERROR_NONEXCLUSIVE:
 
  240      return "DXGI_ERROR_NONEXCLUSIVE";
 
  241    case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
 
  242      return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE";
 
  243    case DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED:
 
  244      return "DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED";
 
  245    case DXGI_ERROR_REMOTE_OUTOFMEMORY:
 
  246      return "DXGI_ERROR_REMOTE_OUTOFMEMORY";
 
  247    case DXGI_ERROR_ACCESS_LOST:
 
  248      return "DXGI_ERROR_ACCESS_LOST";
 
  249    case DXGI_ERROR_WAIT_TIMEOUT:
 
  250      return "DXGI_ERROR_WAIT_TIMEOUT";
 
  251    case DXGI_ERROR_SESSION_DISCONNECTED:
 
  252      return "DXGI_ERROR_SESSION_DISCONNECTED";
 
  253    case DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE:
 
  254      return "DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE";
 
  255    case DXGI_ERROR_CANNOT_PROTECT_CONTENT:
 
  256      return "DXGI_ERROR_CANNOT_PROTECT_CONTENT";
 
  257    case DXGI_ERROR_ACCESS_DENIED:
 
  258      return "DXGI_ERROR_ACCESS_DENIED";
 
  259    case DXGI_ERROR_NAME_ALREADY_EXISTS:
 
  260      return "DXGI_ERROR_NAME_ALREADY_EXISTS";
 
  261    case DXGI_ERROR_SDK_COMPONENT_MISSING:
 
  262      return "DXGI_ERROR_SDK_COMPONENT_MISSING";
 
  263    case DXGI_STATUS_UNOCCLUDED:
 
  264      return "DXGI_STATUS_UNOCCLUDED";
 
  265    case DXGI_STATUS_DDA_WAS_STILL_DRAWING:
 
  266      return "DXGI_STATUS_DDA_WAS_STILL_DRAWING";
 
  267    case DXGI_ERROR_MODE_CHANGE_IN_PROGRESS:
 
  268      return "DXGI_ERROR_MODE_CHANGE_IN_PROGRESS";
 
  269    case DXGI_DDI_ERR_WASSTILLDRAWING:
 
  270      return "DXGI_DDI_ERR_WASSTILLDRAWING";
 
  271    case DXGI_DDI_ERR_UNSUPPORTED:
 
  272      return "DXGI_DDI_ERR_UNSUPPORTED";
 
  273    case DXGI_DDI_ERR_NONEXCLUSIVE:
 
  274      return "DXGI_DDI_ERR_NONEXCLUSIVE";
 
  276      return "DXGI_ERROR_ACCESS_DENIED";
 
  279  return "DXGI_ERROR_UNKNOWN";
 
  282static void win_shadow_d3d11_module_init()
 
  287  d3d11_module = LoadLibraryA(
"d3d11.dll");
 
  292  pfnD3D11CreateDevice = GetProcAddressAs(d3d11_module, 
"D3D11CreateDevice", fnD3D11CreateDevice);
 
  295int win_shadow_dxgi_init_duplication(winShadowSubsystem* subsystem)
 
  299  IDXGIOutput* pOutput;
 
  300  DXGI_OUTPUT_DESC outputDesc = { 0 };
 
  301  DXGI_OUTPUT_DESC* pOutputDesc;
 
  302  D3D11_TEXTURE2D_DESC textureDesc;
 
  303  IDXGIDevice* dxgiDevice = NULL;
 
  304  IDXGIAdapter* dxgiAdapter = NULL;
 
  305  IDXGIOutput* dxgiOutput = NULL;
 
  306  IDXGIOutput1* dxgiOutput1 = NULL;
 
  308  hr = subsystem->dxgiDevice->lpVtbl->QueryInterface(subsystem->dxgiDevice, &IID_IDXGIDevice,
 
  309                                                     (
void**)&dxgiDevice);
 
  313    WLog_ERR(TAG, 
"ID3D11Device::QueryInterface(IDXGIDevice) failure: %s (0x%08lX)",
 
  314             GetDxgiErrorString(hr), hr);
 
  318  hr = dxgiDevice->lpVtbl->GetParent(dxgiDevice, &IID_IDXGIAdapter, (
void**)&dxgiAdapter);
 
  322    dxgiDevice->lpVtbl->Release(dxgiDevice);
 
  328    WLog_ERR(TAG, 
"IDXGIDevice::GetParent(IDXGIAdapter) failure: %s (0x%08lX)",
 
  329             GetDxgiErrorString(hr), hr);
 
  335  while (dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, i, &pOutput) != DXGI_ERROR_NOT_FOUND)
 
  337    pOutputDesc = &outputDesc;
 
  339    hr = pOutput->lpVtbl->GetDesc(pOutput, pOutputDesc);
 
  343      WLog_ERR(TAG, 
"IDXGIOutput::GetDesc failure: %s (0x%08lX)", GetDxgiErrorString(hr), hr);
 
  347    if (pOutputDesc->AttachedToDesktop)
 
  350    pOutput->lpVtbl->Release(pOutput);
 
  356  hr = dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, dTop, &dxgiOutput);
 
  360    dxgiAdapter->lpVtbl->Release(dxgiAdapter);
 
  366    WLog_ERR(TAG, 
"IDXGIAdapter::EnumOutputs failure: %s (0x%08lX)", GetDxgiErrorString(hr),
 
  371  hr = dxgiOutput->lpVtbl->QueryInterface(dxgiOutput, &IID_IDXGIOutput1, (
void**)&dxgiOutput1);
 
  375    dxgiOutput->lpVtbl->Release(dxgiOutput);
 
  381    WLog_ERR(TAG, 
"IDXGIOutput::QueryInterface(IDXGIOutput1) failure: %s (0x%08lX)",
 
  382             GetDxgiErrorString(hr), hr);
 
  386  hr = dxgiOutput1->lpVtbl->DuplicateOutput(dxgiOutput1, (IUnknown*)subsystem->dxgiDevice,
 
  387                                            &(subsystem->dxgiOutputDuplication));
 
  391    dxgiOutput1->lpVtbl->Release(dxgiOutput1);
 
  397    WLog_ERR(TAG, 
"IDXGIOutput1::DuplicateOutput failure: %s (0x%08lX)", GetDxgiErrorString(hr),
 
  402  textureDesc.Width = subsystem->width;
 
  403  textureDesc.Height = subsystem->height;
 
  404  textureDesc.MipLevels = 1;
 
  405  textureDesc.ArraySize = 1;
 
  406  textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
 
  407  textureDesc.SampleDesc.Count = 1;
 
  408  textureDesc.SampleDesc.Quality = 0;
 
  409  textureDesc.Usage = D3D11_USAGE_STAGING;
 
  410  textureDesc.BindFlags = 0;
 
  411  textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
 
  412  textureDesc.MiscFlags = 0;
 
  414  hr = subsystem->dxgiDevice->lpVtbl->CreateTexture2D(subsystem->dxgiDevice, &textureDesc, NULL,
 
  415                                                      &(subsystem->dxgiStage));
 
  419    WLog_ERR(TAG, 
"ID3D11Device::CreateTexture2D failure: %s (0x%08lX)", GetDxgiErrorString(hr),
 
  427int win_shadow_dxgi_init(winShadowSubsystem* subsystem)
 
  432  UINT DriverTypeIndex;
 
  433  IDXGIDevice* DxgiDevice = NULL;
 
  434  IDXGIAdapter* DxgiAdapter = NULL;
 
  435  IDXGIOutput* DxgiOutput = NULL;
 
  436  IDXGIOutput1* DxgiOutput1 = NULL;
 
  438  win_shadow_d3d11_module_init();
 
  440  if (!pfnD3D11CreateDevice)
 
  443  for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
 
  445    hr = pfnD3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels,
 
  446                              NumFeatureLevels, D3D11_SDK_VERSION, &(subsystem->dxgiDevice),
 
  447                              &(subsystem->featureLevel), &(subsystem->dxgiDeviceContext));
 
  455    WLog_ERR(TAG, 
"D3D11CreateDevice failure: 0x%08lX", hr);
 
  459  status = win_shadow_dxgi_init_duplication(subsystem);
 
  464int win_shadow_dxgi_uninit(winShadowSubsystem* subsystem)
 
  466  if (subsystem->dxgiStage)
 
  468    subsystem->dxgiStage->lpVtbl->Release(subsystem->dxgiStage);
 
  469    subsystem->dxgiStage = NULL;
 
  472  if (subsystem->dxgiDesktopImage)
 
  474    subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
 
  475    subsystem->dxgiDesktopImage = NULL;
 
  478  if (subsystem->dxgiOutputDuplication)
 
  480    subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication);
 
  481    subsystem->dxgiOutputDuplication = NULL;
 
  484  if (subsystem->dxgiDeviceContext)
 
  486    subsystem->dxgiDeviceContext->lpVtbl->Release(subsystem->dxgiDeviceContext);
 
  487    subsystem->dxgiDeviceContext = NULL;
 
  490  if (subsystem->dxgiDevice)
 
  492    subsystem->dxgiDevice->lpVtbl->Release(subsystem->dxgiDevice);
 
  493    subsystem->dxgiDevice = NULL;
 
  499int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem, BYTE** ppDstData,
 
  500                                     int* pnDstStep, 
int x, 
int y, 
int width, 
int height)
 
  505  DXGI_MAPPED_RECT mappedRect;
 
  507  if ((width * height) < 1)
 
  512  Box.right = x + width;
 
  513  Box.bottom = y + height;
 
  517  subsystem->dxgiDeviceContext->lpVtbl->CopySubresourceRegion(
 
  518      subsystem->dxgiDeviceContext, (ID3D11Resource*)subsystem->dxgiStage, 0, 0, 0, 0,
 
  519      (ID3D11Resource*)subsystem->dxgiDesktopImage, 0, &Box);
 
  521  hr = subsystem->dxgiStage->lpVtbl->QueryInterface(subsystem->dxgiStage, &IID_IDXGISurface,
 
  522                                                    (
void**)&(subsystem->dxgiSurface));
 
  526    WLog_ERR(TAG, 
"ID3D11Texture2D::QueryInterface(IDXGISurface) failure: %s 0x%08lX",
 
  527             GetDxgiErrorString(hr), hr);
 
  531  hr = subsystem->dxgiSurface->lpVtbl->Map(subsystem->dxgiSurface, &mappedRect, DXGI_MAP_READ);
 
  535    WLog_ERR(TAG, 
"IDXGISurface::Map failure: %s 0x%08lX", GetDxgiErrorString(hr), hr);
 
  537    if (hr == DXGI_ERROR_DEVICE_REMOVED)
 
  539      win_shadow_dxgi_uninit(subsystem);
 
  541      status = win_shadow_dxgi_init(subsystem);
 
  552  subsystem->dxgiSurfaceMapped = TRUE;
 
  554  *ppDstData = mappedRect.pBits;
 
  555  *pnDstStep = mappedRect.Pitch;
 
  560int win_shadow_dxgi_release_frame_data(winShadowSubsystem* subsystem)
 
  562  if (subsystem->dxgiSurface)
 
  564    if (subsystem->dxgiSurfaceMapped)
 
  566      subsystem->dxgiSurface->lpVtbl->Unmap(subsystem->dxgiSurface);
 
  567      subsystem->dxgiSurfaceMapped = FALSE;
 
  570    subsystem->dxgiSurface->lpVtbl->Release(subsystem->dxgiSurface);
 
  571    subsystem->dxgiSurface = NULL;
 
  574  if (subsystem->dxgiOutputDuplication)
 
  576    if (subsystem->dxgiFrameAcquired)
 
  578      subsystem->dxgiOutputDuplication->lpVtbl->ReleaseFrame(
 
  579          subsystem->dxgiOutputDuplication);
 
  580      subsystem->dxgiFrameAcquired = FALSE;
 
  584  subsystem->pendingFrames = 0;
 
  589int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem)
 
  595  UINT DataBufferSize = 0;
 
  596  BYTE* DataBuffer = NULL;
 
  598  if (subsystem->dxgiFrameAcquired)
 
  600    win_shadow_dxgi_release_frame_data(subsystem);
 
  603  if (subsystem->dxgiDesktopImage)
 
  605    subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
 
  606    subsystem->dxgiDesktopImage = NULL;
 
  609  hr = subsystem->dxgiOutputDuplication->lpVtbl->AcquireNextFrame(
 
  610      subsystem->dxgiOutputDuplication, timeout, &(subsystem->dxgiFrameInfo),
 
  611      &(subsystem->dxgiResource));
 
  615    subsystem->dxgiFrameAcquired = TRUE;
 
  616    subsystem->pendingFrames = subsystem->dxgiFrameInfo.AccumulatedFrames;
 
  619  if (hr == DXGI_ERROR_WAIT_TIMEOUT)
 
  624    WLog_ERR(TAG, 
"IDXGIOutputDuplication::AcquireNextFrame failure: %s (0x%08lX)",
 
  625             GetDxgiErrorString(hr), hr);
 
  627    if (hr == DXGI_ERROR_ACCESS_LOST)
 
  629      win_shadow_dxgi_release_frame_data(subsystem);
 
  631      if (subsystem->dxgiDesktopImage)
 
  633        subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
 
  634        subsystem->dxgiDesktopImage = NULL;
 
  637      if (subsystem->dxgiOutputDuplication)
 
  639        subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication);
 
  640        subsystem->dxgiOutputDuplication = NULL;
 
  643      status = win_shadow_dxgi_init_duplication(subsystem);
 
  650    else if (hr == DXGI_ERROR_INVALID_CALL)
 
  652      win_shadow_dxgi_uninit(subsystem);
 
  654      status = win_shadow_dxgi_init(subsystem);
 
  665  hr = subsystem->dxgiResource->lpVtbl->QueryInterface(
 
  666      subsystem->dxgiResource, &IID_ID3D11Texture2D, (
void**)&(subsystem->dxgiDesktopImage));
 
  668  if (subsystem->dxgiResource)
 
  670    subsystem->dxgiResource->lpVtbl->Release(subsystem->dxgiResource);
 
  671    subsystem->dxgiResource = NULL;
 
  676    WLog_ERR(TAG, 
"IDXGIResource::QueryInterface(ID3D11Texture2D) failure: %s (0x%08lX)",
 
  677             GetDxgiErrorString(hr), hr);
 
  684int win_shadow_dxgi_get_invalid_region(winShadowSubsystem* subsystem)
 
  694  UINT MetadataBufferSize;
 
  695  UINT MoveRectsBufferSize;
 
  696  UINT DirtyRectsBufferSize;
 
  697  RECT* pDirtyRectsBuffer;
 
  698  DXGI_OUTDUPL_MOVE_RECT* pMoveRect;
 
  699  DXGI_OUTDUPL_MOVE_RECT* pMoveRectBuffer;
 
  700  rdpShadowSurface* surface = subsystem->server->surface;
 
  702  if (subsystem->dxgiFrameInfo.AccumulatedFrames == 0)
 
  705  if (subsystem->dxgiFrameInfo.TotalMetadataBufferSize == 0)
 
  708  MetadataBufferSize = subsystem->dxgiFrameInfo.TotalMetadataBufferSize;
 
  710  if (MetadataBufferSize > subsystem->MetadataBufferSize)
 
  712    subsystem->MetadataBuffer = (BYTE*)realloc(subsystem->MetadataBuffer, MetadataBufferSize);
 
  714    if (!subsystem->MetadataBuffer)
 
  717    subsystem->MetadataBufferSize = MetadataBufferSize;
 
  724  MoveRectsBufferSize = MetadataBufferSize - UsedBufferSize;
 
  725  pMoveRectBuffer = (DXGI_OUTDUPL_MOVE_RECT*)&(subsystem->MetadataBuffer[UsedBufferSize]);
 
  727  hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameMoveRects(
 
  728      subsystem->dxgiOutputDuplication, MoveRectsBufferSize, pMoveRectBuffer,
 
  729      &MoveRectsBufferSize);
 
  734             "IDXGIOutputDuplication::GetFrameMoveRects failure: %s (0x%08lX) Size: %u Total " 
  736             GetDxgiErrorString(hr), hr, MoveRectsBufferSize, MetadataBufferSize,
 
  743  UsedBufferSize += MoveRectsBufferSize;
 
  745  DirtyRectsBufferSize = MetadataBufferSize - UsedBufferSize;
 
  746  pDirtyRectsBuffer = (RECT*)&(subsystem->MetadataBuffer[UsedBufferSize]);
 
  748  hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameDirtyRects(
 
  749      subsystem->dxgiOutputDuplication, DirtyRectsBufferSize, pDirtyRectsBuffer,
 
  750      &DirtyRectsBufferSize);
 
  755             "IDXGIOutputDuplication::GetFrameDirtyRects failure: %s (0x%08lX) Size: %u Total " 
  757             GetDxgiErrorString(hr), hr, DirtyRectsBufferSize, MetadataBufferSize,
 
  762  numMoveRects = MoveRectsBufferSize / 
sizeof(DXGI_OUTDUPL_MOVE_RECT);
 
  764  for (UINT i = 0; i < numMoveRects; i++)
 
  766    pMoveRect = &pMoveRectBuffer[i];
 
  767    pSrcPt = &(pMoveRect->SourcePoint);
 
  768    pDstRect = &(pMoveRect->DestinationRect);
 
  770    invalidRect.left = (UINT16)pDstRect->left;
 
  771    invalidRect.top = (UINT16)pDstRect->top;
 
  772    invalidRect.right = (UINT16)pDstRect->right;
 
  773    invalidRect.bottom = (UINT16)pDstRect->bottom;
 
  775    region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
 
  778  numDirtyRects = DirtyRectsBufferSize / 
sizeof(RECT);
 
  780  for (UINT i = 0; i < numDirtyRects; i++)
 
  782    pDirtyRect = &pDirtyRectsBuffer[i];
 
  784    invalidRect.left = (UINT16)pDirtyRect->left;
 
  785    invalidRect.top = (UINT16)pDirtyRect->top;
 
  786    invalidRect.right = (UINT16)pDirtyRect->right;
 
  787    invalidRect.bottom = (UINT16)pDirtyRect->bottom;
 
  789    region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);