libfreerdp-core: fix deep cloning of rdpSettings*
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sat, 19 Oct 2013 02:42:50 +0000 (22:42 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sat, 19 Oct 2013 02:42:50 +0000 (22:42 -0400)
include/freerdp/settings.h
libfreerdp/common/settings.c
libfreerdp/core/settings.c

index dbd8ad6..406a318 100644 (file)
@@ -1315,14 +1315,17 @@ FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* pre
 
 FREERDP_API void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device);
 FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name);
+FREERDP_API RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device);
 FREERDP_API void freerdp_device_collection_free(rdpSettings* settings);
 
 FREERDP_API void freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel);
 FREERDP_API ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name);
+FREERDP_API ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel);
 FREERDP_API void freerdp_static_channel_collection_free(rdpSettings* settings);
 
 FREERDP_API void freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel);
 FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const char* name);
+FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel);
 FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings);
 
 FREERDP_API void freerdp_performance_flags_make(rdpSettings* settings);
index 90af694..d0cc73f 100644 (file)
@@ -164,6 +164,74 @@ RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char*
        return NULL;
 }
 
+RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device)
+{
+       RDPDR_DEVICE* _device = NULL;
+
+       if (device->Type == RDPDR_DTYP_FILESYSTEM)
+       {
+               RDPDR_DRIVE* drive = (RDPDR_DRIVE*) device;
+               RDPDR_DRIVE* _drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE));
+
+               _drive->Id = drive->Id;
+               _drive->Type = drive->Type;
+               _drive->Name = _strdup(drive->Name);
+               _drive->Path = _strdup(drive->Path);
+
+               _device = (RDPDR_DEVICE*) _drive;
+       }
+       else if (device->Type == RDPDR_DTYP_PRINT)
+       {
+               RDPDR_PRINTER* printer = (RDPDR_PRINTER*) device;
+               RDPDR_PRINTER* _printer = (RDPDR_PRINTER*) malloc(sizeof(RDPDR_PRINTER));
+
+               _printer->Id = printer->Id;
+               _printer->Type = printer->Type;
+               _printer->Name = _strdup(printer->Name);
+               _printer->DriverName = _strdup(printer->DriverName);
+
+               _device = (RDPDR_DEVICE*) _printer;
+       }
+       else if (device->Type == RDPDR_DTYP_SMARTCARD)
+       {
+               RDPDR_SMARTCARD* smartcard = (RDPDR_SMARTCARD*) device;
+               RDPDR_SMARTCARD* _smartcard = (RDPDR_SMARTCARD*) malloc(sizeof(RDPDR_SMARTCARD));
+
+               _smartcard->Id = smartcard->Id;
+               _smartcard->Type = smartcard->Type;
+               _smartcard->Name = _strdup(smartcard->Name);
+               _smartcard->Path = _strdup(smartcard->Path);
+
+               _device = (RDPDR_DEVICE*) _smartcard;
+       }
+       else if (device->Type == RDPDR_DTYP_SERIAL)
+       {
+               RDPDR_SERIAL* serial = (RDPDR_SERIAL*) device;
+               RDPDR_SERIAL* _serial = (RDPDR_SERIAL*) malloc(sizeof(RDPDR_SERIAL));
+
+               _serial->Id = serial->Id;
+               _serial->Type = serial->Type;
+               _serial->Name = _strdup(serial->Name);
+               _serial->Path = _strdup(serial->Path);
+
+               _device = (RDPDR_DEVICE*) _serial;
+       }
+       else if (device->Type == RDPDR_DTYP_PARALLEL)
+       {
+               RDPDR_PARALLEL* parallel = (RDPDR_PARALLEL*) device;
+               RDPDR_PARALLEL* _parallel = (RDPDR_PARALLEL*) malloc(sizeof(RDPDR_PARALLEL));
+
+               _parallel->Id = parallel->Id;
+               _parallel->Type = parallel->Type;
+               _parallel->Name = _strdup(parallel->Name);
+               _parallel->Path = _strdup(parallel->Path);
+
+               _device = (RDPDR_DEVICE*) _parallel;
+       }
+
+       return _device;
+}
+
 void freerdp_device_collection_free(rdpSettings* settings)
 {
        int index;
@@ -234,6 +302,24 @@ ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const
        return NULL;
 }
 
+ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel)
+{
+       int index;
+       ADDIN_ARGV* _channel = NULL;
+
+       _channel = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV));
+
+       _channel->argc = channel->argc;
+       _channel->argv = (char**) malloc(sizeof(char*) * channel->argc);
+
+       for (index = 0; index < _channel->argc; index++)
+       {
+               _channel->argv[index] = _strdup(channel->argv[index]);
+       }
+
+       return _channel;
+}
+
 void freerdp_static_channel_collection_free(rdpSettings* settings)
 {
        int i, j;
@@ -282,6 +368,24 @@ ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const
        return NULL;
 }
 
+ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel)
+{
+       int index;
+       ADDIN_ARGV* _channel = NULL;
+
+       _channel = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV));
+
+       _channel->argc = channel->argc;
+       _channel->argv = (char**) malloc(sizeof(char*) * channel->argc);
+
+       for (index = 0; index < _channel->argc; index++)
+       {
+               _channel->argv[index] = _strdup(channel->argv[index]);
+       }
+
+       return _channel;
+}
+
 void freerdp_dynamic_channel_collection_free(rdpSettings* settings)
 {
        int index;
index 972519d..898fdd2 100644 (file)
@@ -425,6 +425,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
 
 rdpSettings* freerdp_settings_clone(rdpSettings* settings)
 {
+       int index;
        rdpSettings* _settings;
 
        _settings = (rdpSettings*) malloc(sizeof(rdpSettings));
@@ -724,20 +725,38 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
                _settings->ClientTimeZone = (TIME_ZONE_INFO*) malloc(sizeof(TIME_ZONE_INFO));
                CopyMemory(_settings->ClientTimeZone, _settings->ClientTimeZone, sizeof(TIME_ZONE_INFO));
 
-               _settings->DeviceArraySize = 16;
+               _settings->DeviceCount = settings->DeviceCount;
+               _settings->DeviceArraySize = settings->DeviceArraySize;
                _settings->DeviceArray = (RDPDR_DEVICE**) malloc(sizeof(RDPDR_DEVICE*) * _settings->DeviceArraySize);
                ZeroMemory(_settings->DeviceArray, sizeof(RDPDR_DEVICE*) * _settings->DeviceArraySize);
 
-               _settings->StaticChannelArraySize = 16;
+               for (index = 0; index < _settings->DeviceCount; index++)
+               {
+                       _settings->DeviceArray[index] = freerdp_device_clone(settings->DeviceArray[index]);
+               }
+
+               _settings->StaticChannelCount = settings->StaticChannelCount;
+               _settings->StaticChannelArraySize = settings->StaticChannelArraySize;
                _settings->StaticChannelArray = (ADDIN_ARGV**)
                                malloc(sizeof(ADDIN_ARGV*) * _settings->StaticChannelArraySize);
                ZeroMemory(_settings->StaticChannelArray, sizeof(ADDIN_ARGV*) * _settings->StaticChannelArraySize);
 
-               _settings->DynamicChannelArraySize = 16;
+               for (index = 0; index < _settings->StaticChannelCount; index++)
+               {
+                       _settings->StaticChannelArray[index] = freerdp_static_channel_clone(settings->StaticChannelArray[index]);
+               }
+
+               _settings->DynamicChannelCount = settings->DynamicChannelCount;
+               _settings->DynamicChannelArraySize = settings->DynamicChannelArraySize;
                _settings->DynamicChannelArray = (ADDIN_ARGV**)
                                malloc(sizeof(ADDIN_ARGV*) * _settings->DynamicChannelArraySize);
                ZeroMemory(_settings->DynamicChannelArray, sizeof(ADDIN_ARGV*) * _settings->DynamicChannelArraySize);
 
+               for (index = 0; index < _settings->DynamicChannelCount; index++)
+               {
+                       _settings->DynamicChannelArray[index] = freerdp_dynamic_channel_clone(settings->DynamicChannelArray[index]);
+               }
+
                _settings->SettingsModified = (BYTE*) malloc(sizeof(rdpSettings) / 8);
                ZeroMemory(_settings->SettingsModified, sizeof(rdpSettings) / 8);
        }