mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 08:24:16 +09:00
Merge branch 'master' of github.com:FreeRDP/FreeRDP
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -37,6 +37,9 @@ external/*
|
||||
# Documentation
|
||||
docs/api
|
||||
client/X11/xfreerdp.1
|
||||
client/X11/xfreerdp.1.xml
|
||||
client/X11/xfreerdp-channels.1.xml
|
||||
client/X11/xfreerdp-examples.1.xml
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
||||
@@ -417,12 +417,12 @@ set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}")
|
||||
set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions")
|
||||
|
||||
# Include directories
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# Configure files
|
||||
add_definitions("-DHAVE_CONFIG_H")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
# RPATH configuration
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
@@ -447,8 +447,8 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
|
||||
# WinPR
|
||||
set(WINPR_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/winpr/include")
|
||||
include_directories(${WINPR_INCLUDE_DIR})
|
||||
include_directories("${CMAKE_SOURCE_DIR}/winpr/include")
|
||||
include_directories("${CMAKE_BINARY_DIR}/winpr/include")
|
||||
|
||||
add_subdirectory(winpr)
|
||||
|
||||
|
||||
@@ -19,16 +19,16 @@ set(MODULE_NAME "freerdp-channels-client")
|
||||
set(MODULE_PREFIX "FREERDP_CHANNELS_CLIENT")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
tables.c
|
||||
tables.h
|
||||
addin.c
|
||||
addin.h
|
||||
init.c
|
||||
init.h
|
||||
open.c
|
||||
open.h
|
||||
channels.c
|
||||
channels.h)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tables.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tables.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.h)
|
||||
|
||||
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
|
||||
|
||||
@@ -96,7 +96,7 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
|
||||
endforeach()
|
||||
set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};")
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_SOURCE_DIR}/tables.c)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_BINARY_DIR}/tables.c)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
||||
@@ -87,14 +87,15 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS
|
||||
if (!cliprdr->use_long_format_names)
|
||||
name_length = 32;
|
||||
|
||||
Stream_EnsureRemainingCapacity(body, Stream_Capacity(body) + 4 + name_length);
|
||||
Stream_EnsureRemainingCapacity(body, 4 + name_length);
|
||||
|
||||
Stream_Write_UINT32(body, cb_event->formats[i]);
|
||||
Stream_Write(body, name, name_length);
|
||||
}
|
||||
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Capacity(body));
|
||||
Stream_Write(s, Stream_Buffer(body), Stream_Capacity(body));
|
||||
Stream_SealLength(body);
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Length(body));
|
||||
Stream_Write(s, Stream_Buffer(body), Stream_Length(body));
|
||||
Stream_Free(body, TRUE);
|
||||
}
|
||||
|
||||
@@ -290,16 +291,16 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
|
||||
|
||||
void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
|
||||
{
|
||||
/* where is this documented? */
|
||||
#if 0
|
||||
/* http://msdn.microsoft.com/en-us/library/hh872154.aspx */
|
||||
wMessage* event;
|
||||
|
||||
if ((msgFlags & CB_RESPONSE_FAIL) != 0)
|
||||
{
|
||||
event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL);
|
||||
/* In case of an error the clipboard will not be synchronized with the server.
|
||||
* Post this event to restart format negociation and data transfer. */
|
||||
event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
|
||||
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
|
||||
|
||||
@@ -286,6 +286,7 @@ static void parallel_free(DEVICE* device)
|
||||
MessageQueue_PostQuit(parallel->queue, 0);
|
||||
WaitForSingleObject(parallel->thread, INFINITE);
|
||||
|
||||
Stream_Free(parallel->device.data, TRUE);
|
||||
MessageQueue_Free(parallel->queue);
|
||||
CloseHandle(parallel->thread);
|
||||
|
||||
|
||||
@@ -179,13 +179,16 @@ static void* printer_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg;
|
||||
HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(printer_dev->event, INFINITE);
|
||||
DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(printer_dev->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (rc == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
else if( rc != WAIT_OBJECT_0 )
|
||||
continue;
|
||||
|
||||
ResetEvent(printer_dev->event);
|
||||
|
||||
|
||||
@@ -323,29 +323,28 @@ static void* serial_thread_func(void* arg)
|
||||
IRP* irp;
|
||||
DWORD status;
|
||||
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
|
||||
HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue)};
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
status = WaitForMultipleObjects(2, ev, FALSE, 1);
|
||||
|
||||
status = WaitForSingleObject(Queue_Event(serial->queue), 10);
|
||||
|
||||
if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT))
|
||||
if (WAIT_OBJECT_0 == status)
|
||||
break;
|
||||
|
||||
serial->nfds = 1;
|
||||
FD_ZERO(&serial->read_fds);
|
||||
FD_ZERO(&serial->write_fds);
|
||||
|
||||
serial->tv.tv_sec = 1;
|
||||
serial->tv.tv_sec = 0;
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
if (status == WAIT_OBJECT_0)
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
|
||||
serial_process_irp(serial, irp);
|
||||
continue;
|
||||
}
|
||||
|
||||
serial_check_fds(serial);
|
||||
@@ -367,10 +366,18 @@ static void serial_free(DEVICE* device)
|
||||
|
||||
DEBUG_SVC("freeing device");
|
||||
|
||||
/* Stop thread */
|
||||
SetEvent(serial->stopEvent);
|
||||
WaitForSingleObject(serial->thread, INFINITE);
|
||||
|
||||
/* TODO: free lists */
|
||||
serial_tty_free(serial->tty);
|
||||
|
||||
/* Clean up resources */
|
||||
Stream_Free(serial->device.data, TRUE);
|
||||
Queue_Free(serial->queue);
|
||||
list_free(serial->pending_irps);
|
||||
CloseHandle(serial->stopEvent);
|
||||
CloseHandle(serial->thread);
|
||||
free(serial);
|
||||
}
|
||||
|
||||
@@ -383,6 +390,11 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (abort_io)
|
||||
{
|
||||
@@ -433,6 +445,11 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
|
||||
SERIAL_TTY* tty;
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
@@ -478,6 +495,11 @@ void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, UINT32* timeout, UINT3
|
||||
DEBUG_SVC("length read %u", Length);
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
*timeout = (tty->read_total_timeout_multiplier * Length) + tty->read_total_timeout_constant;
|
||||
*interval_timeout = tty->read_interval_timeout;
|
||||
@@ -492,6 +514,11 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
|
||||
SERIAL_TTY* tty;
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (irp->MajorFunction)
|
||||
{
|
||||
@@ -542,6 +569,11 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
|
||||
ZeroMemory(&serial->tv, sizeof(struct timeval));
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
|
||||
/* scan every pending */
|
||||
irp = list_peek(serial->pending_irps);
|
||||
@@ -604,6 +636,11 @@ static void serial_set_fds(SERIAL_DEVICE* serial)
|
||||
DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps));
|
||||
|
||||
tty = serial->tty;
|
||||
if(!tty)
|
||||
{
|
||||
DEBUG_WARN("tty = %p", tty);
|
||||
return;
|
||||
}
|
||||
irp = (IRP*) list_peek(serial->pending_irps);
|
||||
|
||||
while (irp)
|
||||
@@ -705,7 +742,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial);
|
||||
|
||||
serial->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
|
||||
serial->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) serial_thread_func, (void*) serial, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -412,7 +412,11 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
|
||||
status = read(tty->fd, buffer, *Length);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
DEBUG_WARN("failed with %zd, errno=[%d] %s\n",
|
||||
status, errno, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tty->event_txempty = status;
|
||||
*Length = status;
|
||||
@@ -456,6 +460,9 @@ void serial_tty_free(SERIAL_TTY* tty)
|
||||
{
|
||||
DEBUG_SVC("in");
|
||||
|
||||
if(!tty)
|
||||
return;
|
||||
|
||||
if (tty->fd >= 0)
|
||||
{
|
||||
if (tty->pold_termios)
|
||||
|
||||
@@ -44,8 +44,7 @@ static void smartcard_free(DEVICE* dev)
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev;
|
||||
|
||||
SetEvent(smartcard->stopEvent);
|
||||
CloseHandle(smartcard->thread);
|
||||
CloseHandle(smartcard->irpEvent);
|
||||
WaitForSingleObject(smartcard->thread, INFINITE);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
@@ -55,8 +54,14 @@ static void smartcard_free(DEVICE* dev)
|
||||
/* Begin TS Client defect workaround. */
|
||||
|
||||
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL)
|
||||
free(CompletionIdInfo);
|
||||
free(CompletionIdInfo);
|
||||
|
||||
CloseHandle(smartcard->thread);
|
||||
CloseHandle(smartcard->irpEvent);
|
||||
CloseHandle(smartcard->stopEvent);
|
||||
CloseHandle(smartcard->CompletionIdsMutex);
|
||||
|
||||
Stream_Free(smartcard->device.data, TRUE);
|
||||
list_free(smartcard->CompletionIds);
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
@@ -119,13 +124,16 @@ static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
|
||||
static void* smartcard_thread_func(void* arg)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
|
||||
HANDLE ev[] = {smartcard->irpEvent, smartcard->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(smartcard->irpEvent, INFINITE);
|
||||
DWORD status = WaitForSingleObject(2, ev, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
else if(status != WAIT_OBJECT_0)
|
||||
continue;
|
||||
|
||||
ResetEvent(smartcard->irpEvent);
|
||||
smartcard_process_irp_list(smartcard);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
set(MODULE_NAME "xfreerdp-client")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_X11_CONTROL")
|
||||
|
||||
include(FindXmlto)
|
||||
include(FindDocBookXSL)
|
||||
include_directories(${X11_INCLUDE_DIRS})
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
@@ -68,18 +68,43 @@ set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_DL_LIBS})
|
||||
|
||||
if(WITH_MANPAGES)
|
||||
if(XMLTO_FOUND)
|
||||
find_program( XSLTPROC_EXECUTABLE NAMES xsltproc)
|
||||
|
||||
if(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
|
||||
|
||||
# We need the variable ${MAN_TODAY} to contain the current date in ISO
|
||||
# format to replace it in the configure_file step.
|
||||
include(today)
|
||||
|
||||
TODAY(MAN_TODAY)
|
||||
|
||||
configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY IMMEDIATE)
|
||||
|
||||
add_executable(generate_argument_docbook
|
||||
generate_argument_docbook.c)
|
||||
target_link_libraries(generate_argument_docbook winpr-utils freerdp-core freerdp-utils freerdp-client)
|
||||
|
||||
add_custom_command(OUTPUT xfreerdp.1
|
||||
COMMAND ${XMLTO_EXECUTABLE} man ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml
|
||||
DEPENDS xfreerdp.1.xml)
|
||||
COMMAND generate_argument_docbook
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml
|
||||
generate_argument_docbook)
|
||||
|
||||
add_custom_target(xfreerdp.manpage ALL
|
||||
DEPENDS xfreerdp.1)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION share/man/man1)
|
||||
else(XMLTO_FOUND)
|
||||
message(WARNING "WITH_MANPAGES was set, but xmlto was not found. man-pages will not be installed")
|
||||
endif(XMLTO_FOUND)
|
||||
else(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
|
||||
message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed")
|
||||
endif(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
|
||||
endif(WITH_MANPAGES)
|
||||
|
||||
set(XSHM_FEATURE_TYPE "REQUIRED")
|
||||
|
||||
177
client/X11/generate_argument_docbook.c
Normal file
177
client/X11/generate_argument_docbook.c
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
/* We need to include the command line c file to get access to
|
||||
* the argument struct. */
|
||||
#include "../common/cmdline.c"
|
||||
|
||||
LPSTR tmp = NULL;
|
||||
|
||||
LPCSTR tr_esc_str(LPCSTR arg)
|
||||
{
|
||||
size_t cs = 0, x, ds;
|
||||
size_t s;
|
||||
|
||||
if( NULL == arg )
|
||||
return NULL;
|
||||
|
||||
s = strlen(arg);
|
||||
|
||||
/* Find trailing whitespaces */
|
||||
while( (s > 0) && isspace(arg[s-1]))
|
||||
s--;
|
||||
|
||||
/* Prepare a initial buffer with the size of the result string. */
|
||||
tmp = malloc(s * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not allocate string buffer.");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
/* Copy character for character and check, if it is necessary to escape. */
|
||||
ds = s + 1;
|
||||
for(x=0; x<s; x++)
|
||||
{
|
||||
switch(arg[x])
|
||||
{
|
||||
case '<':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-3);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'l';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '>':
|
||||
ds += 3;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-4);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'g';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '\'':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-5);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 's';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '"':
|
||||
ds += 5;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-6);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'q';
|
||||
tmp[cs++] = 'u';
|
||||
tmp[cs++] = 'o';
|
||||
tmp[cs++] = 't';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
case '&':
|
||||
ds += 4;
|
||||
tmp = realloc(tmp, ds * sizeof(LPCSTR));
|
||||
if( NULL == tmp )
|
||||
{
|
||||
fprintf(stderr, "Could not reallocate string buffer.");
|
||||
exit(-7);
|
||||
}
|
||||
tmp[cs++] = '&';
|
||||
tmp[cs++] = 'a';
|
||||
tmp[cs++] = 'm';
|
||||
tmp[cs++] = 'p';
|
||||
tmp[cs++] = ';';
|
||||
break;
|
||||
default:
|
||||
tmp[cs++] = arg[x];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assure, the string is '\0' terminated. */
|
||||
tmp[ds-1] = '\0';
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
size_t elements = sizeof(args)/sizeof(args[0]);
|
||||
size_t x;
|
||||
const char *fname = "xfreerdp-argument.1.xml";
|
||||
FILE *fp = NULL;
|
||||
|
||||
/* Open output file for writing, truncate if existing. */
|
||||
fp = fopen(fname, "w");
|
||||
if( NULL == fp )
|
||||
{
|
||||
fprintf(stderr, "Could not open '%s' for writing.", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The tag used as header in the manpage */
|
||||
fprintf(fp, "<refsect1>\n");
|
||||
fprintf(fp, "\t<title>Options</title>\n");
|
||||
fprintf(fp, "\t\t<variablelist>\n");
|
||||
|
||||
/* Iterate over argument struct and write data to docbook 4.5
|
||||
* compatible XML */
|
||||
if( elements < 2 )
|
||||
{
|
||||
fprintf(stderr, "The argument array 'args' is empty, writing an empty file.");
|
||||
elements = 1;
|
||||
}
|
||||
|
||||
for(x=0; x<elements - 1; x++)
|
||||
{
|
||||
const COMMAND_LINE_ARGUMENT_A *arg = &args[x];
|
||||
|
||||
fprintf(fp, "\t\t\t<varlistentry>\n");
|
||||
if( COMMAND_LINE_VALUE_REQUIRED == arg->Flags )
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option> <replaceable>%s</replaceable></term>\n", tr_esc_str(arg->Name), tr_esc_str(arg->Format) );
|
||||
else
|
||||
fprintf(fp, "\t\t\t\t<term><option>/%s</option></term>\n", tr_esc_str(arg->Name) );
|
||||
fprintf(fp, "\t\t\t\t<listitem>\n");
|
||||
fprintf(fp, "\t\t\t\t\t<para>%s</para>\n", tr_esc_str(arg->Text));
|
||||
|
||||
fprintf(fp, "\t\t\t\t</listitem>\n");
|
||||
fprintf(fp, "\t\t\t</varlistentry>\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t</variablelist>\n");
|
||||
fprintf(fp, "\t</refsect1>\n");
|
||||
fclose(fp);
|
||||
|
||||
if(NULL != tmp)
|
||||
free(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
0
client/X11/xfreerdp-channels.1.xml
Normal file
0
client/X11/xfreerdp-channels.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
89
client/X11/xfreerdp-examples.1.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp connection.rdp /p:Pwd123! /f</command></term>
|
||||
<listitem>
|
||||
<para>Connect in fullscreen mode using a stored configuration <replaceable>connection.rdp</replaceable> and the password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>rdp.contoso.com</replaceable> with user <replaceable>CONTOSO\\JohnDoe</replaceable> and password <replaceable>Pwd123!</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489</command></term>
|
||||
<listitem>
|
||||
<para>Connect to host <replaceable>192.168.1.100</replaceable> on port <replaceable>4489</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable>. The screen width is set to <replaceable>1366</replaceable> and the height to <replaceable>768</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168. 1.100</command></term>
|
||||
<listitem>
|
||||
<para>Establish a connection to host <replaceable>192.168.1.100</replaceable> with user <replaceable>JohnDoe</replaceable>, password <replaceable>Pwd123!</replaceable> and connect to Hyper-V console (use port 2179, disable negotiation) with VMID <replaceable>C824F53E-95D2-46C6-9A18-23A5BB403532</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>+clipboard</command></term>
|
||||
<listitem>
|
||||
<para>Activate clipboard redirection</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/drive:home,/home/user</command></term>
|
||||
<listitem>
|
||||
<para>Activate drive redirection of <replaceable>/home/user</replaceable> as home drive</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/smartcard:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate smartcard redirection for device <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/printer:<device>,<driver></command></term>
|
||||
<listitem>
|
||||
<para>Activate printer redirection for printer <replaceable>device</replaceable> using driver <replaceable>driver</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/serial:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate serial port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/parallel:<device></command></term>
|
||||
<listitem>
|
||||
<para>Activate parallel port redirection for port <replaceable>device</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/sound:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio output redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/microphone:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate audio input redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/multimedia:sys:alsa</command></term>
|
||||
<listitem>
|
||||
<para>Activate multimedia redirection using device <replaceable>sys:alsa</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>/usb:id,dev:054c:0268</command></term>
|
||||
<listitem>
|
||||
<para>Activate USB device redirection for the device identified by <replaceable>054c:0268</replaceable></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
@@ -1,571 +0,0 @@
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>2011-08-27</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>2011-08-27</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [options] server[:port] [[options] server[:port] …]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>2011-08-27</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-0</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Attach to the admin console of the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-a <replaceable class="parameter">bpp</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the color depth for the connection to <replaceable class="parameter">bpp</replaceable> bits per pixel.
|
||||
Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="WorkingDir">
|
||||
<term>-c <replaceable class="parameter">dir</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the working-dir to <replaceable class="parameter">dir</replaceable>.
|
||||
This parameter is only used when an AlternateShell (<xref linkend="AlternateShell"/>) is requested.
|
||||
<replaceable class="parameter">dir</replaceable> should contain the executable file specified in the AlternateShell.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Removes the windows decorations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Domain used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-f</term>
|
||||
<listitem>
|
||||
<para>
|
||||
start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-T <replaceable class="parameter">text</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the window title to <replaceable class="parameter">text</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-g <replaceable class="parameter">geometry</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the size of the FreeRDP window (and of the remote desktop, when establishing a new connection).
|
||||
<replaceable class="parameter">geometry</replaceable> can have one of the following forms:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> -
|
||||
in this case the resulting window will be of
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> pixels.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">P</replaceable>% -
|
||||
in this case the resulting window will be <replaceable class="parameter">P</replaceable>%
|
||||
of your screen.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The special keyword <emphasis>workarea</emphasis> -
|
||||
in this case the resulting window will be of the same size as your workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print help.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the keyboard-layout-id to <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-K</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not interfere with window manager bindings. Normally, xfreerdp captures all keystrokes while its window is focused.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">hostname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the reported client hostname to <replaceable class="parameter">hostname</replaceable>.
|
||||
Default is to automatically detect the hostname.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-o</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Play audio on the console instead of redirecting to the client.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-p <replaceable class="parameter">password</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Password used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="AlternateShell">
|
||||
<term>-s <replaceable class="parameter">shell</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the startup-shell to <replaceable class="parameter">shell</replaceable>.
|
||||
This parameter should contain a complete path to the alternate shell.
|
||||
If the alternete shell requires a different working directory use <xref linkend="WorkingDir"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-t <replaceable class="parameter">port</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Connect to <replaceable class="parameter">port</replaceable>, instead of the default 3389.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-u <replaceable class="parameter">username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Username used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-x <replaceable class="parameter">flag</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the experience performance flags.
|
||||
<replaceable class="parameter">flag</replaceable> can be one of:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
m - (modem): Equivalent to 15.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
b - (broadband): Equivalent to 1.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
l - (lan): Equivalent to 0.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">num</replaceable> - A hexadecimal number that
|
||||
represents a bit-mask, were numbers mean the following
|
||||
<footnote><para>Taken from <ulink url="http://msdn.microsoft.com/en-us/library/cc240476%28v=prot.10%29.aspx">
|
||||
MS-RDPBCGR Section 2.2.1.11.1.1.1 - Extended Info Packet</ulink></para></footnote>:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>1: Disable desktop wallpaper.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>2: Disable full-window drag (only the window outline is displayed when the window is moved).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>4: Disable menu animations.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>8: Disable user interface themes.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>20: Disable mouse cursor shadows.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>40: Disable cursor blinking.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>80: Enable font smoothing.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>100: Enable Desktop Composition.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-X <replaceable class="parameter">xid</replaceable></term>
|
||||
<listitem>
|
||||
<para>embed xfreerdp into window with <replaceable class="parameter">xid</replaceable>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable compression.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--app</term>
|
||||
<listitem>
|
||||
<para>
|
||||
initialize a RemoteApp connection. This implies -g workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-auth</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--authonly</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Only authenticates. This is useful to test your credentials (username and password).
|
||||
Returns status code 0 if the client can connect, 1 otherwise. Requires a username,
|
||||
password and connection host at the command line.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--bcv3 <replaceable class="parameter">codec</replaceable></term>
|
||||
<listitem>
|
||||
<para>Use <replaceable class="parameter">codec</replaceable> for bitmap cache v3
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-bmp-cache</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable bitmap cache.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--certificate-name <replaceable class="parameter">name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
use <replaceable class="parameter">name</replaceable> for the logon certificate, instead of the server name
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--composition</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable composition (RDVH only, not to be confused with remote composition).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ext <replaceable class="parameter">extname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load extension <replaceable class="parameter">extname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-fastpath</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disables fast-path. Use slow-path packets instead, which have larger headers.
|
||||
It might be good for debugging certain issues when you suspect it might be
|
||||
linked to the parsing of one of the two header types.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--from-stdin</term>
|
||||
<listitem>
|
||||
<para>Prompts for unspecified arguments -u username, -p
|
||||
password, -d domain and connection host. This is useful to
|
||||
hide arguments from ps. Also useful for scripts that will
|
||||
feed these arguments to the client via (what else?) stdin.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-full-window-drag</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable full window drag.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--gdi <replaceable class="parameter">backend</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
GDI (Graphics Device Interface) rendering backend. <replaceable class="parameter">backend</replaceable> can be either sw (software) or hw (hardware).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ignore-certificate</term>
|
||||
<listitem>
|
||||
<para>
|
||||
ignore verification of logon certificate.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--kbd-list</term>
|
||||
<listitem>
|
||||
<para>
|
||||
list all keyboard layout ids used by -k
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-menu-animations</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable menu animations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-motion</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Don't send mouse motion events.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nego</term>
|
||||
<listitem>
|
||||
<para>disable negotiation of security layer and enforce highest enabled security protocol.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nla</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable network level authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--nsc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable NSCodec.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-osb</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable off screen bitmaps.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcb <replaceable class="parameter">blob</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">blob</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--pcid <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use preconnection <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--plugin <replaceable class="parameter">pluginname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
load <replaceable class="parameter">pluginname</replaceable>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-rdp</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable RemoteFX.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx-mode</term>
|
||||
<listitem>
|
||||
<para>
|
||||
RemoteFX operational flags. <replaceable class="parameter">flags</replaceable> can be either v[ideo], i[mage]), default is video.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-salted-checksum</term>
|
||||
<listitem>
|
||||
<para>
|
||||
disable salted checksums with Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ntlm</term>
|
||||
<listitem>
|
||||
<para>
|
||||
force NTLM protocol version. <replaceable class="parameter">version</replaceable> can be one of 1 or 2.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--sec <replaceable class="parameter">proto</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
force protocol security. <replaceable class="parameter">proto</replaceable> can be one of rdp, tls or nla.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-theming</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable theming.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-tls</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable TLS encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--tsg
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable> </term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use Terminal Server Gateway with
|
||||
<replaceable class="parameter">username</replaceable>
|
||||
<replaceable class="parameter">password</replaceable>
|
||||
<replaceable class="parameter">hostname</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print version information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--disable-wallpaper</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable wallpaper.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
60
client/X11/xfreerdp.1.xml.in
Normal file
60
client/X11/xfreerdp.1.xml.in
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE refentry
|
||||
PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY syntax SYSTEM "xfreerdp-argument.1.xml">
|
||||
<!ENTITY channels SYSTEM "xfreerdp-channels.1.xml">
|
||||
<!ENTITY examples SYSTEM "xfreerdp-examples.1.xml">
|
||||
]
|
||||
>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>FreeRDP X11 client</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [file] [options] [/v:server[:port]]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>@MAN_TODAY@</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is an X11 Remote Desktop Protocol (RDP)
|
||||
client which is part of the FreeRDP project. An RDP server is built-in
|
||||
to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox).
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
&syntax;
|
||||
|
||||
&channels;
|
||||
|
||||
&examples;
|
||||
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
@@ -25,9 +25,10 @@ set(${MODULE_PREFIX}_SRCS
|
||||
compatibility.h
|
||||
file.c)
|
||||
|
||||
set(FREERDP_CHANNELS_CLIENT_PATH "../../channels/client")
|
||||
foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS})
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_PATH}/${FREERDP_CHANNELS_CLIENT_SRC}")
|
||||
get_filename_component(NINC ${FREERDP_CHANNELS_CLIENT_SRC} PATH)
|
||||
include_directories(${NINC})
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_SRC}")
|
||||
endforeach()
|
||||
|
||||
if(MSVC)
|
||||
|
||||
52
cmake/FindDocBookXSL.cmake
Normal file
52
cmake/FindDocBookXSL.cmake
Normal file
@@ -0,0 +1,52 @@
|
||||
# Try to find DocBook XSL stylesheet
|
||||
# Once done, it will define:
|
||||
#
|
||||
# DOCBOOKXSL_FOUND - system has the required DocBook XML DTDs
|
||||
# DOCBOOKXSL_DIR - the directory containing the stylesheets
|
||||
# used to process DocBook XML
|
||||
|
||||
# Copyright (c) 2010, Luigi Toscano, <luigi.toscano@tiscali.it>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
set (STYLESHEET_PATH_LIST
|
||||
share/xml/docbook/stylesheet/docbook-xsl
|
||||
share/xml/docbook/xsl-stylesheets
|
||||
share/sgml/docbook/xsl-stylesheets
|
||||
share/xml/docbook/stylesheet/nwalsh/current
|
||||
share/xml/docbook/stylesheet/nwalsh
|
||||
share/xsl/docbook
|
||||
share/xsl/docbook-xsl
|
||||
)
|
||||
|
||||
find_path (DOCBOOKXSL_DIR lib/lib.xsl
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
|
||||
if (NOT DOCBOOKXSL_DIR)
|
||||
# hacks for systems that put the version in the stylesheet dirs
|
||||
set (STYLESHEET_PATH_LIST)
|
||||
foreach (STYLESHEET_PREFIX_ITER ${CMAKE_SYSTEM_PREFIX_PATH})
|
||||
file(GLOB STYLESHEET_SUFFIX_ITER RELATIVE ${STYLESHEET_PREFIX_ITER}
|
||||
${STYLESHEET_PREFIX_ITER}/share/xml/docbook/xsl-stylesheets-*
|
||||
)
|
||||
if (STYLESHEET_SUFFIX_ITER)
|
||||
list (APPEND STYLESHEET_PATH_LIST ${STYLESHEET_SUFFIX_ITER})
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
find_path (DOCBOOKXSL_DIR VERSION
|
||||
PATHS ${CMAKE_SYSTEM_PREFIX_PATH}
|
||||
PATH_SUFFIXES ${STYLESHEET_PATH_LIST}
|
||||
)
|
||||
endif (NOT DOCBOOKXSL_DIR)
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (DocBookXSL
|
||||
"Could NOT find DocBook XSL stylesheets"
|
||||
DOCBOOKXSL_DIR)
|
||||
|
||||
mark_as_advanced (DOCBOOKXSL_DIR)
|
||||
16
cmake/today.cmake
Normal file
16
cmake/today.cmake
Normal file
@@ -0,0 +1,16 @@
|
||||
# This script returns the current date in ISO format
|
||||
#
|
||||
# YYYY-MM-DD
|
||||
#
|
||||
MACRO (TODAY RESULT)
|
||||
IF (WIN32)
|
||||
EXECUTE_PROCESS(COMMAND "cmd" " /C date +%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSEIF(UNIX)
|
||||
EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}})
|
||||
ELSE (WIN32)
|
||||
MESSAGE(SEND_ERROR "date not implemented")
|
||||
SET(${RESULT} 000000)
|
||||
ENDIF (WIN32)
|
||||
ENDMACRO (TODAY)
|
||||
@@ -292,24 +292,38 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
|
||||
rdp_client_disconnect(rdp);
|
||||
|
||||
/* FIXME: this is a subset of rdp_free */
|
||||
/* --> this should really go into rdp.c */
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = NULL ;
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = NULL;
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
rdp->fips_encrypt = NULL ;
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
rdp->fips_decrypt = NULL ;
|
||||
crypto_hmac_free(rdp->fips_hmac);
|
||||
rdp->fips_hmac = NULL ;
|
||||
|
||||
free(settings->ServerRandom);
|
||||
settings->ServerRandom = NULL ;
|
||||
free(settings->ServerCertificate);
|
||||
settings->ServerCertificate = NULL ;
|
||||
free(settings->ClientAddress);
|
||||
settings->ClientAddress = NULL ;
|
||||
|
||||
mppc_enc_free(rdp->mppc_enc);
|
||||
mppc_dec_free(rdp->mppc_dec);
|
||||
mcs_free(rdp->mcs);
|
||||
nego_free(rdp->nego);
|
||||
license_free(rdp->license);
|
||||
transport_free(rdp->transport);
|
||||
|
||||
free(settings->ServerRandom);
|
||||
free(settings->ServerCertificate);
|
||||
free(settings->ClientAddress);
|
||||
|
||||
rdp->transport = transport_new(settings);
|
||||
rdp->license = license_new(rdp);
|
||||
rdp->nego = nego_new(rdp->transport);
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
rdp->mppc_dec = mppc_dec_new();
|
||||
rdp->mppc_enc = mppc_enc_new(PROTO_RDP_50);
|
||||
|
||||
rdp->transport->layer = TRANSPORT_LAYER_TCP;
|
||||
settings->RedirectedSessionId = redirection->sessionID;
|
||||
|
||||
@@ -739,7 +739,11 @@ int transport_check_fds(rdpTransport** ptransport)
|
||||
|
||||
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
|
||||
|
||||
Stream_Release(received);
|
||||
if (transport == *ptransport)
|
||||
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
|
||||
/* so only release if still valid */
|
||||
Stream_Release(received);
|
||||
|
||||
|
||||
if (recv_status < 0)
|
||||
status = -1;
|
||||
|
||||
@@ -63,11 +63,14 @@ endif()
|
||||
|
||||
if(FREERDP_BUILD)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include PARENT_SCOPE)
|
||||
else()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
endif()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/winpr/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/winpr/config.h)
|
||||
|
||||
if(NOT WITH_WAYK)
|
||||
add_subdirectory(include)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
@@ -43,6 +45,18 @@
|
||||
|
||||
#include "../handle/handle.h"
|
||||
|
||||
static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
|
||||
{
|
||||
ts->tv_sec += dwMilliseconds / 1000L;
|
||||
ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L;
|
||||
|
||||
while(ts->tv_nsec >= 1000000000L)
|
||||
{
|
||||
ts->tv_sec ++;
|
||||
ts->tv_nsec -= 1000000000L;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
ULONG Type;
|
||||
@@ -53,18 +67,30 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
|
||||
if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
int status;
|
||||
int status = 0;
|
||||
WINPR_THREAD* thread;
|
||||
void* thread_status = NULL;
|
||||
|
||||
if (dwMilliseconds != INFINITE)
|
||||
fprintf(stderr, "WaitForSingleObject: timeout not implemented for thread wait\n");
|
||||
|
||||
thread = (WINPR_THREAD*) Object;
|
||||
|
||||
if (thread->started)
|
||||
{
|
||||
status = pthread_join(thread->thread, &thread_status);
|
||||
if (dwMilliseconds != INFINITE)
|
||||
{
|
||||
#if _GNU_SOURCE
|
||||
struct timespec timeout;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||
ts_add_ms(&timeout, dwMilliseconds);
|
||||
|
||||
status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout);
|
||||
#else
|
||||
fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__);
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
status = pthread_join(thread->thread, &thread_status);
|
||||
|
||||
if (status != 0)
|
||||
fprintf(stderr, "WaitForSingleObject: pthread_join failure: %d\n", status);
|
||||
@@ -80,9 +106,16 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
mutex = (WINPR_MUTEX*) Object;
|
||||
|
||||
if (dwMilliseconds != INFINITE)
|
||||
fprintf(stderr, "WaitForSingleObject: timeout not implemented for mutex wait\n");
|
||||
{
|
||||
struct timespec timeout;
|
||||
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
clock_gettime(CLOCK_REALTIME, &timeout);
|
||||
ts_add_ms(&timeout, dwMilliseconds);
|
||||
|
||||
pthread_mutex_timedlock(&mutex->mutex, &timeout);
|
||||
}
|
||||
else
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_EVENT)
|
||||
{
|
||||
@@ -213,6 +246,8 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
|
||||
DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
@@ -235,7 +270,10 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if (bWaitAll)
|
||||
{
|
||||
fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (index = 0; index < nCount; index++)
|
||||
{
|
||||
@@ -336,11 +374,15 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
|
||||
DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
fprintf(stderr, "[ERROR] %s: Function not implemented.\n", __func__);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count)
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wStream*));
|
||||
if (pool->uSize - index + count > 0)
|
||||
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index + count) * sizeof(wStream*));
|
||||
pool->uSize += count;
|
||||
}
|
||||
}
|
||||
@@ -101,7 +102,8 @@ void StreamPool_ShiftAvailable(wStreamPool* pool, int index, int count)
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wStream*));
|
||||
if (pool->aSize - index + count > 0)
|
||||
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index + count) * sizeof(wStream*));
|
||||
pool->aSize += count;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user