shadow: initial windows server-side connectivity
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 18 Jul 2014 01:15:22 +0000 (21:15 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 18 Jul 2014 01:15:22 +0000 (21:15 -0400)
14 files changed:
include/freerdp/server/shadow.h
libfreerdp/core/peer.c
libfreerdp/core/tcp.c
libfreerdp/core/tcp.h
libfreerdp/core/transport.c
libfreerdp/crypto/certificate.c
libfreerdp/crypto/tls.c
server/Windows/wf_dxgi.c
server/shadow/Win/win_shadow.c
server/shadow/Win/win_shadow.h
server/shadow/shadow_client.c
server/shadow/shadow_server.c
winpr/include/winpr/path.h
winpr/libwinpr/path/shell.c

index 2092275..c5b7e20 100644 (file)
@@ -93,6 +93,7 @@ struct rdp_shadow_server
        DWORD port;
        BOOL mayView;
        BOOL mayInteract;
+       char* ConfigPath;
        freerdp_listener* listener;
        pfnShadowCreateSubsystem CreateSubsystem;
 };
index 10b10ff..3821a91 100644 (file)
@@ -36,17 +36,18 @@ extern const char* DATA_PDU_TYPE_STRINGS[80];
 
 static BOOL freerdp_peer_initialize(freerdp_peer* client)
 {
-       rdpRdp *rdp = client->context->rdp;
-       rdpSettings *settings = rdp->settings;
+       rdpRdprdp = client->context->rdp;
+       rdpSettingssettings = rdp->settings;
 
        settings->ServerMode = TRUE;
        settings->FrameAcknowledge = 0;
        settings->LocalConnection = client->local;
        rdp->state = CONNECTION_STATE_INITIAL;
 
-       if (settings->RdpKeyFile != NULL)
+       if (settings->RdpKeyFile)
        {
                settings->RdpServerRsaKey = key_new(settings->RdpKeyFile);
+
                if (!settings->RdpServerRsaKey)
                {
                        fprintf(stderr, "%s: inavlid RDP key file %s\n", __FUNCTION__, settings->RdpKeyFile);
@@ -77,7 +78,6 @@ static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
        return client->context->rdp->transport->TcpIn->event;
 }
 
-
 static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
 {
        int status;
index 21a8751..699f20b 100644 (file)
@@ -640,16 +640,31 @@ BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking)
        else
                fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
 #else
-       int status;
-       u_long arg = blocking;
-
-       status = ioctlsocket(tcp->sockfd, FIONBIO, &arg);
+       /**
+        * ioctlsocket function:
+        * msdn.microsoft.com/en-ca/library/windows/desktop/ms738573/
+        * 
+        * The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode.
+        * If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use
+        * ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL.
+        * 
+        * To set the socket back to blocking mode, an application must first disable WSAAsyncSelect
+        * by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect
+        * by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.
+        */
 
-       if (status != NO_ERROR)
-               fprintf(stderr, "ioctlsocket() failed with error: %ld\n", status);
+       if (blocking == TRUE)
+       {
+               if (tcp->event)
+                       WSAEventSelect(tcp->sockfd, tcp->event, 0);
+       }
+       else
+       {
+               if (!tcp->event)
+                       tcp->event = WSACreateEvent();
 
-       tcp->wsa_event = WSACreateEvent();
-       WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ);
+               WSAEventSelect(tcp->sockfd, tcp->event, FD_READ);
+       }
 #endif
 
        return TRUE;
@@ -757,14 +772,9 @@ HANDLE tcp_get_event_handle(rdpTcp* tcp)
        if (!tcp)
                return NULL;
        
-#ifndef _WIN32
        return tcp->event;
-#else
-       return (HANDLE) tcp->wsa_event;
-#endif
 }
 
-
 int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds)
 {
        int status;
index 4d87e3b..9f65522 100644 (file)
@@ -49,9 +49,6 @@ struct rdp_tcp
        char ip_address[32];
        BYTE mac_address[6];
        rdpSettings* settings;
-#ifdef _WIN32
-       WSAEVENT wsa_event;
-#endif
        BIO* socketBio;
        BIO* bufferedBio;
        RingBuffer xmitBuffer;
index 3f214e5..fc84d8f 100644 (file)
@@ -951,12 +951,12 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
        void* pfd;
 
 #ifdef _WIN32
-       rfds[*rcount] = transport->TcpIn->wsa_event;
+       rfds[*rcount] = transport->TcpIn->event;
        (*rcount)++;
 
        if (transport->SplitInputOutput)
        {
-               rfds[*rcount] = transport->TcpOut->wsa_event;
+               rfds[*rcount] = transport->TcpOut->event;
                (*rcount)++;
        }
 #else
@@ -1058,7 +1058,7 @@ int transport_check_fds(rdpTransport* transport)
                return -1;
 
 #ifdef _WIN32
-       WSAResetEvent(transport->TcpIn->wsa_event);
+       WSAResetEvent(transport->TcpIn->event);
 #endif
        ResetEvent(transport->ReceiveEvent);
 
index d65796a..8a0b9c0 100644 (file)
@@ -39,7 +39,7 @@ static const char certificate_known_hosts_file[] = "known_hosts";
 
 #include <freerdp/crypto/certificate.h>
 
-void certificate_store_init(rdpCertificateStore* certificate_store)
+int certificate_store_init(rdpCertificateStore* certificate_store)
 {
        char* server_path;
        rdpSettings* settings;
@@ -54,6 +54,9 @@ void certificate_store_init(rdpCertificateStore* certificate_store)
 
        certificate_store->path = GetCombinedPath(settings->ConfigPath, (char*) certificate_store_dir);
 
+       if (!certificate_store->path)
+               return -1;
+
        if (!PathFileExistsA(certificate_store->path))
        {
                CreateDirectoryA(certificate_store->path, 0);
@@ -62,6 +65,9 @@ void certificate_store_init(rdpCertificateStore* certificate_store)
 
        server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir);
 
+       if (!server_path)
+               return -1;
+
        if (!PathFileExistsA(server_path))
        {
                CreateDirectoryA(server_path, 0);
@@ -72,14 +78,17 @@ void certificate_store_init(rdpCertificateStore* certificate_store)
 
        certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file);
 
+       if (!certificate_store->file)
+               return -1;
+
        if (PathFileExistsA(certificate_store->file) == FALSE)
        {
                certificate_store->fp = fopen((char*) certificate_store->file, "w+");
 
-               if (certificate_store->fp == NULL)
+               if (!certificate_store->fp)
                {
                        fprintf(stderr, "certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
-                       return;
+                       return -1;
                }
 
                fflush(certificate_store->fp);
@@ -88,6 +97,8 @@ void certificate_store_init(rdpCertificateStore* certificate_store)
        {
                certificate_store->fp = fopen((char*) certificate_store->file, "r+");
        }
+
+       return 1;
 }
 
 int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
@@ -264,14 +275,14 @@ rdpCertificateStore* certificate_store_new(rdpSettings* settings)
 {
        rdpCertificateStore* certificate_store;
 
-       certificate_store = (rdpCertificateStore *)calloc(1, sizeof(rdpCertificateStore));
+       certificate_store = (rdpCertificateStore*) calloc(1, sizeof(rdpCertificateStore));
 
        if (!certificate_store)
                return NULL;
 
        certificate_store->settings = settings;
+
        certificate_store_init(certificate_store);
-       /* TODO: certificate_store_init should not fail silently */
 
        return certificate_store;
 }
index 967bf15..453ec5d 100644 (file)
@@ -1340,10 +1340,14 @@ rdpTls* tls_new(rdpSettings* settings)
        SSL_library_init();
 
        tls->settings = settings;
-       tls->certificate_store = certificate_store_new(settings);
 
-       if (!tls->certificate_store)
-               goto out_free;
+       if (!settings->ServerMode)
+       {
+               tls->certificate_store = certificate_store_new(settings);
+
+               if (!tls->certificate_store)
+                       goto out_free;
+       }
 
        tls->alertLevel = TLS_ALERT_LEVEL_WARNING;
        tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY;
@@ -1379,8 +1383,11 @@ void tls_free(rdpTls* tls)
                tls->Bindings = NULL;
        }
 
-       certificate_store_free(tls->certificate_store);
-       tls->certificate_store = NULL;
+       if (tls->certificate_store)
+       {
+               certificate_store_free(tls->certificate_store);
+               tls->certificate_store = NULL;
+       }
 
        free(tls);
 }
index 43dd8af..fdaacca 100644 (file)
@@ -69,8 +69,6 @@ int wf_dxgi_init(wfInfo* wfi)
 {
        gAcquiredDesktopImage = NULL;
 
-       printf("wf_dxgi_init\n");
-
        if (wf_dxgi_createDevice(wfi) != 0)
        {
                return 1;
index 2089bec..5a3318c 100644 (file)
 
 #include "win_shadow.h"
 
+#ifdef WITH_DXGI_1_2
+
+#ifndef CINTERFACE
+#define CINTERFACE
+#endif
+
+#include <D3D11.h>
+#include <dxgi1_2.h>
+
+static D3D_DRIVER_TYPE DriverTypes[] =
+{
+       D3D_DRIVER_TYPE_HARDWARE,
+       D3D_DRIVER_TYPE_WARP,
+       D3D_DRIVER_TYPE_REFERENCE,
+};
+
+static UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
+
+static D3D_FEATURE_LEVEL FeatureLevels[] =
+{
+       D3D_FEATURE_LEVEL_11_0,
+       D3D_FEATURE_LEVEL_10_1,
+       D3D_FEATURE_LEVEL_10_0,
+       D3D_FEATURE_LEVEL_9_1
+};
+
+static UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
+
+static D3D_FEATURE_LEVEL FeatureLevel;
+
+static ID3D11Device* gDevice = NULL;
+static ID3D11DeviceContext* gContext = NULL;
+static IDXGIOutputDuplication* gOutputDuplication = NULL;
+static ID3D11Texture2D* gAcquiredDesktopImage = NULL;
+
+static IDXGISurface* surf;
+static ID3D11Texture2D* sStage;
+
+static DXGI_OUTDUPL_FRAME_INFO FrameInfo;
+
+static HMODULE d3d11_module = NULL;
+
+typedef HRESULT (WINAPI * fnD3D11CreateDevice)(
+       IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags,
+       CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion,
+       ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext);
+
+static fnD3D11CreateDevice pfnD3D11CreateDevice = NULL;
+
+#undef DEFINE_GUID
+#define INITGUID
+
+#include <initguid.h>
+
+/* dxgi.h GUIDs */
+
+DEFINE_GUID(IID_IDXGIObject, 0xaec22fb8, 0x76f3, 0x4639, 0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a, 0x2e);
+DEFINE_GUID(IID_IDXGIDeviceSubObject, 0x3d3e0379, 0xf9de, 0x4d58, 0xbb, 0x6c, 0x18, 0xd6, 0x29, 0x92, 0xf1, 0xa6);
+DEFINE_GUID(IID_IDXGIResource, 0x035f3ab4, 0x482e, 0x4e50, 0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b);
+DEFINE_GUID(IID_IDXGIKeyedMutex, 0x9d8e1289, 0xd7b3, 0x465f, 0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a, 0xf8, 0x5d);
+DEFINE_GUID(IID_IDXGISurface, 0xcafcb56c, 0x6ac3, 0x4889, 0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60, 0xec);
+DEFINE_GUID(IID_IDXGISurface1, 0x4AE63092, 0x6327, 0x4c1b, 0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86);
+DEFINE_GUID(IID_IDXGIAdapter, 0x2411e7e1, 0x12ac, 0x4ccf, 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0);
+DEFINE_GUID(IID_IDXGIOutput, 0xae02eedb, 0xc735, 0x4690, 0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13, 0xaa);
+DEFINE_GUID(IID_IDXGISwapChain, 0x310d36a0, 0xd2e7, 0x4c0a, 0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8, 0x88, 0x6a);
+DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69);
+DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c);
+DEFINE_GUID(IID_IDXGIFactory1, 0x770aae78, 0xf26f, 0x4dba, 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87);
+DEFINE_GUID(IID_IDXGIAdapter1, 0x29038f61, 0x3839, 0x4626, 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05);
+DEFINE_GUID(IID_IDXGIDevice1, 0x77db970f, 0x6276, 0x48ba, 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c);
+
+/* dxgi1_2.h GUIDs */
+
+DEFINE_GUID(IID_IDXGIDisplayControl, 0xea9dbf1a, 0xc88e, 0x4486, 0x85, 0x4a, 0x98, 0xaa, 0x01, 0x38, 0xf3, 0x0c);
+DEFINE_GUID(IID_IDXGIOutputDuplication, 0x191cfac3, 0xa341, 0x470d, 0xb2, 0x6e, 0xa8, 0x64, 0xf4, 0x28, 0x31, 0x9c);
+DEFINE_GUID(IID_IDXGISurface2, 0xaba496dd, 0xb617, 0x4cb8, 0xa8, 0x66, 0xbc, 0x44, 0xd7, 0xeb, 0x1f, 0xa2);
+DEFINE_GUID(IID_IDXGIResource1, 0x30961379, 0x4609, 0x4a41, 0x99, 0x8e, 0x54, 0xfe, 0x56, 0x7e, 0xe0, 0xc1);
+DEFINE_GUID(IID_IDXGIDevice2, 0x05008617, 0xfbfd, 0x4051, 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6, 0xa9);
+DEFINE_GUID(IID_IDXGISwapChain1, 0x790a45f7, 0x0d42, 0x4876, 0x98, 0x3a, 0x0a, 0x55, 0xcf, 0xe6, 0xf4, 0xaa);
+DEFINE_GUID(IID_IDXGIFactory2, 0x50c83a1c, 0xe072, 0x4c48, 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0);
+DEFINE_GUID(IID_IDXGIAdapter2, 0x0AA1AE0A, 0xFA0E, 0x4B84, 0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC, 0xB5);
+DEFINE_GUID(IID_IDXGIOutput1, 0x00cddea8, 0x939b, 0x4b83, 0xa3, 0x40, 0xa6, 0x85, 0x22, 0x66, 0x66, 0xcc);
+
+static void win_shadow_d3d11_module_init()
+{
+       if (d3d11_module)
+               return;
+
+       d3d11_module = LoadLibraryA("d3d11.dll");
+
+       if (!d3d11_module)
+               return;
+
+       pfnD3D11CreateDevice = (fnD3D11CreateDevice) GetProcAddress(d3d11_module, "D3D11CreateDevice");
+}
+
+int win_shadow_dxgi_init(winShadowSubsystem* subsystem)
+{
+       HRESULT status;
+       UINT dTop, i = 0;
+       UINT DriverTypeIndex;
+       DXGI_OUTPUT_DESC desc;
+       IDXGIOutput* pOutput;
+       IDXGIDevice* DxgiDevice = NULL;
+       IDXGIAdapter* DxgiAdapter = NULL;
+       IDXGIOutput* DxgiOutput = NULL;
+       IDXGIOutput1* DxgiOutput1 = NULL;
+
+       win_shadow_d3d11_module_init();
+
+       if (!pfnD3D11CreateDevice)
+               return -1;
+
+       for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
+       {
+               status = pfnD3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels,
+                       NumFeatureLevels, D3D11_SDK_VERSION, &gDevice, &FeatureLevel, &gContext);
+
+               if (SUCCEEDED(status))
+                       break;
+       }
+
+       if (FAILED(status))
+               return -1;
+
+       status = gDevice->lpVtbl->QueryInterface(gDevice, &IID_IDXGIDevice, (void**) &DxgiDevice);
+
+       if (FAILED(status))
+               return -1;
+
+       status = DxgiDevice->lpVtbl->GetParent(DxgiDevice, &IID_IDXGIAdapter, (void**) &DxgiAdapter);
+       DxgiDevice->lpVtbl->Release(DxgiDevice);
+       DxgiDevice = NULL;
+
+       if (FAILED(status))
+               return -1;
+
+       ZeroMemory(&desc, sizeof(desc));
+       pOutput = NULL;
+
+       while (DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, i, &pOutput) != DXGI_ERROR_NOT_FOUND)
+       {
+               DXGI_OUTPUT_DESC* pDesc = &desc;
+
+               status = pOutput->lpVtbl->GetDesc(pOutput, pDesc);
+
+               if (FAILED(status))
+                       return -1;
+
+               if (pDesc->AttachedToDesktop)
+                       dTop = i;
+
+               pOutput->lpVtbl->Release(pOutput);
+               ++i;
+       }
+
+       dTop = 0; /* screen id */
+
+       status = DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, dTop, &DxgiOutput);
+       DxgiAdapter->lpVtbl->Release(DxgiAdapter);
+       DxgiAdapter = NULL;
+
+       if (FAILED(status))
+               return -1;
+
+       status = DxgiOutput->lpVtbl->QueryInterface(DxgiOutput, &IID_IDXGIOutput1, (void**) &DxgiOutput1);
+       DxgiOutput->lpVtbl->Release(DxgiOutput);
+       DxgiOutput = NULL;
+
+       if (FAILED(status))
+               return -1;
+
+       status = DxgiOutput1->lpVtbl->DuplicateOutput(DxgiOutput1, (IUnknown*) gDevice, &gOutputDuplication);
+       DxgiOutput1->lpVtbl->Release(DxgiOutput1);
+       DxgiOutput1 = NULL;
+
+       if (FAILED(status))
+               return -1;
+
+       return 1;
+}
+
+#endif
+
 void win_shadow_input_synchronize_event(winShadowSubsystem* subsystem, UINT32 flags)
 {
 
@@ -177,6 +361,28 @@ void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, UINT16
        }
 }
 
+
+int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y, int width, int height)
+{
+       rdpShadowServer* server;
+       rdpShadowScreen* screen;
+       RECTANGLE_16 invalidRect;
+
+       server = subsystem->server;
+       screen = server->screen;
+
+       invalidRect.left = x;
+       invalidRect.top = y;
+       invalidRect.right = x + width;
+       invalidRect.bottom = y + height;
+
+       EnterCriticalSection(&(screen->lock));
+       region16_union_rect(&(screen->invalidRegion), &(screen->invalidRegion), &invalidRect);
+       LeaveCriticalSection(&(screen->lock));
+
+       return 1;
+}
+
 int win_shadow_surface_copy(winShadowSubsystem* subsystem)
 {
        return 1;
@@ -184,8 +390,13 @@ int win_shadow_surface_copy(winShadowSubsystem* subsystem)
 
 void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
 {
+       int fps;
        DWORD status;
        DWORD nCount;
+       UINT64 cTime;
+       DWORD dwTimeout;
+       DWORD dwInterval;
+       UINT64 frameTime;
        HANDLE events[32];
        HANDLE StopEvent;
 
@@ -194,14 +405,31 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
        nCount = 0;
        events[nCount++] = StopEvent;
 
+       fps = 16;
+       dwInterval = 1000 / fps;
+       frameTime = GetTickCount64() + dwInterval;
+
        while (1)
        {
-               status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+               dwTimeout = INFINITE;
+
+               cTime = GetTickCount64();
+               dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime);
+
+               status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
 
                if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0)
                {
                        break;
                }
+
+               if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
+               {
+                       win_shadow_invalidate_region(subsystem, 0, 0, subsystem->width, subsystem->height);
+
+                       dwInterval = 1000 / fps;
+                       frameTime += dwInterval;
+               }
        }
 
        ExitThread(0);
@@ -210,6 +438,50 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
 
 int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
 {
+       HDC hdc;
+       int status;
+       DWORD iDevNum = 0;
+       MONITOR_DEF* virtualScreen;
+       DISPLAY_DEVICE DisplayDevice;
+
+       ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
+       DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
+
+       if (!EnumDisplayDevices(NULL, iDevNum, &DisplayDevice, 0))
+               return -1;
+
+       hdc = CreateDC(DisplayDevice.DeviceName, NULL, NULL, NULL);
+
+       subsystem->width = GetDeviceCaps(hdc, HORZRES);
+       subsystem->height = GetDeviceCaps(hdc, VERTRES);
+       subsystem->bpp = GetDeviceCaps(hdc, BITSPIXEL);
+
+       DeleteDC(hdc);
+
+#ifdef WITH_DXGI_1_2
+       status = win_shadow_dxgi_init(subsystem);
+#endif
+
+       virtualScreen = &(subsystem->virtualScreen);
+
+       virtualScreen->left = 0;
+       virtualScreen->top = 0;
+       virtualScreen->right = subsystem->width;
+       virtualScreen->bottom = subsystem->height;
+       virtualScreen->flags = 1;
+
+       if (subsystem->monitorCount < 1)
+       {
+               subsystem->monitorCount = 1;
+               subsystem->monitors[0].left = virtualScreen->left;
+               subsystem->monitors[0].top = virtualScreen->top;
+               subsystem->monitors[0].right = virtualScreen->right;
+               subsystem->monitors[0].bottom = virtualScreen->bottom;
+               subsystem->monitors[0].flags = 1;
+       }
+
+       printf("width: %d height: %d\n", subsystem->width, subsystem->height);
+
        return 1;
 }
 
index 1c27d4f..9da11e3 100644 (file)
@@ -29,11 +29,17 @@ typedef struct win_shadow_subsystem winShadowSubsystem;
 #include <winpr/stream.h>
 #include <winpr/collections.h>
 
+#if _WIN32_WINNT >= 0x0602
+#define WITH_DXGI_1_2  1
+#endif
+
 struct win_shadow_subsystem
 {
        RDP_SHADOW_SUBSYSTEM_COMMON();
 
-
+       int bpp;
+       int width;
+       int height;
 };
 
 #ifdef __cplusplus
index a38977f..180b6be 100644 (file)
 
 #include "shadow.h"
 
-static const char* makecert_argv[4] =
+static const char* makecert_argv[6] =
 {
        "makecert",
        "-rdp",
        "-live",
-       "-silent"
+       "-silent",
+       "-y", "5"
 };
 
 static int makecert_argc = (sizeof(makecert_argv) / sizeof(char*));
 
-int shadow_generate_certificate(rdpSettings* settings)
+int shadow_generate_certificate(rdpShadowClient* client)
 {
-       char* serverFilePath;
-       MAKECERT_CONTEXT* context;
+       char* filepath;
+       rdpContext* context;
+       rdpSettings* settings;
+       MAKECERT_CONTEXT* makecert;
+       rdpShadowServer* server = client->server;
+
+       context = (rdpContext*) client;
+       settings = context->settings;
+
+       if (!PathFileExistsA(server->ConfigPath))
+               CreateDirectoryA(server->ConfigPath, 0);
 
-       serverFilePath = GetCombinedPath(settings->ConfigPath, "server");
+       filepath = GetCombinedPath(server->ConfigPath, "shadow");
+
+       if (!filepath)
+               return -1;
 
-       if (!PathFileExistsA(serverFilePath))
-               CreateDirectoryA(serverFilePath, 0);
+       if (!PathFileExistsA(filepath))
+               CreateDirectoryA(filepath, 0);
 
-       settings->CertificateFile = GetCombinedPath(serverFilePath, "server.crt");
-       settings->PrivateKeyFile = GetCombinedPath(serverFilePath, "server.key");
+       settings->CertificateFile = GetCombinedPath(filepath, "shadow.crt");
+       settings->PrivateKeyFile = GetCombinedPath(filepath, "shadow.key");
 
        if ((!PathFileExistsA(settings->CertificateFile)) ||
                        (!PathFileExistsA(settings->PrivateKeyFile)))
        {
-               context = makecert_context_new();
+               makecert = makecert_context_new();
 
-               makecert_context_process(context, makecert_argc, (char**) makecert_argv);
+               makecert_context_process(makecert, makecert_argc, (char**) makecert_argv);
 
-               makecert_context_set_output_file_name(context, "server");
+               makecert_context_set_output_file_name(makecert, "shadow");
 
                if (!PathFileExistsA(settings->CertificateFile))
-                       makecert_context_output_certificate_file(context, serverFilePath);
+                       makecert_context_output_certificate_file(makecert, filepath);
 
                if (!PathFileExistsA(settings->PrivateKeyFile))
-                       makecert_context_output_private_key_file(context, serverFilePath);
+                       makecert_context_output_private_key_file(makecert, filepath);
 
-               makecert_context_free(context);
+               makecert_context_free(makecert);
        }
 
-       free(serverFilePath);
+       free(filepath);
 
        return 1;
 }
@@ -97,7 +110,7 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
        settings->TlsSecurity = TRUE;
        settings->NlaSecurity = FALSE;
 
-       shadow_generate_certificate(settings);
+       shadow_generate_certificate(client);
 
        client->inLobby = TRUE;
        client->mayView = server->mayView;
@@ -651,7 +664,7 @@ void* shadow_client_thread(rdpShadowClient* client)
                events[nCount++] = ChannelEvent;
 
                cTime = GetTickCount64();
-               dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime;
+               dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime);
 
                status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout);
 
index 0cc7573..945189c 100644 (file)
@@ -21,7 +21,9 @@
 #endif
 
 #include <winpr/crt.h>
+#include <winpr/path.h>
 #include <winpr/cmdline.h>
+#include <winpr/winsock.h>
 
 #include <freerdp/version.h>
 
@@ -282,11 +284,16 @@ void* shadow_server_thread(rdpShadowServer* server)
 
 int shadow_server_start(rdpShadowServer* server)
 {
+       WSADATA wsaData;
+
+       if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
+               return -1;
+
 #ifndef _WIN32
        signal(SIGPIPE, SIG_IGN);
 #endif
 
-       if (server->listener->Open(server->listener, NULL, server->port))
+       if (server->listener->Open(server->listener, NULL, (UINT16) server->port))
        {
                server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
                                shadow_server_thread, (void*) server, 0, NULL);
@@ -312,6 +319,8 @@ int shadow_server_stop(rdpShadowServer* server)
 
 int shadow_server_init(rdpShadowServer* server)
 {
+       int status;
+
        WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
 
        server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -343,7 +352,12 @@ int shadow_server_init(rdpShadowServer* server)
                return -1;
 
        if (server->subsystem->Init)
-               server->subsystem->Init(server->subsystem);
+       {
+               status = server->subsystem->Init(server->subsystem);
+
+               if (status < 0)
+                       fprintf(stderr, "subsystem init failure: %d\n", status);
+       }
 
        server->screen = shadow_screen_new(server);
 
@@ -396,6 +410,13 @@ rdpShadowServer* shadow_server_new()
        server->mayView = TRUE;
        server->mayInteract = TRUE;
 
+#ifdef _WIN32
+       server->ConfigPath = GetEnvironmentSubPath("LOCALAPPDATA", "freerdp");
+#endif
+
+       if (!server->ConfigPath)
+               server->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp");
+
        return server;
 }
 
index a69867d..36333e9 100644 (file)
@@ -281,10 +281,10 @@ extern "C" {
 
 WINPR_API char* GetKnownPath(int id);
 WINPR_API char* GetKnownSubPath(int id, const char* path);
+WINPR_API char* GetEnvironmentPath(char* name);
+WINPR_API char* GetEnvironmentSubPath(char* name, const char* path);
 WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath);
 
-//#ifndef _WIN32
-
 WINPR_API BOOL PathFileExistsA(LPCSTR pszPath);
 WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath);
 
@@ -298,6 +298,4 @@ WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath);
 #define PathFileExists PathFileExistsA
 #endif
 
-//#endif
-
 #endif /* WINPR_PATH_H */
index 10f7b7d..eae9a65 100644 (file)
@@ -271,6 +271,39 @@ char* GetKnownSubPath(int id, const char* path)
        return subPath;
 }
 
+char* GetEnvironmentPath(char* name)
+{
+       char* env;
+       DWORD nSize;
+
+       nSize = GetEnvironmentVariableA(name, NULL, 0);
+
+       if (nSize)
+       {
+               env = (LPSTR) malloc(nSize);
+               nSize = GetEnvironmentVariableA(name, env, nSize);
+       }
+
+       return env;
+}
+
+char* GetEnvironmentSubPath(char* name, const char* path)
+{
+       char* env;
+       char* subpath;
+
+       env = GetEnvironmentPath(name);
+
+       if (!env)
+               return NULL;
+
+       subpath = GetCombinedPath(env, path);
+
+       free(env);
+
+       return subpath;
+}
+
 char* GetCombinedPath(const char* basePath, const char* subPath)
 {
        int length;
@@ -309,8 +342,6 @@ char* GetCombinedPath(const char* basePath, const char* subPath)
        return path;
 }
 
-//#ifndef _WIN32
-
 BOOL PathFileExistsA(LPCSTR pszPath)
 {
        struct stat stat_info;
@@ -326,4 +357,3 @@ BOOL PathFileExistsW(LPCWSTR pszPath)
        return FALSE;
 }
 
-//#endif