diff --git a/include/freerdp/server/shadow.h b/include/freerdp/server/shadow.h index 2092275c2..c5b7e2036 100644 --- a/include/freerdp/server/shadow.h +++ b/include/freerdp/server/shadow.h @@ -93,6 +93,7 @@ struct rdp_shadow_server DWORD port; BOOL mayView; BOOL mayInteract; + char* ConfigPath; freerdp_listener* listener; pfnShadowCreateSubsystem CreateSubsystem; }; diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 10b10ff72..3821a9174 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -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; + rdpRdp* rdp = client->context->rdp; + rdpSettings* settings = 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; diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 21a875150..699f20b69 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -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; + /** + * 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. + */ - status = ioctlsocket(tcp->sockfd, FIONBIO, &arg); + if (blocking == TRUE) + { + if (tcp->event) + WSAEventSelect(tcp->sockfd, tcp->event, 0); + } + else + { + if (!tcp->event) + tcp->event = WSACreateEvent(); - if (status != NO_ERROR) - fprintf(stderr, "ioctlsocket() failed with error: %ld\n", status); - - 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; diff --git a/libfreerdp/core/tcp.h b/libfreerdp/core/tcp.h index 4d87e3b01..9f65522f3 100644 --- a/libfreerdp/core/tcp.h +++ b/libfreerdp/core/tcp.h @@ -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; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 3f214e5ad..fc84d8fb0 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -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); diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index d65796ace..8a0b9c00f 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -39,7 +39,7 @@ static const char certificate_known_hosts_file[] = "known_hosts"; #include -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; } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 967bf1586..453ec5dcc 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -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); } diff --git a/server/Windows/wf_dxgi.c b/server/Windows/wf_dxgi.c index 43dd8af9e..fdaacca2d 100644 --- a/server/Windows/wf_dxgi.c +++ b/server/Windows/wf_dxgi.c @@ -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; diff --git a/server/shadow/Win/win_shadow.c b/server/shadow/Win/win_shadow.c index 2089bece9..5a3318c29 100644 --- a/server/shadow/Win/win_shadow.c +++ b/server/shadow/Win/win_shadow.c @@ -28,6 +28,190 @@ #include "win_shadow.h" +#ifdef WITH_DXGI_1_2 + +#ifndef CINTERFACE +#define CINTERFACE +#endif + +#include +#include + +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 + +/* 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; } diff --git a/server/shadow/Win/win_shadow.h b/server/shadow/Win/win_shadow.h index 1c27d4f86..9da11e371 100644 --- a/server/shadow/Win/win_shadow.h +++ b/server/shadow/Win/win_shadow.h @@ -29,11 +29,17 @@ typedef struct win_shadow_subsystem winShadowSubsystem; #include #include +#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 diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index a38977fc7..180b6be5c 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -31,48 +31,61 @@ #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; - serverFilePath = GetCombinedPath(settings->ConfigPath, "server"); + context = (rdpContext*) client; + settings = context->settings; - if (!PathFileExistsA(serverFilePath)) - CreateDirectoryA(serverFilePath, 0); + if (!PathFileExistsA(server->ConfigPath)) + CreateDirectoryA(server->ConfigPath, 0); - settings->CertificateFile = GetCombinedPath(serverFilePath, "server.crt"); - settings->PrivateKeyFile = GetCombinedPath(serverFilePath, "server.key"); + filepath = GetCombinedPath(server->ConfigPath, "shadow"); + + if (!filepath) + return -1; + + if (!PathFileExistsA(filepath)) + CreateDirectoryA(filepath, 0); + + 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); diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index 0cc757373..945189c34 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -21,7 +21,9 @@ #endif #include +#include #include +#include #include @@ -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; } diff --git a/winpr/include/winpr/path.h b/winpr/include/winpr/path.h index a69867d02..36333e9b6 100644 --- a/winpr/include/winpr/path.h +++ b/winpr/include/winpr/path.h @@ -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 */ diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 10f7b7d9d..eae9a6539 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -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