mirror of https://github.com/FreeRDP/FreeRDP
shadow: initial windows server-side connectivity
This commit is contained in:
parent
a732045c91
commit
d8b858811f
|
@ -93,6 +93,7 @@ struct rdp_shadow_server
|
|||
DWORD port;
|
||||
BOOL mayView;
|
||||
BOOL mayInteract;
|
||||
char* ConfigPath;
|
||||
freerdp_listener* listener;
|
||||
pfnShadowCreateSubsystem CreateSubsystem;
|
||||
};
|
||||
|
|
|
@ -44,9 +44,10 @@ static BOOL freerdp_peer_initialize(freerdp_peer* client)
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -270,8 +281,8 @@ rdpCertificateStore* certificate_store_new(rdpSettings* settings)
|
|||
return NULL;
|
||||
|
||||
certificate_store->settings = settings;
|
||||
|
||||
certificate_store_init(certificate_store);
|
||||
/* TODO: certificate_store_init should not fail silently */
|
||||
|
||||
return certificate_store;
|
||||
}
|
||||
|
|
|
@ -1340,10 +1340,14 @@ rdpTls* tls_new(rdpSettings* settings)
|
|||
SSL_library_init();
|
||||
|
||||
tls->settings = settings;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (tls->certificate_store)
|
||||
{
|
||||
certificate_store_free(tls->certificate_store);
|
||||
tls->certificate_store = NULL;
|
||||
}
|
||||
|
||||
free(tls);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -28,6 +28,190 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue