/** * FreeRDP: A Remote Desktop Protocol Implementation * FreeRDP Windows Server * * Copyright 2012 Marc-Andre Moreau * Copyright 2012 Corey Clayton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include "wf_peer.h" #include "wf_settings.h" #include "wf_info.h" #include "wf_interface.h" #include #define TAG SERVER_TAG("windows") #define SERVER_KEY "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server" static cbCallback cbEvent = NULL; int get_screen_info(int id, _TCHAR* name, size_t length, int* width, int* height, int* bpp) { DISPLAY_DEVICE dd = { 0 }; dd.cb = sizeof(DISPLAY_DEVICE); if (EnumDisplayDevices(NULL, id, &dd, 0) != 0) { HDC dc; if (name != NULL) _stprintf_s(name, length, _T("%s (%s)"), dd.DeviceName, dd.DeviceString); dc = CreateDC(dd.DeviceName, NULL, NULL, NULL); *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES); *bpp = GetDeviceCaps(dc, BITSPIXEL); // ReleaseDC(NULL, dc); DeleteDC(dc); } else { return 0; } return 1; } void set_screen_id(int id) { wfInfo* wfi; wfi = wf_info_get_instance(); if (!wfi) return; wfi->screenID = id; return; } static DWORD WINAPI wf_server_main_loop(LPVOID lpParam) { freerdp_listener* instance; wfInfo* wfi; wfi = wf_info_get_instance(); if (!wfi) { WLog_ERR(TAG, "Failed to get instance"); return -1; } wfi->force_all_disconnect = FALSE; instance = (freerdp_listener*)lpParam; WINPR_ASSERT(instance); WINPR_ASSERT(instance->GetEventHandles); WINPR_ASSERT(instance->CheckFileDescriptor); while (wfi->force_all_disconnect == FALSE) { DWORD status; HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 }; DWORD count = instance->GetEventHandles(instance, handles, ARRAYSIZE(handles)); if (count == 0) { WLog_ERR(TAG, "Failed to get FreeRDP file descriptor"); break; } status = WaitForMultipleObjects(count, handles, FALSE, INFINITE); if (status == WAIT_FAILED) { WLog_ERR(TAG, "WaitForMultipleObjects failed"); break; } if (instance->CheckFileDescriptor(instance) != TRUE) { WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } } WLog_INFO(TAG, "wf_server_main_loop terminating"); instance->Close(instance); return 0; } BOOL wfreerdp_server_start(wfServer* server) { freerdp_listener* instance; server->instance = freerdp_listener_new(); server->instance->PeerAccepted = wf_peer_accepted; instance = server->instance; wf_settings_read_dword(HKEY_LOCAL_MACHINE, SERVER_KEY, _T("DefaultPort"), &server->port); if (!instance->Open(instance, NULL, (UINT16)server->port)) return FALSE; if (!(server->thread = CreateThread(NULL, 0, wf_server_main_loop, (void*)instance, 0, NULL))) return FALSE; return TRUE; } BOOL wfreerdp_server_stop(wfServer* server) { wfInfo* wfi; wfi = wf_info_get_instance(); if (!wfi) return FALSE; WLog_INFO(TAG, "Stopping server"); wfi->force_all_disconnect = TRUE; server->instance->Close(server->instance); return TRUE; } wfServer* wfreerdp_server_new() { WSADATA wsaData; wfServer* server; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return NULL; server = (wfServer*)calloc(1, sizeof(wfServer)); if (server) { server->port = 3389; } WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi()); cbEvent = NULL; return server; } void wfreerdp_server_free(wfServer* server) { free(server); WSACleanup(); } BOOL wfreerdp_server_is_running(wfServer* server) { DWORD tStatus; BOOL bRet; bRet = GetExitCodeThread(server->thread, &tStatus); if (bRet == 0) { WLog_ERR(TAG, "Error in call to GetExitCodeThread"); return FALSE; } if (tStatus == STILL_ACTIVE) return TRUE; return FALSE; } UINT32 wfreerdp_server_num_peers() { wfInfo* wfi; wfi = wf_info_get_instance(); if (!wfi) return -1; return wfi->peerCount; } UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t* dstStr) { wfInfo* wfi; freerdp_peer* peer; wfi = wf_info_get_instance(); if (!wfi) return 0; peer = wfi->peers[pId]; if (peer) { UINT32 sLen; sLen = strnlen_s(peer->hostname, 50); swprintf(dstStr, 50, L"%hs", peer->hostname); return sLen; } else { WLog_WARN(TAG, "nonexistent peer id=%d", pId); return 0; } } BOOL wfreerdp_server_peer_is_local(int pId) { wfInfo* wfi; freerdp_peer* peer; wfi = wf_info_get_instance(); if (!wfi) return FALSE; peer = wfi->peers[pId]; if (peer) { return peer->local; } else { return FALSE; } } BOOL wfreerdp_server_peer_is_connected(int pId) { wfInfo* wfi; freerdp_peer* peer; wfi = wf_info_get_instance(); if (!wfi) return FALSE; peer = wfi->peers[pId]; if (peer) { return peer->connected; } else { return FALSE; } } BOOL wfreerdp_server_peer_is_activated(int pId) { wfInfo* wfi; freerdp_peer* peer; wfi = wf_info_get_instance(); if (!wfi) return FALSE; peer = wfi->peers[pId]; if (peer) { return peer->activated; } else { return FALSE; } } BOOL wfreerdp_server_peer_is_authenticated(int pId) { wfInfo* wfi; freerdp_peer* peer; wfi = wf_info_get_instance(); if (!wfi) return FALSE; peer = wfi->peers[pId]; if (peer) { return peer->authenticated; } else { return FALSE; } } void wfreerdp_server_register_callback_event(cbCallback cb) { cbEvent = cb; } void wfreerdp_server_peer_callback_event(int pId, UINT32 eType) { if (cbEvent) cbEvent(pId, eType); }