diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index f6f48554c..c90a0818a 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -662,9 +662,9 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* * We cannot enter paths like c:\ because : is an arg separator * thus, paths are entered as c+\ and the + is substituted here */ - if ( path[1] == '+' ) + if (path[1] == '+') { - if ( (path[0]>='a' && path[0]<='z') || (path[0]>='A' && path[0]<='Z') ) + if ((path[0]>='a' && path[0]<='z') || (path[0]>='A' && path[0]<='Z')) { path[1] = ':'; } @@ -723,16 +723,40 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) path = drive->Path; #ifndef WIN32 + + if (strcmp(path, "*") == 0) + { + /* all drives */ + + free(path); + path = _strdup("/"); + } + else if (strcmp(path, "%") == 0) + { + char* home_env = NULL; + + /* home directory */ + + home_env = getenv("HOME"); + free(path); + + if (home_env) + path = _strdup(home_env); + else + path = _strdup("/"); + } + drive_register_drive_path(pEntryPoints, name, path); + #else /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ - if( path[0] == '%' ) + if (path[0] == '%') { _snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE")); drive_register_drive_path(pEntryPoints, name, _strdup(buf)); } - else if( path[0] == '*' ) + else if (path[0] == '*') { int i; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index aa28c5242..69af8d12d 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -71,9 +71,12 @@ COMMAND_LINE_ARGUMENT_A args[] = { "compression", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, "z", "Compression" }, { "shell", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Alternate shell" }, { "shell-dir", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Shell working directory" }, + { "sound", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "audio", "Audio output (sound)" }, + { "microphone", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mic", "Audio input (microphone)" }, { "audio-mode", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Audio output mode" }, - { "mic", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Audio input (microphone)" }, { "network", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Network connection type" }, + { "drives", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect all drives" }, + { "home-drive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect home drive" }, { "clipboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect clipboard" }, { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (cleartype)" }, { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" }, @@ -1051,6 +1054,14 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin { settings->CompressionEnabled = arg->Value ? TRUE : FALSE; } + CommandLineSwitchCase(arg, "drives") + { + settings->RedirectDrives = arg->Value ? TRUE : FALSE; + } + CommandLineSwitchCase(arg, "home-drive") + { + settings->RedirectHomeDrive = arg->Value ? TRUE : FALSE; + } CommandLineSwitchCase(arg, "clipboard") { settings->RedirectClipboard = arg->Value ? TRUE : FALSE; @@ -1063,6 +1074,64 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin { settings->ShellWorkingDirectory = _strdup(arg->Value); } + CommandLineSwitchCase(arg, "sound") + { + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + char** p; + int count; + + p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); + + p = (char**) realloc(p, sizeof(char*) * (count + 1)); + MoveMemory(&p[1], p, sizeof(char*) * count); + p[0] = "rdpsnd"; + count++; + + freerdp_client_add_static_channel(settings, count, p); + + free(p); + } + else + { + char* p[1]; + int count; + + count = 1; + p[0] = "rdpsnd"; + + freerdp_client_add_static_channel(settings, count, p); + } + } + CommandLineSwitchCase(arg, "microphone") + { + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + char** p; + int count; + + p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); + + p = (char**) realloc(p, sizeof(char*) * (count + 1)); + MoveMemory(&p[1], p, sizeof(char*) * count); + p[0] = "audin"; + count++; + + freerdp_client_add_dynamic_channel(settings, count, p); + + free(p); + } + else + { + char* p[1]; + int count; + + count = 1; + p[0] = "audin"; + + freerdp_client_add_dynamic_channel(settings, count, p); + } + } CommandLineSwitchCase(arg, "audio-mode") { int mode; @@ -1405,6 +1474,38 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) settings->AudioPlayback = TRUE; /* Both rdpsnd and tsmf require this flag to be set */ } + if (settings->RedirectDrives) + { + settings->DeviceRedirection = TRUE; + + if (!freerdp_device_collection_find(settings, "drive")) + { + char* params[3]; + + params[0] = "drive"; + params[1] = "media"; + params[2] = "*"; + + freerdp_client_add_device_channel(settings, 3, (char**) params); + } + } + + if (settings->RedirectHomeDrive) + { + settings->DeviceRedirection = TRUE; + + if (!freerdp_device_collection_find(settings, "drive")) + { + char* params[3]; + + params[0] = "drive"; + params[1] = "home"; + params[2] = "%"; + + freerdp_client_add_device_channel(settings, 3, (char**) params); + } + } + if (settings->DeviceRedirection) { freerdp_client_load_static_channel_addin(channels, settings, "rdpdr", settings); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 64a2f261c..f46d13b88 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -929,6 +929,7 @@ struct rdp_settings /* Drive Redirection */ ALIGN64 BOOL RedirectDrives; /* */ + ALIGN64 BOOL RedirectHomeDrive; /* */ ALIGN64 char* DrivesToRedirect; /* */ /* Smartcard Redirection */ @@ -988,6 +989,7 @@ FREERDP_API int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char* option, char* value); 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 void freerdp_device_collection_free(rdpSettings* settings); FREERDP_API void freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel); diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 4a8a8ee8f..89c11e9ab 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -143,6 +143,22 @@ void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device) settings->DeviceArray[settings->DeviceCount++] = device; } +RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name) +{ + int index; + RDPDR_DEVICE* device; + + for (index = 0; index < settings->DeviceCount; index++) + { + device = (RDPDR_DEVICE*) settings->DeviceArray[index]; + + if (strcmp(device->Name, name) == 0) + return device; + } + + return NULL; +} + void freerdp_device_collection_free(rdpSettings* settings) { int index; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index a0e06e1d7..918f62421 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -743,9 +743,7 @@ STREAM* transport_receive_pool_take(rdpTransport* transport) pdu = Queue_Dequeue(transport->ReceivePool); if (!pdu) - { pdu = stream_new(BUFFER_SIZE); - } pdu->p = pdu->data; @@ -775,9 +773,7 @@ rdpTransport* transport_new(rdpSettings* settings) transport->SleepInterval = 100; transport->ReceivePool = Queue_New(TRUE, -1, -1); - transport->ReceiveQueue = Queue_New(TRUE, -1, -1); - Queue_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free; - Queue_Object(transport->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) stream_free; + //Queue_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free; /* receive buffer for non-blocking read. */ transport->ReceiveBuffer = transport_receive_pool_take(transport); @@ -799,9 +795,6 @@ void transport_free(rdpTransport* transport) { if (transport != NULL) { - if (transport->ReceiveBuffer) - stream_free(transport->ReceiveBuffer); - stream_free(transport->ReceiveStream); stream_free(transport->SendStream); CloseHandle(transport->ReceiveEvent); @@ -820,7 +813,6 @@ void transport_free(rdpTransport* transport) tsg_free(transport->tsg); Queue_Free(transport->ReceivePool); - Queue_Free(transport->ReceiveQueue); free(transport); }