Implemented writing RDP file to disk

TODO: Optimize by only writing the fields that have a value i.e
~((size_t) file->FieldName) != 0

Fixed wfi leak.
Fixed insufficient mem alloc.
This commit is contained in:
Benoit LeBlanc
2013-04-22 16:08:47 -04:00
parent 3549e97abb
commit 3eebd2edf2
7 changed files with 377 additions and 11 deletions

View File

@@ -44,7 +44,7 @@
#include <freerdp/utils/event.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/client/file.h>
//#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
@@ -57,14 +57,28 @@
#include "resource.h"
wfInfo* wf_wfi_new()
{
wfInfo* wfi;
wfi = (wfInfo*) malloc(sizeof(wfInfo));
ZeroMemory(wfi, sizeof(wfInfo));
return wfi;
}
void wf_wfi_free(wfInfo* wfi)
{
free(wfi);
}
void wf_context_new(freerdp* instance, rdpContext* context)
{
wfInfo* wfi;
context->channels = freerdp_channels_new();
wfi = (wfInfo*) malloc(sizeof(wfInfo));
ZeroMemory(wfi, sizeof(wfInfo));
wfi = wf_wfi_new();
((wfContext*) context)->wfi = wfi;
wfi->instance = instance;
@@ -76,6 +90,9 @@ void wf_context_free(freerdp* instance, rdpContext* context)
cache_free(context->cache);
freerdp_channels_free(context->channels);
wf_wfi_free(((wfContext*) context)->wfi);
((wfContext*) context)->wfi = NULL;
}
int wf_create_console(void)
@@ -207,7 +224,6 @@ BOOL wf_pre_connect(freerdp* instance)
{
int i1;
wfInfo* wfi;
rdpFile* file;
wfContext* context;
rdpSettings* settings;
@@ -220,14 +236,17 @@ BOOL wf_pre_connect(freerdp* instance)
if (settings->ConnectionFile)
{
file = freerdp_client_rdp_file_new();
if (wfi->connectionRdpFile)
{
freerdp_client_rdp_file_free(wfi->connectionRdpFile);
}
wfi->connectionRdpFile = freerdp_client_rdp_file_new();
fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
freerdp_client_parse_rdp_file(file, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(file, settings);
freerdp_client_rdp_file_free(file);
freerdp_client_parse_rdp_file(wfi->connectionRdpFile, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(wfi->connectionRdpFile, settings);
}
settings->OsMajorType = OSMAJORTYPE_WINDOWS;
@@ -976,5 +995,67 @@ int freerdp_client_set_param_string(wfInfo* cfi, int id, char* param)
int freerdp_client_set_callback_function(wfInfo* cfi, callbackFunc callbackFunc)
{
cfi->callback_func = callbackFunc;
return 0;
}
// TODO: Some of that code is a duplicate of wf_pre_connect. Refactor?
int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename)
{
rdpSettings* settings;
settings = cfi->instance->settings;
if (filename)
{
settings->ConnectionFile = _strdup(filename);
// free old settings file
freerdp_client_rdp_file_free(cfi->connectionRdpFile);
cfi->connectionRdpFile = freerdp_client_rdp_file_new();
fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile);
if (!freerdp_client_parse_rdp_file(cfi->connectionRdpFile, settings->ConnectionFile))
{
return 1;
}
if (!freerdp_client_populate_settings_from_rdp_file(cfi->connectionRdpFile, settings))
{
return 2;
}
}
return 0;
}
int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename)
{
if (filename == NULL)
return 1;
if (cfi->instance->settings->ConnectionFile)
{
free(cfi->instance->settings->ConnectionFile);
}
cfi->instance->settings->ConnectionFile = _strdup(filename);
// Reuse existing rdpFile structure if available, to preserve unsupported settings when saving to disk.
if (cfi->connectionRdpFile == NULL)
{
cfi->connectionRdpFile = freerdp_client_rdp_file_new();
}
if (!freerdp_client_populate_rdp_file_from_settings(cfi->connectionRdpFile, cfi->instance->settings))
{
return 1;
}
if (!freerdp_client_write_rdp_file(cfi->connectionRdpFile, filename, UNICODE));
{
return 2;
}
return 0;
}

View File

@@ -35,6 +35,7 @@
#include <freerdp/channels/channels.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/nsc.h>
#include <freerdp/client/file.h>
#include "wf_event.h"
@@ -124,6 +125,8 @@ struct wf_info
BOOL sw_gdi;
callbackFunc callback_func;
rdpFile* connectionRdpFile;
};
/**
@@ -160,6 +163,9 @@ FREERDP_API int freerdp_client_set_param_string(wfInfo* cfi, int id, char* param
FREERDP_API int freerdp_client_set_callback_function(wfInfo* cfi, callbackFunc callbackFunc);
FREERDP_API int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename);
FREERDP_API int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename);
#ifdef __cplusplus
}
#endif

View File

@@ -695,6 +695,7 @@ int freerdp_parse_username(char* username, char** user, char** domain)
int freerdp_set_connection_type(rdpSettings* settings, int type)
{
settings->ConnectionType = type;
if (type == CONNECTION_TYPE_MODEM)
{
settings->DisableWallpaper = TRUE;
@@ -764,6 +765,43 @@ int freerdp_set_connection_type(rdpSettings* settings, int type)
return 0;
}
FREERDP_API int freerdp_get_connection_type(rdpSettings* settings)
{
int connectionType;
connectionType = settings->ConnectionType;
if (~settings->ConnectionType)
{
if (settings->NetworkAutoDetect)
{
connectionType = CONNECTION_TYPE_AUTODETECT;
}
else if (settings->DisableThemes == TRUE)
{
connectionType = CONNECTION_TYPE_MODEM;
}
else if (settings->DisableWallpaper == TRUE)
{
if (settings->AllowDesktopComposition == FALSE)
{
connectionType = CONNECTION_TYPE_BROADBAND_LOW;
}
else
{
// SATELLITE or BROADBAND_HIGH: same criteria?
connectionType = CONNECTION_TYPE_BROADBAND_HIGH;
}
}
else
{
// WAN or LAN: same criteria?
connectionType = CONNECTION_TYPE_WAN;
}
}
return connectionType;
}
int freerdp_map_keyboard_layout_name_to_id(char* name)
{
int i;

View File

@@ -478,6 +478,239 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
}
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings)
{
if (settings->Domain)
file->Domain = settings->Domain;
if (settings->Username)
{
file->Username = settings->Username;
}
if (settings->ServerPort)
file->ServerPort = settings->ServerPort;
if (settings->ServerHostname)
file->FullAddress = settings->ServerHostname;
if (settings->DesktopWidth)
file->DesktopWidth = settings->DesktopWidth;
if (settings->DesktopHeight)
file->DesktopHeight = settings->DesktopHeight;
if (settings->ColorDepth)
file->SessionBpp = settings->ColorDepth;
if (settings->ConsoleSession)
file->ConnectToConsole = settings->ConsoleSession;
if (settings->ConsoleSession)
file->AdministrativeSession = settings->ConsoleSession;
if (settings->NegotiateSecurityLayer)
file->NegotiateSecurityLayer = settings->NegotiateSecurityLayer;
if (settings->NlaSecurity)
file->EnableCredSSPSupport = settings->NlaSecurity;
if (settings->AlternateShell)
file->AlternateShell = settings->AlternateShell;
if (settings->ShellWorkingDirectory)
file->ShellWorkingDirectory = settings->ShellWorkingDirectory;
file->ConnectionType = freerdp_get_connection_type(settings);
if (settings->AudioPlayback)
{
file->AudioMode = AUDIO_MODE_REDIRECT;
}
else if (settings->RemoteConsoleAudio)
{
file->AudioMode = AUDIO_MODE_PLAY_ON_SERVER;
}
else
{
file->AudioMode = AUDIO_MODE_NONE;
}
if (settings->GatewayHostname)
file->GatewayHostname = settings->GatewayHostname;
if (settings->GatewayUsageMethod)
file->GatewayUsageMethod = TRUE;
if (settings->GatewayUseSameCredentials)
file->PromptCredentialOnce = TRUE;
if (settings->RemoteApplicationMode)
file->RemoteApplicationMode = settings->RemoteApplicationMode;
if (settings->RemoteApplicationProgram)
file->RemoteApplicationProgram = settings->RemoteApplicationProgram;
if (settings->RemoteApplicationName)
file->RemoteApplicationName = settings->RemoteApplicationName;
if (settings->RemoteApplicationIcon)
file->RemoteApplicationIcon = settings->RemoteApplicationIcon;
if (settings->RemoteApplicationFile)
file->RemoteApplicationFile = settings->RemoteApplicationFile;
if (settings->RemoteApplicationGuid)
file->RemoteApplicationGuid = settings->RemoteApplicationGuid;
if (settings->RemoteApplicationCmdLine)
file->RemoteApplicationCmdLine = settings->RemoteApplicationCmdLine;
if (settings->SpanMonitors)
file->SpanMonitors = settings->SpanMonitors;
if (settings->UseMultimon)
file->UseMultiMon = settings->UseMultimon;
return TRUE;
}
BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
{
BOOL success = FALSE;
char* buffer;
char *str;
int len, len2;
FILE* fp = NULL;
WCHAR* unicodestr = NULL;
len = _snprintf(str, len + 1, "%s %d", "test abcdefg", 123);
printf("%s %d\n", str, len);
free(str);
len = freerdp_client_write_rdp_file_buffer(file, NULL, 0);
if (len <= 0)
{
fprintf(stderr, "freerdp_client_write_rdp_file: Error determining buffer size.\n");
return FALSE;
}
buffer = (char*) malloc((len + 1) * sizeof(char));
len2 = freerdp_client_write_rdp_file_buffer(file, buffer, len + 1);
if (len2 == len)
{
fp = fopen(name, "w+b");
if (fp != NULL)
{
if (unicode)
{
ConvertToUnicode(CP_UTF8, 0, buffer, len, &unicodestr, 0);
// Write multi-byte header
fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp);
fwrite(unicodestr, 2, len, fp);
free(unicodestr);
}
else
{
fwrite(buffer, 1, len, fp);
}
fflush(fp);
fclose(fp);
}
}
if (buffer != NULL)
free(buffer);
return success;
}
// TODO: Optimize by only writing the fields that have a value i.e ~((size_t) file->FieldName) != 0
size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size)
{
return _snprintf(buffer, size,
"screen mode id:i:%d\n"
"use multimon:i:%d\n"
"desktopwidth:i:%d\n"
"desktopheight:i:%d\n"
"session bpp:i:%d\n"
"winposstr:s:%s\n"
"compression:i:%d\n"
"keyboardhook:i:%d\n"
"audiocapturemode:i:%d\n"
"videoplaybackmode:i:%d\n"
"connection type:i:%d\n"
"networkautodetect:i:%d\n"
"bandwidthautodetect:i:%d\n"
"displayconnectionbar:i:%d\n"
"enableworkspacereconnect:i:%d\n"
"disable wallpaper:i:%d\n"
"allow font smoothing:i:%d\n"
"allow desktop composition:i:%d\n"
"disable full window drag:i:%d\n"
"disable menu anims:i:%d\n"
"disable themes:i:%d\n"
"disable cursor setting:i:%d\n"
"bitmapcachepersistenable:i:%d\n"
"full address:s:%s\n"
"audiomode:i:%d\n"
"redirectprinters:i:%d\n"
"redirectcomports:i:%d\n"
"redirectsmartcards:i:%d\n"
"redirectclipboard:i:%d\n"
"redirectposdevices:i:%d\n"
"autoreconnection enabled:i:%d\n"
"authentication level:i:%d\n"
"prompt for credentials:i:%d\n"
"negotiate security layer:i:%d\n"
"remoteapplicationmode:i:%d\n"
"alternate shell:s:%s\n"
"shell working directory:s:%s\n"
"gatewayhostname:s:%s\n"
"gatewayusagemethod:i:%d\n"
"gatewaycredentialssource:i:%d\n"
"gatewayprofileusagemethod:i:%d\n"
"promptcredentialonce:i:%d\n"
"use redirection server name:i:%d\n"
"rdgiskdcproxy:i:%d\n"
"kdcproxyname:s:%s\n"
"drivestoredirect:s:%s\n"
"username:s:%s\n",
file->ScreenModeId,
file->UseMultiMon,
file->DesktopWidth,
file->DesktopHeight,
file->SessionBpp,
(~((size_t) file->WinPosStr) && file->WinPosStr != NULL) ? file->WinPosStr : "",
file->Compression,
file->KeyboardHook,
file->AudioCaptureMode,
file->VideoPlaybackMode,
file->ConnectionType,
file->NetworkAutoDetect,
file->BandwidthAutoDetect,
file->DisplayConnectionBar,
file->EnableWorkspaceReconnect,
file->DisableWallpaper,
file->AllowFontSmoothing,
file->AllowDesktopComposition,
file->DisableFullWindowDrag,
file->DisableMenuAnims,
file->DisableThemes,
file->DisableCursorSetting,
file->BitmapCachePersistEnable,
(~((size_t) file->FullAddress) && file->FullAddress != NULL) ? file->FullAddress : "",
file->AudioMode,
file->RedirectPrinters,
file->RedirectComPorts,
file->RedirectSmartCards,
file->RedirectClipboard,
file->RedirectPosDevices,
file->AutoReconnectionEnabled,
file->AuthenticationLevel,
file->PromptForCredentials,
file->NegotiateSecurityLayer,
file->RemoteApplicationMode,
(~((size_t) file->AlternateShell) && file->AlternateShell != NULL) ? file->AlternateShell : "",
(~((size_t) file->ShellWorkingDirectory) && file->ShellWorkingDirectory != NULL) ? file->ShellWorkingDirectory : "",
(~((size_t) file->GatewayHostname) && file->GatewayHostname != NULL) ? file->GatewayHostname : "",
file->GatewayUsageMethod,
file->GatewayCredentialsSource,
file->GatewayProfileUsageMethod,
file->PromptCredentialOnce,
file->UseRedirectionServerName,
file->RdgIsKdcProxy,
(~((size_t) file->KdcProxyName) && file->KdcProxyName != NULL) ? file->KdcProxyName : "",
(~((size_t) file->DrivesToRedirect) && file->DrivesToRedirect != NULL) ? file->DrivesToRedirect : "",
(~((size_t) file->Username) && file->Username != NULL) ? file->Username : "");
}
BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings)
{
if (~((size_t) file->Domain))
@@ -491,7 +724,9 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
freerdp_parse_username(file->Username, &user, &domain);
settings->Username = user;
settings->Domain = domain;
if (domain != NULL)
settings->Domain = domain;
}
if (~file->ServerPort)

View File

@@ -36,6 +36,8 @@ FREERDP_API int freerdp_client_print_command_line_help(int argc, char** argv);
FREERDP_API int freerdp_parse_username(char* username, char** user, char** domain);
FREERDP_API int freerdp_set_connection_type(rdpSettings* settings, int type);
FREERDP_API int freerdp_get_connection_type(rdpSettings* settings);
FREERDP_API int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** params);
FREERDP_API int freerdp_client_add_static_channel(rdpSettings* settings, int count, char** params);
FREERDP_API int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params);

View File

@@ -141,6 +141,10 @@ FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name);
FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size);
FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings);
FREERDP_API BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings);
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode);
FREERDP_API size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size);
FREERDP_API rdpFile* freerdp_client_rdp_file_new(void);
FREERDP_API void freerdp_client_rdp_file_free(rdpFile* file);

View File

@@ -127,7 +127,7 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
#ifdef UNICODE
length = strlen(hostname);
hostnameX = (LPWSTR) malloc(length * sizeof(TCHAR));
hostnameX = (LPWSTR) malloc((length + 1)* sizeof(TCHAR));
MultiByteToWideChar(CP_UTF8, 0, hostname, length, hostnameX, length);
hostnameX[length] = 0;
#else