shadow: initial windows server-side connectivity

This commit is contained in:
Marc-André Moreau 2014-07-17 21:15:22 -04:00
parent a732045c91
commit d8b858811f
14 changed files with 429 additions and 65 deletions

View File

@ -93,6 +93,7 @@ struct rdp_shadow_server
DWORD port;
BOOL mayView;
BOOL mayInteract;
char* ConfigPath;
freerdp_listener* listener;
pfnShadowCreateSubsystem CreateSubsystem;
};

View File

@ -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;

View 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;
/**
* 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;

View 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;

View 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);

View 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)
@ -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;
}

View File

@ -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);
}

View 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;

View File

@ -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;
}

View 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

View File

@ -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);

View 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;
}

View 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 */

View 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