From 83104fda9c853b8c4aa0f1e707013dcdf50499fa Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 3 Sep 2021 08:26:07 +0200 Subject: [PATCH] Updated sample-server * Refactored code to remove global static variables * Added better error checks and WINPR_ASSERT --- server/Sample/sf_audin.c | 17 +- server/Sample/sf_encomsp.c | 9 +- server/Sample/sf_rdpsnd.c | 7 + server/Sample/sfreerdp.c | 353 +++++++++++++++++++++++++++---------- 4 files changed, 284 insertions(+), 102 deletions(-) diff --git a/server/Sample/sf_audin.c b/server/Sample/sf_audin.c index a83a40c5e..5ec0c248f 100644 --- a/server/Sample/sf_audin.c +++ b/server/Sample/sf_audin.c @@ -23,6 +23,8 @@ #include "config.h" #endif +#include + #include "sfreerdp.h" #include "sf_audin.h" @@ -38,6 +40,8 @@ */ static UINT sf_peer_audin_opening(audin_server_context* context) { + WINPR_ASSERT(context); + WLog_DBG(TAG, "AUDIN opening."); /* Simply choose the first format supported by the client. */ context->SelectFormat(context, 0); @@ -52,6 +56,8 @@ static UINT sf_peer_audin_opening(audin_server_context* context) static UINT sf_peer_audin_open_result(audin_server_context* context, UINT32 result) { /* TODO: Implement */ + WINPR_ASSERT(context); + WLog_WARN(TAG, "%s not implemented", __FUNCTION__); WLog_DBG(TAG, "AUDIN open result %" PRIu32 ".", result); return CHANNEL_RC_OK; @@ -66,6 +72,10 @@ static UINT sf_peer_audin_receive_samples(audin_server_context* context, const A wStream* buf, size_t nframes) { /* TODO: Implement */ + WINPR_ASSERT(context); + WINPR_ASSERT(format); + WINPR_ASSERT(buf); + WLog_WARN(TAG, "%s not implemented", __FUNCTION__); WLog_DBG(TAG, "%s receive %" PRIdz " frames.", __FUNCTION__, nframes); return CHANNEL_RC_OK; @@ -73,7 +83,11 @@ static UINT sf_peer_audin_receive_samples(audin_server_context* context, const A void sf_peer_audin_init(testPeerContext* context) { + WINPR_ASSERT(context); + context->audin = audin_server_context_new(context->vcm); + WINPR_ASSERT(context->audin); + context->audin->rdpcontext = &context->_p; context->audin->data = context; context->audin->num_server_formats = server_audin_get_formats(&context->audin->server_formats); @@ -112,6 +126,5 @@ BOOL sf_peer_audin_running(testPeerContext* context) void sf_peer_audin_uninit(testPeerContext* context) { - if (context) - audin_server_context_free(context->audin); + audin_server_context_free(context->audin); } diff --git a/server/Sample/sf_encomsp.c b/server/Sample/sf_encomsp.c index 6fdad0321..0de9ba7b3 100644 --- a/server/Sample/sf_encomsp.c +++ b/server/Sample/sf_encomsp.c @@ -23,16 +23,21 @@ #include "config.h" #endif +#include + #include "sf_encomsp.h" BOOL sf_peer_encomsp_init(testPeerContext* context) { - context->encomsp = encomsp_server_context_new(context->vcm); - context->encomsp->rdpcontext = &context->_p; + WINPR_ASSERT(context); + context->encomsp = encomsp_server_context_new(context->vcm); if (!context->encomsp) return FALSE; + context->encomsp->rdpcontext = &context->_p; + + WINPR_ASSERT(context->encomsp->Start); if (context->encomsp->Start(context->encomsp) != CHANNEL_RC_OK) return FALSE; diff --git a/server/Sample/sf_rdpsnd.c b/server/Sample/sf_rdpsnd.c index 558b1949a..a15d2aa79 100644 --- a/server/Sample/sf_rdpsnd.c +++ b/server/Sample/sf_rdpsnd.c @@ -23,6 +23,8 @@ #include "config.h" #endif +#include + #include #include "sf_rdpsnd.h" @@ -34,12 +36,16 @@ static void sf_peer_rdpsnd_activated(RdpsndServerContext* context) { WINPR_UNUSED(context); + WINPR_ASSERT(context); WLog_DBG(TAG, "RDPSND Activated"); } BOOL sf_peer_rdpsnd_init(testPeerContext* context) { + WINPR_ASSERT(context); + context->rdpsnd = rdpsnd_server_context_new(context->vcm); + WINPR_ASSERT(context->rdpsnd); context->rdpsnd->rdpcontext = &context->_p; context->rdpsnd->data = context; context->rdpsnd->num_server_formats = @@ -50,6 +56,7 @@ BOOL sf_peer_rdpsnd_init(testPeerContext* context) context->rdpsnd->Activated = sf_peer_rdpsnd_activated; + WINPR_ASSERT(context->rdpsnd->Initialize); if (context->rdpsnd->Initialize(context->rdpsnd, TRUE) != CHANNEL_RC_OK) { return FALSE; diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 06265247d..75cf63aba 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -55,62 +56,23 @@ #define SAMPLE_SERVER_DEFAULT_WIDTH 1024 #define SAMPLE_SERVER_DEFAULT_HEIGHT 768 -static char* test_pcap_file = NULL; -static BOOL test_dump_rfx_realtime = TRUE; - -static BOOL test_peer_context_new(freerdp_peer* client, rdpContext* ctx) +struct server_info { - testPeerContext* context = (testPeerContext*)ctx; - if (!(context->rfx_context = rfx_context_new_ex(TRUE, client->settings->ThreadingFlags))) - goto fail_rfx_context; - - if (!rfx_context_reset(context->rfx_context, SAMPLE_SERVER_DEFAULT_WIDTH, - SAMPLE_SERVER_DEFAULT_HEIGHT)) - goto fail_rfx_context; - - context->rfx_context->mode = RLGR3; - rfx_context_set_pixel_format(context->rfx_context, PIXEL_FORMAT_RGB24); - - if (!(context->nsc_context = nsc_context_new())) - goto fail_nsc_context; - - if (!nsc_context_set_parameters(context->nsc_context, NSC_COLOR_FORMAT, PIXEL_FORMAT_RGB24)) - goto fail_stream_new; - - if (!(context->s = Stream_New(NULL, 65536))) - goto fail_stream_new; - - context->icon_x = UINT32_MAX; - context->icon_y = UINT32_MAX; - context->vcm = WTSOpenServerA((LPSTR)client->context); - - if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) - goto fail_open_server; - - return TRUE; -fail_open_server: - context->vcm = NULL; - Stream_Free(context->s, TRUE); - context->s = NULL; -fail_stream_new: - nsc_context_free(context->nsc_context); - context->nsc_context = NULL; -fail_nsc_context: - rfx_context_free(context->rfx_context); - context->rfx_context = NULL; -fail_rfx_context: - return FALSE; -} + BOOL test_dump_rfx_realtime; + const char* test_pcap_file; +}; static void test_peer_context_free(freerdp_peer* client, rdpContext* ctx) { testPeerContext* context = (testPeerContext*)ctx; + WINPR_UNUSED(client); if (context) { if (context->debug_channel_thread) { + WINPR_ASSERT(context->stopEvent); SetEvent(context->stopEvent); WaitForSingleObject(context->debug_channel_thread, INFINITE); CloseHandle(context->debug_channel_thread); @@ -127,18 +89,56 @@ static void test_peer_context_free(freerdp_peer* client, rdpContext* ctx) sf_peer_audin_uninit(context); - if (context->rdpsnd) - rdpsnd_server_context_free(context->rdpsnd); - - if (context->encomsp) - encomsp_server_context_free(context->encomsp); + rdpsnd_server_context_free(context->rdpsnd); + encomsp_server_context_free(context->encomsp); WTSCloseServer((HANDLE)context->vcm); } } +static BOOL test_peer_context_new(freerdp_peer* client, rdpContext* ctx) +{ + testPeerContext* context = (testPeerContext*)ctx; + + WINPR_ASSERT(client); + WINPR_ASSERT(context); + + if (!(context->rfx_context = rfx_context_new_ex(TRUE, client->settings->ThreadingFlags))) + goto fail; + + if (!rfx_context_reset(context->rfx_context, SAMPLE_SERVER_DEFAULT_WIDTH, + SAMPLE_SERVER_DEFAULT_HEIGHT)) + goto fail; + + context->rfx_context->mode = RLGR3; + rfx_context_set_pixel_format(context->rfx_context, PIXEL_FORMAT_RGB24); + + if (!(context->nsc_context = nsc_context_new())) + goto fail; + + if (!nsc_context_set_parameters(context->nsc_context, NSC_COLOR_FORMAT, PIXEL_FORMAT_RGB24)) + goto fail; + + if (!(context->s = Stream_New(NULL, 65536))) + goto fail; + + context->icon_x = UINT32_MAX; + context->icon_y = UINT32_MAX; + context->vcm = WTSOpenServerA((LPSTR)client->context); + + if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) + goto fail; + + return TRUE; +fail: + test_peer_context_free(client, ctx); + return FALSE; +} + static BOOL test_peer_init(freerdp_peer* client) { + WINPR_ASSERT(client); + client->ContextSize = sizeof(testPeerContext); client->ContextNew = test_peer_context_new; client->ContextFree = test_peer_context_free; @@ -147,6 +147,9 @@ static BOOL test_peer_init(freerdp_peer* client) static wStream* test_peer_stream_init(testPeerContext* context) { + WINPR_ASSERT(context); + WINPR_ASSERT(context->s); + Stream_Clear(context->s); Stream_SetPosition(context->s, 0); return context->s; @@ -154,21 +157,39 @@ static wStream* test_peer_stream_init(testPeerContext* context) static void test_peer_begin_frame(freerdp_peer* client) { - rdpUpdate* update = client->update; + rdpUpdate* update; SURFACE_FRAME_MARKER fm = { 0 }; - testPeerContext* context = (testPeerContext*)client->context; + testPeerContext* context; + + WINPR_ASSERT(client); + update = client->update; + WINPR_ASSERT(update); + + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + fm.frameAction = SURFACECMD_FRAMEACTION_BEGIN; fm.frameId = context->frame_id; + WINPR_ASSERT(update->SurfaceFrameMarker); update->SurfaceFrameMarker(update->context, &fm); } static void test_peer_end_frame(freerdp_peer* client) { - rdpUpdate* update = client->update; + rdpUpdate* update; SURFACE_FRAME_MARKER fm = { 0 }; - testPeerContext* context = (testPeerContext*)client->context; + testPeerContext* context; + + WINPR_ASSERT(client); + update = client->update; + WINPR_ASSERT(update); + + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + fm.frameAction = SURFACECMD_FRAMEACTION_END; fm.frameId = context->frame_id; + WINPR_ASSERT(update->SurfaceFrameMarker); update->SurfaceFrameMarker(update->context, &fm); context->frame_id++; } @@ -180,7 +201,7 @@ static BOOL test_peer_draw_background(freerdp_peer* client) RFX_RECT rect; BYTE* rgb_data; const rdpSettings* settings; - rdpUpdate* update = client->update; + rdpUpdate* update; SURFACE_BITS_COMMAND cmd = { 0 }; testPeerContext* context; BOOL ret = FALSE; @@ -192,6 +213,9 @@ static BOOL test_peer_draw_background(freerdp_peer* client) settings = client->settings; WINPR_ASSERT(settings); + update = client->update; + WINPR_ASSERT(update); + if (!settings->RemoteFxCodec && !freerdp_settings_get_bool(settings, FreeRDP_NSCodec)) return FALSE; @@ -258,13 +282,19 @@ out: static BOOL test_peer_load_icon(freerdp_peer* client) { - testPeerContext* context = (testPeerContext*)client->context; + testPeerContext* context; FILE* fp; int i; char line[50]; BYTE* rgb_data = NULL; int c; + WINPR_ASSERT(client); + + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + WINPR_ASSERT(client->settings); + if (!client->settings->RemoteFxCodec && !freerdp_settings_get_bool(client->settings, FreeRDP_NSCodec)) { @@ -324,14 +354,18 @@ static void test_peer_draw_icon(freerdp_peer* client, UINT32 x, UINT32 y) { wStream* s; RFX_RECT rect; - rdpUpdate* update = client->update; + rdpUpdate* update; SURFACE_BITS_COMMAND cmd = { 0 }; testPeerContext* context; WINPR_ASSERT(client); + WINPR_ASSERT(client->settings); + context = (testPeerContext*)client->context; WINPR_ASSERT(context); - WINPR_ASSERT(client->update); + + update = client->update; + WINPR_ASSERT(update); if (client->update->dump_rfx) return; @@ -379,6 +413,7 @@ static void test_peer_draw_icon(freerdp_peer* client, UINT32 x, UINT32 y) cmd.bmp.height = context->icon_height; cmd.bmp.bitmapDataLength = (UINT32)Stream_GetPosition(s); cmd.bmp.bitmapData = Stream_Buffer(s); + WINPR_ASSERT(update->SurfaceBits); update->SurfaceBits(update->context, &cmd); } @@ -400,6 +435,7 @@ static void test_peer_draw_icon(freerdp_peer* client, UINT32 x, UINT32 y) cmd.bmp.height = context->icon_height; cmd.bmp.bitmapDataLength = (UINT32)Stream_GetPosition(s); cmd.bmp.bitmapData = Stream_Buffer(s); + WINPR_ASSERT(update->SurfaceBits); update->SurfaceBits(update->context, &cmd); context->icon_x = x; context->icon_y = y; @@ -410,6 +446,9 @@ static BOOL test_sleep_tsdiff(UINT32* old_sec, UINT32* old_usec, UINT32 new_sec, { INT64 sec, usec; + WINPR_ASSERT(old_sec); + WINPR_ASSERT(old_usec); + if ((*old_sec == 0) && (*old_usec == 0)) { *old_sec = new_sec; @@ -452,14 +491,23 @@ static BOOL tf_peer_dump_rfx(freerdp_peer* client) rdpUpdate* update; rdpPcap* pcap_rfx; pcap_record record; + struct server_info* info; + + WINPR_ASSERT(client); + WINPR_ASSERT(client->context); + + info = client->ContextExtra; + WINPR_ASSERT(info); + s = Stream_New(NULL, 512); if (!s) return FALSE; update = client->update; + WINPR_ASSERT(update); - if (!(pcap_rfx = pcap_open(test_pcap_file, FALSE))) + if (!(pcap_rfx = pcap_open(info->test_pcap_file, FALSE))) return FALSE; prev_seconds = prev_useconds = 0; @@ -476,13 +524,15 @@ static BOOL tf_peer_dump_rfx(freerdp_peer* client) pcap_get_next_record_content(pcap_rfx, &record); Stream_SetPointer(s, Stream_Buffer(s) + Stream_Capacity(s)); - if (test_dump_rfx_realtime && + if (info->test_dump_rfx_realtime && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, record.header.ts_usec) == FALSE) break; + WINPR_ASSERT(update->SurfaceCommand); update->SurfaceCommand(update->context, s); + WINPR_ASSERT(client->CheckFileDescriptor); if (client->CheckFileDescriptor(client) != TRUE) break; } @@ -501,6 +551,7 @@ static DWORD WINAPI tf_debug_channel_thread_func(LPVOID arg) ULONG written; testPeerContext* context = (testPeerContext*)arg; + WINPR_ASSERT(context); if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE) { @@ -549,7 +600,14 @@ static DWORD WINAPI tf_debug_channel_thread_func(LPVOID arg) static BOOL tf_peer_post_connect(freerdp_peer* client) { - testPeerContext* context = (testPeerContext*)client->context; + testPeerContext* context; + + WINPR_ASSERT(client); + WINPR_ASSERT(client->settings); + + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + /** * This callback is called when the entire connection sequence is done, i.e. we've received the * Font List PDU from the client and sent out the Font Map PDU. @@ -638,14 +696,26 @@ static BOOL tf_peer_post_connect(freerdp_peer* client) static BOOL tf_peer_activate(freerdp_peer* client) { - testPeerContext* context = (testPeerContext*)client->context; + testPeerContext* context; + struct server_info* info; + + WINPR_ASSERT(client); + WINPR_ASSERT(client->settings); + WINPR_ASSERT(client->update); + + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + + info = client->ContextExtra; + WINPR_ASSERT(info); + context->activated = TRUE; // client->settings->CompressionLevel = PACKET_COMPR_TYPE_8K; // client->settings->CompressionLevel = PACKET_COMPR_TYPE_64K; // client->settings->CompressionLevel = PACKET_COMPR_TYPE_RDP6; - client->settings->CompressionLevel = PACKET_COMPR_TYPE_RDP61; + client->settings->CompressionLevel = PACKET_COMPR_TYPE_RDP8; - if (test_pcap_file != NULL) + if (info->test_pcap_file != NULL) { client->update->dump_rfx = TRUE; @@ -661,15 +731,30 @@ static BOOL tf_peer_activate(freerdp_peer* client) static BOOL tf_peer_synchronize_event(rdpInput* input, UINT32 flags) { WINPR_UNUSED(input); + WINPR_ASSERT(input); WLog_DBG(TAG, "Client sent a synchronize event (flags:0x%" PRIX32 ")", flags); return TRUE; } static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - freerdp_peer* client = input->context->peer; - rdpUpdate* update = client->update; - testPeerContext* context = (testPeerContext*)input->context; + freerdp_peer* client; + rdpUpdate* update; + testPeerContext* context; + + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + + client = input->context->peer; + WINPR_ASSERT(client); + WINPR_ASSERT(client->settings); + + update = client->update; + WINPR_ASSERT(update); + + context = (testPeerContext*)input->context; + WINPR_ASSERT(context); + WLog_DBG(TAG, "Client sent a keyboard event (flags:0x%04" PRIX16 " code:0x%04" PRIX16 ")", flags, code); @@ -690,6 +775,7 @@ static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) client->settings->DesktopHeight)) return FALSE; + WINPR_ASSERT(update->DesktopResize); update->DesktopResize(update->context); context->activated = FALSE; } @@ -703,6 +789,7 @@ static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) } else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */ { + WINPR_ASSERT(client->Close); client->Close(client); } else if ((flags & 0x4000) && code == 0x13) /* 'r' key */ @@ -719,6 +806,8 @@ static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) static BOOL tf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { WINPR_UNUSED(input); + WINPR_ASSERT(input); + WLog_DBG(TAG, "Client sent a unicode keyboard event (flags:0x%04" PRIX16 " code:0x%04" PRIX16 ")", flags, code); @@ -728,6 +817,9 @@ static BOOL tf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 static BOOL tf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { WINPR_UNUSED(flags); + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + // WLog_DBG(TAG, "Client sent a mouse event (flags:0x%04"PRIX16" pos:%"PRIu16",%"PRIu16")", // flags, x, y); test_peer_draw_icon(input->context->peer, x + 10, y); @@ -737,6 +829,9 @@ static BOOL tf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 static BOOL tf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { WINPR_UNUSED(flags); + WINPR_ASSERT(input); + WINPR_ASSERT(input->context); + // WLog_DBG(TAG, "Client sent an extended mouse event (flags:0x%04"PRIX16" // pos:%"PRIu16",%"PRIu16")", flags, x, y); test_peer_draw_icon(input->context->peer, x + 10, y); @@ -747,6 +842,9 @@ static BOOL tf_peer_refresh_rect(rdpContext* context, BYTE count, const RECTANGL { BYTE i; WINPR_UNUSED(context); + WINPR_ASSERT(context); + WINPR_ASSERT(areas || (count == 0)); + WLog_DBG(TAG, "Client requested to refresh:"); for (i = 0; i < count; i++) @@ -761,6 +859,7 @@ static BOOL tf_peer_refresh_rect(rdpContext* context, BYTE count, const RECTANGL static BOOL tf_peer_suppress_output(rdpContext* context, BYTE allow, const RECTANGLE_16* area) { WINPR_UNUSED(context); + WINPR_ASSERT(area); if (allow > 0) { @@ -779,12 +878,14 @@ static BOOL tf_peer_suppress_output(rdpContext* context, BYTE allow, const RECTA static DWORD WINAPI test_peer_mainloop(LPVOID arg) { DWORD error = CHANNEL_RC_OK; - HANDLE handles[32]; + HANDLE handles[32] = { 0 }; DWORD count; DWORD status; testPeerContext* context; freerdp_peer* client = (freerdp_peer*)arg; + WINPR_ASSERT(client); + if (!test_peer_init(client)) { freerdp_peer_free(client); @@ -792,6 +893,7 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) } /* Initialize the real server settings here */ + WINPR_ASSERT(client->settings); if (!freerdp_settings_set_string(client->settings, FreeRDP_CertificateFile, "server.crt") || !freerdp_settings_set_string(client->settings, FreeRDP_PrivateKeyFile, "server.key") || !freerdp_settings_set_string(client->settings, FreeRDP_RdpKeyFile, "server.key")) @@ -823,15 +925,23 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) client->update->RefreshRect = tf_peer_refresh_rect; client->update->SuppressOutput = tf_peer_suppress_output; client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */ + + WINPR_ASSERT(client->Initialize); client->Initialize(client); + context = (testPeerContext*)client->context; + WINPR_ASSERT(context); + WLog_INFO(TAG, "We've got a client %s", client->local ? "(local)" : client->hostname); while (error == CHANNEL_RC_OK) { count = 0; { - DWORD tmp = client->GetEventHandles(client, &handles[count], 32 - count); + DWORD tmp; + + WINPR_ASSERT(client->GetEventHandles); + tmp = client->GetEventHandles(client, &handles[count], 32 - count); if (tmp == 0) { @@ -850,6 +960,7 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) break; } + WINPR_ASSERT(client->CheckFileDescriptor); if (client->CheckFileDescriptor(client) != TRUE) break; @@ -888,6 +999,8 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) } WLog_INFO(TAG, "Client %s disconnected.", client->local ? "(local)" : client->hostname); + + WINPR_ASSERT(client->Disconnect); client->Disconnect(client); freerdp_peer_context_free(client); freerdp_peer_free(client); @@ -897,8 +1010,16 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) static BOOL test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { HANDLE hThread; + struct server_info* info; + WINPR_UNUSED(instance); + WINPR_ASSERT(instance); + WINPR_ASSERT(client); + + info = instance->info; + client->ContextExtra = info; + if (!(hThread = CreateThread(NULL, 0, test_peer_mainloop, (void*)client, 0, NULL))) return FALSE; @@ -908,12 +1029,14 @@ static BOOL test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) static void test_server_mainloop(freerdp_listener* instance) { - HANDLE handles[32]; + HANDLE handles[32] = { 0 }; DWORD count; DWORD status; + WINPR_ASSERT(instance); while (1) { + WINPR_ASSERT(instance->GetEventHandles); count = instance->GetEventHandles(instance, handles, 32); if (0 == count) @@ -930,6 +1053,7 @@ static void test_server_mainloop(freerdp_listener* instance) break; } + WINPR_ASSERT(instance->CheckFileDescriptor); if (instance->CheckFileDescriptor(instance) != TRUE) { WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); @@ -937,45 +1061,72 @@ static void test_server_mainloop(freerdp_listener* instance) } } + WINPR_ASSERT(instance->Close); instance->Close(instance); } +static const struct +{ + const char spcap[7]; + const char sfast[7]; + const char sport[7]; + const char slocal_only[13]; +} options = { "--pcap=", "--fast", "--port=", "--local-only" }; + +static WINPR_NORETURN(void usage(const char* app, const char* invalid)) +{ + FILE* fp = stdout; + fprintf(fp, "Invalid argument '%s'\n", invalid); + fprintf(fp, "Usage: %s [ ...]\n", app); + fprintf(fp, "Arguments:\n"); + fprintf(fp, "\t%s\n", options.spcap); + fprintf(fp, "\t%s\n", options.sfast); + fprintf(fp, "\t%s\n", options.sport); + fprintf(fp, "\t%s\n", options.slocal_only); + exit(-1); +} + int main(int argc, char* argv[]) { - const char spcap[] = "--"; - const char sfast[] = "--fast"; - const char sport[] = "--port="; - const char slocal_only[] = "--local_only"; + int rc = -1; + BOOL started = FALSE; WSADATA wsaData; freerdp_listener* instance; - char* file; + char* file = NULL; char name[MAX_PATH]; long port = 3389, i; BOOL localOnly = FALSE; + struct server_info info = { 0 }; + const char* app = argv[0]; + + info.test_dump_rfx_realtime = TRUE; + errno = 0; for (i = 1; i < argc; i++) { char* arg = argv[i]; - if (strncmp(arg, sfast, sizeof(sfast)) == 0) - test_dump_rfx_realtime = FALSE; - else if (strncmp(arg, sport, sizeof(sport) - 1) == 0) + if (strncmp(arg, options.sfast, sizeof(options.sfast)) == 0) + info.test_dump_rfx_realtime = FALSE; + else if (strncmp(arg, options.sport, sizeof(options.sport)) == 0) { - StrSep(&arg, "="); - - if (!arg) - return -1; - - port = strtol(arg, NULL, 10); + const char* sport = &arg[sizeof(options.sport)]; + port = strtol(sport, NULL, 10); if ((port < 1) || (port > UINT16_MAX) || (errno != 0)) - return -1; + usage(app, arg); } - else if (strncmp(arg, slocal_only, sizeof(slocal_only)) == 0) + else if (strncmp(arg, options.slocal_only, sizeof(options.slocal_only)) == 0) localOnly = TRUE; - else if (strncmp(arg, spcap, sizeof(spcap)) == 0) - test_pcap_file = arg; + else if (strncmp(arg, options.spcap, sizeof(options.spcap)) == 0) + { + info.test_pcap_file = &arg[sizeof(options.spcap)]; + if (!winpr_PathFileExists(info.test_pcap_file)) + usage(app, arg); + } + else + usage(app, arg); } WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi()); @@ -985,35 +1136,41 @@ int main(int argc, char* argv[]) if (!instance) return -1; + instance->info = (void*)&info; instance->PeerAccepted = test_peer_accepted; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) - { - freerdp_listener_free(instance); - return -1; - } + goto fail; /* Open the server socket and start listening. */ sprintf_s(name, sizeof(name), "tfreerdp-server.%ld", port); file = GetKnownSubPath(KNOWN_PATH_TEMP, name); if (!file) + goto fail; + + if (localOnly) { - freerdp_listener_free(instance); - WSACleanup(); - return -1; + WINPR_ASSERT(instance->OpenLocal); + started = instance->OpenLocal(instance, file); + } + else + { + WINPR_ASSERT(instance->Open); + started = instance->Open(instance, NULL, (UINT16)port); } - if ((localOnly || instance->Open(instance, NULL, (UINT16)port)) && - instance->OpenLocal(instance, file)) + if (started) { /* Entering the server main loop. In a real server the listener can be run in its own * thread. */ test_server_mainloop(instance); } + rc = 0; +fail: free(file); freerdp_listener_free(instance); WSACleanup(); - return 0; + return rc; }