Removed static channel variables.
Global static variables do not work, if more than one instance of an RDP client is running in the same process space. Removed the varaibles where possible and replaced them with thread local storage where necessary.
This commit is contained in:
parent
2e40c9c99d
commit
dadc5262ae
File diff suppressed because it is too large
Load Diff
@ -52,9 +52,6 @@ struct cliprdr_plugin
|
|||||||
};
|
};
|
||||||
typedef struct cliprdr_plugin cliprdrPlugin;
|
typedef struct cliprdr_plugin cliprdrPlugin;
|
||||||
|
|
||||||
wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen);
|
|
||||||
UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* data_out);
|
|
||||||
|
|
||||||
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr);
|
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr);
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_CLIPRDR
|
#ifdef WITH_DEBUG_CLIPRDR
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#define TAG CHANNELS_TAG("drdynvc.client")
|
#define TAG CHANNELS_TAG("drdynvc.client")
|
||||||
|
|
||||||
|
static WINPR_TLS drdynvcPlugin* s_TLSPluginContext = NULL;
|
||||||
|
|
||||||
static void dvcman_channel_free(void* channel);
|
static void dvcman_channel_free(void* channel);
|
||||||
static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
|
static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
|
||||||
const BYTE* data, UINT32 dataSize);
|
const BYTE* data, UINT32 dataSize);
|
||||||
@ -439,8 +441,8 @@ static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr,
|
static UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr,
|
||||||
UINT32 ChannelId, const char* ChannelName)
|
UINT32 ChannelId, const char* ChannelName)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
BOOL bAccept;
|
BOOL bAccept;
|
||||||
@ -740,8 +742,8 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
|
static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId,
|
||||||
const BYTE* data, UINT32 dataSize)
|
const BYTE* data, UINT32 dataSize)
|
||||||
{
|
{
|
||||||
wStream* data_out;
|
wStream* data_out;
|
||||||
unsigned long pos;
|
unsigned long pos;
|
||||||
@ -1128,105 +1130,6 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
static wListDictionary* g_InitHandles = NULL;
|
|
||||||
static wListDictionary* g_OpenHandles = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
static UINT drdynvc_add_init_handle_data(void* pInitHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
if (!g_InitHandles)
|
|
||||||
g_InitHandles = ListDictionary_New(TRUE);
|
|
||||||
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* drdynvc_get_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drdynvc_remove_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
|
||||||
|
|
||||||
if (ListDictionary_Count(g_InitHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_InitHandles);
|
|
||||||
g_InitHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
g_OpenHandles = ListDictionary_New(TRUE);
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* drdynvc_get_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drdynvc_remove_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
|
||||||
|
|
||||||
if (ListDictionary_Count(g_OpenHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_OpenHandles);
|
|
||||||
g_OpenHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@ -1292,11 +1195,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle,
|
|||||||
UINT event,
|
UINT event,
|
||||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
drdynvcPlugin* drdynvc;
|
drdynvcPlugin* drdynvc = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
drdynvc = (drdynvcPlugin*) drdynvc_get_open_handle_data(openHandle);
|
|
||||||
|
|
||||||
if (!drdynvc)
|
if (!drdynvc || (drdynvc->OpenHandle != openHandle))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match");
|
WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match");
|
||||||
return;
|
return;
|
||||||
@ -1331,6 +1233,7 @@ static void* drdynvc_virtual_channel_client_thread(void* arg)
|
|||||||
wMessage message;
|
wMessage message;
|
||||||
drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg;
|
drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
freerdp_channel_init_thread_context(drdynvc->rdpcontext);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -1398,12 +1301,6 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = drdynvc_add_open_handle_data(drdynvc->OpenHandle, drdynvc)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "drdynvc_add_open_handle_data failed with error %lu!", error);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
drdynvc->queue = MessageQueue_New(NULL);
|
drdynvc->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
if (!drdynvc->queue)
|
if (!drdynvc->queue)
|
||||||
@ -1450,9 +1347,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
error:
|
error:
|
||||||
drdynvc_remove_open_handle_data(drdynvc->OpenHandle);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,6 +1380,8 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
|
|||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drdynvc->OpenHandle = 0;
|
||||||
|
|
||||||
if (drdynvc->data_in)
|
if (drdynvc->data_in)
|
||||||
{
|
{
|
||||||
Stream_Free(drdynvc->data_in, TRUE);
|
Stream_Free(drdynvc->data_in, TRUE);
|
||||||
@ -1497,7 +1394,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
|
|||||||
drdynvc->channel_mgr = NULL;
|
drdynvc->channel_mgr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
drdynvc_remove_open_handle_data(drdynvc->OpenHandle);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,7 +1404,7 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc)
|
|||||||
*/
|
*/
|
||||||
static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
|
static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
|
||||||
{
|
{
|
||||||
drdynvc_remove_init_handle_data(drdynvc->InitHandle);
|
drdynvc->InitHandle = 0;
|
||||||
free(drdynvc);
|
free(drdynvc);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
@ -1517,11 +1413,10 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle,
|
|||||||
UINT event, LPVOID pData,
|
UINT event, LPVOID pData,
|
||||||
UINT dataLength)
|
UINT dataLength)
|
||||||
{
|
{
|
||||||
drdynvcPlugin* drdynvc;
|
drdynvcPlugin* drdynvc = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
drdynvc = (drdynvcPlugin*) drdynvc_get_init_handle_data(pInitHandle);
|
|
||||||
|
|
||||||
if (!drdynvc)
|
if (!drdynvc || (drdynvc->InitHandle != pInitHandle))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match");
|
WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match");
|
||||||
return;
|
return;
|
||||||
@ -1576,7 +1471,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
drdynvcPlugin* drdynvc;
|
drdynvcPlugin* drdynvc;
|
||||||
DrdynvcClientContext* context;
|
DrdynvcClientContext* context;
|
||||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||||
UINT error;
|
|
||||||
drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin));
|
drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin));
|
||||||
|
|
||||||
if (!drdynvc)
|
if (!drdynvc)
|
||||||
@ -1625,9 +1519,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
||||||
WTSErrorToString(rc), rc);
|
WTSErrorToString(rc), rc);
|
||||||
|
free(drdynvc->context);
|
||||||
free(drdynvc);
|
free(drdynvc);
|
||||||
free(*(pEntryPointsEx->ppInterface));
|
|
||||||
*(pEntryPointsEx->ppInterface) = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,17 +1528,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
(drdynvc->channelEntryPoints.ppInterface);
|
(drdynvc->channelEntryPoints.ppInterface);
|
||||||
drdynvc->channelEntryPoints.ppInterface = &
|
drdynvc->channelEntryPoints.ppInterface = &
|
||||||
(drdynvc->channelEntryPoints.pInterface);
|
(drdynvc->channelEntryPoints.pInterface);
|
||||||
|
s_TLSPluginContext = drdynvc;
|
||||||
if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle,
|
|
||||||
(void*) drdynvc)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!", error);
|
|
||||||
free(drdynvc);
|
|
||||||
free(*(pEntryPointsEx->ppInterface));
|
|
||||||
*(pEntryPointsEx->ppInterface) = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,8 @@
|
|||||||
#include "rail_orders.h"
|
#include "rail_orders.h"
|
||||||
#include "rail_main.h"
|
#include "rail_main.h"
|
||||||
|
|
||||||
|
static WINPR_TLS railPlugin* s_TLSPluginContext = NULL;
|
||||||
|
|
||||||
RailClientContext* rail_get_client_interface(railPlugin* rail)
|
RailClientContext* rail_get_client_interface(railPlugin* rail)
|
||||||
{
|
{
|
||||||
RailClientContext* pInterface;
|
RailClientContext* pInterface;
|
||||||
@ -45,7 +47,7 @@ RailClientContext* rail_get_client_interface(railPlugin* rail)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_send(railPlugin* rail, wStream* s)
|
static UINT rail_send(railPlugin* rail, wStream* s)
|
||||||
{
|
{
|
||||||
UINT status;
|
UINT status;
|
||||||
|
|
||||||
@ -56,14 +58,14 @@ UINT rail_send(railPlugin* rail, wStream* s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = rail->channelEntryPoints.pVirtualChannelWrite(rail->OpenHandle,
|
status = rail->channelEntryPoints.pVirtualChannelWrite(rail->OpenHandle,
|
||||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -77,15 +79,15 @@ UINT rail_send(railPlugin* rail, wStream* s)
|
|||||||
UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
|
UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
|
||||||
{
|
{
|
||||||
wStream* s = NULL;
|
wStream* s = NULL;
|
||||||
|
|
||||||
s = Stream_New(NULL, length);
|
s = Stream_New(NULL, length);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
Stream_Write(s, data, length);
|
|
||||||
|
|
||||||
|
Stream_Write(s, data, length);
|
||||||
return rail_send(rail, s);
|
return rail_send(rail, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,11 +100,11 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
|
static UINT rail_client_execute(RailClientContext* context,
|
||||||
|
RAIL_EXEC_ORDER* exec)
|
||||||
{
|
{
|
||||||
char* exeOrFile;
|
char* exeOrFile;
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
exeOrFile = exec->RemoteApplicationProgram;
|
exeOrFile = exec->RemoteApplicationProgram;
|
||||||
|
|
||||||
if (!exeOrFile)
|
if (!exeOrFile)
|
||||||
@ -114,10 +116,12 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
|
|||||||
exec->flags |= RAIL_EXEC_FLAG_FILE;
|
exec->flags |= RAIL_EXEC_FLAG_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rail_string_to_unicode_string(exec->RemoteApplicationProgram, &exec->exeOrFile); /* RemoteApplicationProgram */
|
rail_string_to_unicode_string(exec->RemoteApplicationProgram,
|
||||||
rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, &exec->workingDir); /* ShellWorkingDirectory */
|
&exec->exeOrFile); /* RemoteApplicationProgram */
|
||||||
rail_string_to_unicode_string(exec->RemoteApplicationArguments, &exec->arguments); /* RemoteApplicationCmdLine */
|
rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir,
|
||||||
|
&exec->workingDir); /* ShellWorkingDirectory */
|
||||||
|
rail_string_to_unicode_string(exec->RemoteApplicationArguments,
|
||||||
|
&exec->arguments); /* RemoteApplicationCmdLine */
|
||||||
return rail_send_client_exec_order(rail, exec);
|
return rail_send_client_exec_order(rail, exec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +130,10 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate)
|
static UINT rail_client_activate(RailClientContext* context,
|
||||||
|
RAIL_ACTIVATE_ORDER* activate)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_activate_order(rail, activate);
|
return rail_send_client_activate_order(rail, activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,13 +142,13 @@ UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activ
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
static UINT rail_send_client_sysparam(RailClientContext* context,
|
||||||
|
RAIL_SYSPARAM_ORDER* sysparam)
|
||||||
{
|
{
|
||||||
wStream* s;
|
wStream* s;
|
||||||
int length;
|
int length;
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
UINT error;
|
UINT error;
|
||||||
|
|
||||||
length = RAIL_SYSPARAM_ORDER_LENGTH;
|
length = RAIL_SYSPARAM_ORDER_LENGTH;
|
||||||
|
|
||||||
switch (sysparam->param)
|
switch (sysparam->param)
|
||||||
@ -168,6 +172,7 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER*
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||||
@ -195,13 +200,15 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER*
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
static UINT rail_client_system_param(RailClientContext* context,
|
||||||
|
RAIL_SYSPARAM_ORDER* sysparam)
|
||||||
{
|
{
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -212,6 +219,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_TASKBAR_POS;
|
sysparam->param = SPI_TASKBAR_POS;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -222,6 +230,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -232,6 +241,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -242,6 +252,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -252,6 +263,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -262,6 +274,7 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
||||||
{
|
{
|
||||||
sysparam->param = SPI_SET_WORK_AREA;
|
sysparam->param = SPI_SET_WORK_AREA;
|
||||||
|
|
||||||
if ((error = rail_send_client_sysparam(context, sysparam)))
|
if ((error = rail_send_client_sysparam(context, sysparam)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error);
|
||||||
@ -277,7 +290,8 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
static UINT rail_server_system_param(RailClientContext* context,
|
||||||
|
RAIL_SYSPARAM_ORDER* sysparam)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -287,10 +301,10 @@ UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand)
|
static UINT rail_client_system_command(RailClientContext* context,
|
||||||
|
RAIL_SYSCOMMAND_ORDER* syscommand)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_syscommand_order(rail, syscommand);
|
return rail_send_client_syscommand_order(rail, syscommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,10 +313,10 @@ UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
|
static UINT rail_client_handshake(RailClientContext* context,
|
||||||
|
RAIL_HANDSHAKE_ORDER* handshake)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_handshake_order(rail, handshake);
|
return rail_send_handshake_order(rail, handshake);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +325,8 @@ UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
|
static UINT rail_server_handshake(RailClientContext* context,
|
||||||
|
RAIL_HANDSHAKE_ORDER* handshake)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -321,10 +336,10 @@ UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
static UINT rail_client_handshake_ex(RailClientContext* context,
|
||||||
|
RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_handshake_ex_order(rail, handshakeEx);
|
return rail_send_handshake_ex_order(rail, handshakeEx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +348,8 @@ UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
static UINT rail_server_handshake_ex(RailClientContext* context,
|
||||||
|
RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -343,10 +359,10 @@ UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
|
static UINT rail_client_notify_event(RailClientContext* context,
|
||||||
|
RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_notify_event_order(rail, notifyEvent);
|
return rail_send_client_notify_event_order(rail, notifyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,10 +371,10 @@ UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove)
|
static UINT rail_client_window_move(RailClientContext* context,
|
||||||
|
RAIL_WINDOW_MOVE_ORDER* windowMove)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_window_move_order(rail, windowMove);
|
return rail_send_client_window_move_order(rail, windowMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +383,8 @@ UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER*
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
static UINT rail_server_local_move_size(RailClientContext* context,
|
||||||
|
RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -377,7 +394,8 @@ UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
static UINT rail_server_min_max_info(RailClientContext* context,
|
||||||
|
RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -387,10 +405,10 @@ UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER*
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus)
|
static UINT rail_client_information(RailClientContext* context,
|
||||||
|
RAIL_CLIENT_STATUS_ORDER* clientStatus)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_status_order(rail, clientStatus);
|
return rail_send_client_status_order(rail, clientStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,10 +417,10 @@ UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu)
|
static UINT rail_client_system_menu(RailClientContext* context,
|
||||||
|
RAIL_SYSMENU_ORDER* sysmenu)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_sysmenu_order(rail, sysmenu);
|
return rail_send_client_sysmenu_order(rail, sysmenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,10 +429,10 @@ UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sys
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
static UINT rail_client_language_bar_info(RailClientContext* context,
|
||||||
|
RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_langbar_info_order(rail, langBarInfo);
|
return rail_send_client_langbar_info_order(rail, langBarInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +441,8 @@ UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
static UINT rail_server_language_bar_info(RailClientContext* context,
|
||||||
|
RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -433,7 +452,8 @@ UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult)
|
static UINT rail_server_execute_result(RailClientContext* context,
|
||||||
|
RAIL_EXEC_RESULT_ORDER* execResult)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
@ -443,10 +463,10 @@ UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORD
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
|
static UINT rail_client_get_appid_request(RailClientContext* context,
|
||||||
|
RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
|
||||||
{
|
{
|
||||||
railPlugin* rail = (railPlugin*) context->handle;
|
railPlugin* rail = (railPlugin*) context->handle;
|
||||||
|
|
||||||
return rail_send_client_get_appid_req_order(rail, getAppIdReq);
|
return rail_send_client_get_appid_req_order(rail, getAppIdReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,111 +475,19 @@ UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_RE
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
static UINT rail_server_get_appid_response(RailClientContext* context,
|
||||||
|
RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
static wListDictionary* g_InitHandles = NULL;
|
|
||||||
static wListDictionary* g_OpenHandles = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT rail_add_init_handle_data(void* pInitHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
g_InitHandles = ListDictionary_New(TRUE);
|
|
||||||
}
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_Add failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* rail_get_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rail_remove_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
|
||||||
if (ListDictionary_Count(g_InitHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_InitHandles);
|
|
||||||
g_InitHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT rail_add_open_handle_data(DWORD openHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
g_OpenHandles = ListDictionary_New(TRUE);
|
|
||||||
}
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_Add failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* rail_get_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rail_remove_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
|
||||||
if (ListDictionary_Count(g_OpenHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_OpenHandles);
|
|
||||||
g_OpenHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
|
static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
|
||||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
wStream* data_in;
|
wStream* data_in;
|
||||||
|
|
||||||
@ -574,6 +502,7 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
|
|||||||
Stream_Free(rail->data_in, TRUE);
|
Stream_Free(rail->data_in, TRUE);
|
||||||
|
|
||||||
rail->data_in = Stream_New(NULL, totalLength);
|
rail->data_in = Stream_New(NULL, totalLength);
|
||||||
|
|
||||||
if (!rail->data_in)
|
if (!rail->data_in)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -582,11 +511,13 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data_in = rail->data_in;
|
data_in = rail->data_in;
|
||||||
|
|
||||||
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream_Write(data_in, pData, dataLength);
|
Stream_Write(data_in, pData, dataLength);
|
||||||
|
|
||||||
if (dataFlags & CHANNEL_FLAG_LAST)
|
if (dataFlags & CHANNEL_FLAG_LAST)
|
||||||
@ -607,18 +538,18 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
|
|||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT event,
|
static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle,
|
||||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
UINT event,
|
||||||
|
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
railPlugin* rail;
|
railPlugin* rail = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
rail = (railPlugin*) rail_get_open_handle_data(openHandle);
|
if (!rail || (rail->OpenHandle != openHandle))
|
||||||
|
|
||||||
if (!rail)
|
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match");
|
WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match");
|
||||||
return;
|
return;
|
||||||
@ -627,8 +558,11 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve
|
|||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||||
if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, totalLength, dataFlags)))
|
if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength,
|
||||||
WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!", error);
|
totalLength, dataFlags)))
|
||||||
|
WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!",
|
||||||
|
error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||||
@ -640,7 +574,8 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error && rail->rdpcontext)
|
if (error && rail->rdpcontext)
|
||||||
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_open_event reported an error");
|
setChannelError(rail->rdpcontext, error,
|
||||||
|
"rail_virtual_channel_open_event reported an error");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -667,12 +602,14 @@ static void* rail_virtual_channel_client_thread(void* arg)
|
|||||||
error = ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.id == WMQ_QUIT)
|
if (message.id == WMQ_QUIT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (message.id == 0)
|
if (message.id == 0)
|
||||||
{
|
{
|
||||||
data = (wStream*) message.wParam;
|
data = (wStream*) message.wParam;
|
||||||
|
|
||||||
if ((error = rail_order_recv(rail, data)))
|
if ((error = rail_order_recv(rail, data)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_order_recv failed with error %d!", error);
|
WLog_ERR(TAG, "rail_order_recv failed with error %d!", error);
|
||||||
@ -682,7 +619,8 @@ static void* rail_virtual_channel_client_thread(void* arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error && rail->rdpcontext)
|
if (error && rail->rdpcontext)
|
||||||
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_client_thread reported an error");
|
setChannelError(rail->rdpcontext, error,
|
||||||
|
"rail_virtual_channel_client_thread reported an error");
|
||||||
|
|
||||||
ExitThread((DWORD)error);
|
ExitThread((DWORD)error);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -693,27 +631,22 @@ static void* rail_virtual_channel_client_thread(void* arg)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, UINT32 dataLength)
|
static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
|
||||||
|
UINT32 dataLength)
|
||||||
{
|
{
|
||||||
UINT status;
|
UINT status;
|
||||||
|
|
||||||
status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle,
|
status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle,
|
||||||
&rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event);
|
&rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event);
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status = rail_add_open_handle_data(rail->OpenHandle, rail)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "rail_add_open_handle_data failed with error %lu!", status);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
rail->queue = MessageQueue_New(NULL);
|
rail->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
if (!rail->queue)
|
if (!rail->queue)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "MessageQueue_New failed!");
|
WLog_ERR(TAG, "MessageQueue_New failed!");
|
||||||
@ -721,13 +654,15 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(rail->thread = CreateThread(NULL, 0,
|
if (!(rail->thread = CreateThread(NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, NULL)))
|
(LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0,
|
||||||
|
NULL)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "CreateThread failed!");
|
WLog_ERR(TAG, "CreateThread failed!");
|
||||||
MessageQueue_Free(rail->queue);
|
MessageQueue_Free(rail->queue);
|
||||||
rail->queue = NULL;
|
rail->queue = NULL;
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,51 +674,52 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
|
|||||||
static UINT rail_virtual_channel_event_disconnected(railPlugin* rail)
|
static UINT rail_virtual_channel_event_disconnected(railPlugin* rail)
|
||||||
{
|
{
|
||||||
UINT rc;
|
UINT rc;
|
||||||
if (MessageQueue_PostQuit(rail->queue, 0) && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED))
|
|
||||||
{
|
if (MessageQueue_PostQuit(rail->queue, 0)
|
||||||
rc = GetLastError();
|
&& (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED))
|
||||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
|
{
|
||||||
return rc;
|
rc = GetLastError();
|
||||||
}
|
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
MessageQueue_Free(rail->queue);
|
MessageQueue_Free(rail->queue);
|
||||||
CloseHandle(rail->thread);
|
CloseHandle(rail->thread);
|
||||||
|
|
||||||
rail->queue = NULL;
|
rail->queue = NULL;
|
||||||
rail->thread = NULL;
|
rail->thread = NULL;
|
||||||
|
|
||||||
rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle);
|
rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle);
|
||||||
|
|
||||||
if (CHANNEL_RC_OK != rc)
|
if (CHANNEL_RC_OK != rc)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
|
||||||
WTSErrorToString(rc), rc);
|
WTSErrorToString(rc), rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rail->OpenHandle = 0;
|
||||||
|
|
||||||
if (rail->data_in)
|
if (rail->data_in)
|
||||||
{
|
{
|
||||||
Stream_Free(rail->data_in, TRUE);
|
Stream_Free(rail->data_in, TRUE);
|
||||||
rail->data_in = NULL;
|
rail->data_in = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rail_remove_open_handle_data(rail->OpenHandle);
|
return CHANNEL_RC_OK;
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rail_virtual_channel_event_terminated(railPlugin* rail)
|
static void rail_virtual_channel_event_terminated(railPlugin* rail)
|
||||||
{
|
{
|
||||||
rail_remove_init_handle_data(rail->InitHandle);
|
rail->InitHandle = 0;
|
||||||
free(rail);
|
free(rail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
|
static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle,
|
||||||
|
UINT event, LPVOID pData, UINT dataLength)
|
||||||
{
|
{
|
||||||
railPlugin* rail;
|
railPlugin* rail = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
rail = (railPlugin*) rail_get_init_handle_data(pInitHandle);
|
if (!rail || (rail->InitHandle != pInitHandle))
|
||||||
|
|
||||||
if (!rail)
|
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match");
|
WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match");
|
||||||
return;
|
return;
|
||||||
@ -793,12 +729,16 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e
|
|||||||
{
|
{
|
||||||
case CHANNEL_EVENT_CONNECTED:
|
case CHANNEL_EVENT_CONNECTED:
|
||||||
if ((error = rail_virtual_channel_event_connected(rail, pData, dataLength)))
|
if ((error = rail_virtual_channel_event_connected(rail, pData, dataLength)))
|
||||||
WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!",
|
||||||
|
error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_DISCONNECTED:
|
case CHANNEL_EVENT_DISCONNECTED:
|
||||||
if ((error = rail_virtual_channel_event_disconnected(rail)))
|
if ((error = rail_virtual_channel_event_disconnected(rail)))
|
||||||
WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!", error);
|
WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!",
|
||||||
|
error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_TERMINATED:
|
case CHANNEL_EVENT_TERMINATED:
|
||||||
@ -806,8 +746,9 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error && rail->rdpcontext)
|
if (error && rail->rdpcontext)
|
||||||
setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event reported an error");
|
setChannelError(rail->rdpcontext, error,
|
||||||
|
"rail_virtual_channel_init_event reported an error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rail is always built-in */
|
/* rail is always built-in */
|
||||||
@ -820,9 +761,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
RailClientContext* context;
|
RailClientContext* context;
|
||||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||||
BOOL isFreerdp = FALSE;
|
BOOL isFreerdp = FALSE;
|
||||||
UINT error;
|
|
||||||
|
|
||||||
rail = (railPlugin*) calloc(1, sizeof(railPlugin));
|
rail = (railPlugin*) calloc(1, sizeof(railPlugin));
|
||||||
|
|
||||||
if (!rail)
|
if (!rail)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -830,19 +770,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rail->channelDef.options =
|
rail->channelDef.options =
|
||||||
CHANNEL_OPTION_INITIALIZED |
|
CHANNEL_OPTION_INITIALIZED |
|
||||||
CHANNEL_OPTION_ENCRYPT_RDP |
|
CHANNEL_OPTION_ENCRYPT_RDP |
|
||||||
CHANNEL_OPTION_COMPRESS_RDP |
|
CHANNEL_OPTION_COMPRESS_RDP |
|
||||||
CHANNEL_OPTION_SHOW_PROTOCOL;
|
CHANNEL_OPTION_SHOW_PROTOCOL;
|
||||||
|
|
||||||
strcpy(rail->channelDef.name, "rail");
|
strcpy(rail->channelDef.name, "rail");
|
||||||
|
|
||||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
||||||
|
|
||||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
||||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||||
{
|
{
|
||||||
context = (RailClientContext*) calloc(1, sizeof(RailClientContext));
|
context = (RailClientContext*) calloc(1, sizeof(RailClientContext));
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -852,7 +791,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
|
|
||||||
context->handle = (void*) rail;
|
context->handle = (void*) rail;
|
||||||
context->custom = NULL;
|
context->custom = NULL;
|
||||||
|
|
||||||
context->ClientExecute = rail_client_execute;
|
context->ClientExecute = rail_client_execute;
|
||||||
context->ClientActivate = rail_client_activate;
|
context->ClientActivate = rail_client_activate;
|
||||||
context->ClientSystemParam = rail_client_system_param;
|
context->ClientSystemParam = rail_client_system_param;
|
||||||
@ -874,7 +812,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
context->ClientGetAppIdRequest = rail_client_get_appid_request;
|
context->ClientGetAppIdRequest = rail_client_get_appid_request;
|
||||||
context->ServerGetAppIdResponse = rail_server_get_appid_response;
|
context->ServerGetAppIdResponse = rail_server_get_appid_response;
|
||||||
rail->rdpcontext = pEntryPointsEx->context;
|
rail->rdpcontext = pEntryPointsEx->context;
|
||||||
|
|
||||||
*(pEntryPointsEx->ppInterface) = (void*) context;
|
*(pEntryPointsEx->ppInterface) = (void*) context;
|
||||||
rail->context = context;
|
rail->context = context;
|
||||||
isFreerdp = TRUE;
|
isFreerdp = TRUE;
|
||||||
@ -882,34 +819,29 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
|
|
||||||
WLog_Init();
|
WLog_Init();
|
||||||
rail->log = WLog_Get("com.freerdp.channels.rail.client");
|
rail->log = WLog_Get("com.freerdp.channels.rail.client");
|
||||||
|
|
||||||
WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry");
|
WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry");
|
||||||
|
CopyMemory(&(rail->channelEntryPoints), pEntryPoints,
|
||||||
CopyMemory(&(rail->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||||
|
|
||||||
rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle,
|
rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle,
|
||||||
&rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rail_virtual_channel_init_event);
|
&rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
|
||||||
|
rail_virtual_channel_init_event);
|
||||||
|
|
||||||
if (CHANNEL_RC_OK != rc)
|
if (CHANNEL_RC_OK != rc)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
||||||
WTSErrorToString(rc), rc);
|
WTSErrorToString(rc), rc);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface);
|
rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface);
|
||||||
rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface);
|
rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface);
|
||||||
|
s_TLSPluginContext = rail;
|
||||||
if ((error = rail_add_init_handle_data(rail->InitHandle, (void*) rail)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "rail_add_init_handle_data failed with error %lu!", error);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error_out:
|
error_out:
|
||||||
|
|
||||||
if (isFreerdp)
|
if (isFreerdp)
|
||||||
free(rail->context);
|
free(rail->context);
|
||||||
|
|
||||||
free(rail);
|
free(rail);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,8 @@ struct _DEVICE_DRIVE_EXT
|
|||||||
char* path;
|
char* path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static WINPR_TLS rdpdrPlugin* s_TLSPluginContext = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@ -842,7 +844,7 @@ cleanup:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void first_hotplug(rdpdrPlugin* rdpdr)
|
static void first_hotplug(rdpdrPlugin* rdpdr)
|
||||||
{
|
{
|
||||||
UINT error;
|
UINT error;
|
||||||
|
|
||||||
@ -1411,107 +1413,6 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
static wListDictionary* g_InitHandles = NULL;
|
|
||||||
static wListDictionary* g_OpenHandles = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT rdpdr_add_init_handle_data(void* pInitHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
g_InitHandles = ListDictionary_New(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_Add failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* rdpdr_get_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rdpdr_remove_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
|
||||||
|
|
||||||
if (ListDictionary_Count(g_InitHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_InitHandles);
|
|
||||||
g_InitHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT rdpdr_add_open_handle_data(DWORD openHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
g_OpenHandles = ListDictionary_New(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_Add failed!");
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* rdpdr_get_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rdpdr_remove_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*)(size_t) openHandle;
|
|
||||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
|
||||||
|
|
||||||
if (ListDictionary_Count(g_OpenHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_OpenHandles);
|
|
||||||
g_OpenHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@ -1614,11 +1515,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle,
|
|||||||
UINT event,
|
UINT event,
|
||||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
rdpdrPlugin* rdpdr;
|
rdpdrPlugin* rdpdr = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle);
|
|
||||||
|
|
||||||
if (!rdpdr || !pData)
|
if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match");
|
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match");
|
||||||
return;
|
return;
|
||||||
@ -1716,7 +1616,6 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr,
|
|||||||
LPVOID pData, UINT32 dataLength)
|
LPVOID pData, UINT32 dataLength)
|
||||||
{
|
{
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
UINT error;
|
|
||||||
status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle,
|
status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle,
|
||||||
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event);
|
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event);
|
||||||
|
|
||||||
@ -1727,12 +1626,6 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "rdpdr_add_open_handle_data failed with error %lu!", error);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdpdr->queue = MessageQueue_New(NULL);
|
rdpdr->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
if (!rdpdr->queue)
|
if (!rdpdr->queue)
|
||||||
@ -1788,6 +1681,8 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
|||||||
WTSErrorToString(error), error);
|
WTSErrorToString(error), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdpdr->OpenHandle = 0;
|
||||||
|
|
||||||
if (rdpdr->data_in)
|
if (rdpdr->data_in)
|
||||||
{
|
{
|
||||||
Stream_Free(rdpdr->data_in, TRUE);
|
Stream_Free(rdpdr->data_in, TRUE);
|
||||||
@ -1800,13 +1695,11 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
|||||||
rdpdr->devman = NULL;
|
rdpdr->devman = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpdr_remove_open_handle_data(rdpdr->OpenHandle);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
||||||
{
|
{
|
||||||
rdpdr_remove_init_handle_data(rdpdr->InitHandle);
|
|
||||||
free(rdpdr);
|
free(rdpdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1814,11 +1707,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle,
|
|||||||
UINT event,
|
UINT event,
|
||||||
LPVOID pData, UINT dataLength)
|
LPVOID pData, UINT dataLength)
|
||||||
{
|
{
|
||||||
rdpdrPlugin* rdpdr;
|
rdpdrPlugin* rdpdr = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
rdpdr = (rdpdrPlugin*) rdpdr_get_init_handle_data(pInitHandle);
|
|
||||||
|
|
||||||
if (!rdpdr)
|
if (!rdpdr || (rdpdr->InitHandle != pInitHandle))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "error no match");
|
WLog_ERR(TAG, "error no match");
|
||||||
return;
|
return;
|
||||||
@ -1902,12 +1794,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = rdpdr_add_init_handle_data(rdpdr->InitHandle, (void*) rdpdr)))
|
s_TLSPluginContext = rdpdr;
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "rdpdr_add_init_handle_data failed with error %lu!", rc);
|
|
||||||
free(rdpdr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,10 @@
|
|||||||
|
|
||||||
#include "remdesk_main.h"
|
#include "remdesk_main.h"
|
||||||
|
|
||||||
RemdeskClientContext* remdesk_get_client_interface(remdeskPlugin* remdesk)
|
static WINPR_TLS remdeskPlugin* s_TLSPluginContext = NULL;
|
||||||
|
|
||||||
|
static RemdeskClientContext* remdesk_get_client_interface(
|
||||||
|
remdeskPlugin* remdesk)
|
||||||
{
|
{
|
||||||
RemdeskClientContext* pInterface;
|
RemdeskClientContext* pInterface;
|
||||||
pInterface = (RemdeskClientContext*) remdesk->channelEntryPoints.pInterface;
|
pInterface = (RemdeskClientContext*) remdesk->channelEntryPoints.pInterface;
|
||||||
@ -56,11 +59,11 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle,
|
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle,
|
||||||
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
|
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -70,7 +73,7 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
|
static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
|
||||||
{
|
{
|
||||||
char* name;
|
char* name;
|
||||||
char* pass;
|
char* pass;
|
||||||
@ -97,7 +100,7 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
|
|||||||
name = "Expert";
|
name = "Expert";
|
||||||
|
|
||||||
remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password,
|
remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password,
|
||||||
settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize));
|
settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize));
|
||||||
|
|
||||||
if (!remdesk->EncryptedPassStub)
|
if (!remdesk->EncryptedPassStub)
|
||||||
{
|
{
|
||||||
@ -105,7 +108,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
|
|||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, remdesk->EncryptedPassStubSize);
|
pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub,
|
||||||
|
remdesk->EncryptedPassStubSize);
|
||||||
|
|
||||||
if (!pass)
|
if (!pass)
|
||||||
{
|
{
|
||||||
@ -129,7 +133,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
|
static UINT remdesk_read_channel_header(wStream* s,
|
||||||
|
REMDESK_CHANNEL_HEADER* header)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
UINT32 ChannelNameLen;
|
UINT32 ChannelNameLen;
|
||||||
@ -163,11 +168,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
|
|||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
|
ZeroMemory(header->ChannelName, sizeof(header->ChannelName));
|
||||||
|
|
||||||
pChannelName = (char*) header->ChannelName;
|
pChannelName = (char*) header->ChannelName;
|
||||||
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
|
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
|
||||||
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
|
ChannelNameLen / 2, &pChannelName, 32, NULL, NULL);
|
||||||
|
|
||||||
Stream_Seek(s, ChannelNameLen);
|
Stream_Seek(s, ChannelNameLen);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
@ -184,12 +187,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
|
static UINT remdesk_write_channel_header(wStream* s,
|
||||||
|
REMDESK_CHANNEL_HEADER* header)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
UINT32 ChannelNameLen;
|
UINT32 ChannelNameLen;
|
||||||
WCHAR ChannelNameW[32];
|
WCHAR ChannelNameW[32];
|
||||||
|
|
||||||
ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
|
ZeroMemory(ChannelNameW, sizeof(ChannelNameW));
|
||||||
|
|
||||||
for (index = 0; index < 32; index++)
|
for (index = 0; index < 32; index++)
|
||||||
@ -198,12 +201,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
|
ChannelNameLen = (strlen(header->ChannelName) + 1) * 2;
|
||||||
|
|
||||||
Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
|
Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
|
||||||
Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
|
Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
|
||||||
|
|
||||||
Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
|
Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize)
|
static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader,
|
||||||
|
UINT32 msgType, UINT32 msgSize)
|
||||||
{
|
{
|
||||||
ctlHeader->msgType = msgType;
|
ctlHeader->msgType = msgType;
|
||||||
strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
|
strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME);
|
||||||
@ -237,7 +238,8 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
|
static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk,
|
||||||
|
wStream* s, REMDESK_CHANNEL_HEADER* header)
|
||||||
{
|
{
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
@ -247,7 +249,8 @@ static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
|
static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk,
|
||||||
|
wStream* s, REMDESK_CHANNEL_HEADER* header)
|
||||||
{
|
{
|
||||||
UINT32 versionMajor;
|
UINT32 versionMajor;
|
||||||
UINT32 versionMinor;
|
UINT32 versionMinor;
|
||||||
@ -260,9 +263,7 @@ static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s
|
|||||||
|
|
||||||
Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
|
Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */
|
||||||
Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
|
Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */
|
||||||
|
|
||||||
remdesk->Version = versionMajor;
|
remdesk->Version = versionMajor;
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,13 +277,11 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
|
|||||||
wStream* s;
|
wStream* s;
|
||||||
REMDESK_CTL_VERSION_INFO_PDU pdu;
|
REMDESK_CTL_VERSION_INFO_PDU pdu;
|
||||||
UINT error;
|
UINT error;
|
||||||
|
|
||||||
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8);
|
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8);
|
||||||
|
|
||||||
pdu.versionMajor = 1;
|
pdu.versionMajor = 1;
|
||||||
pdu.versionMinor = 2;
|
pdu.versionMinor = 2;
|
||||||
|
|
||||||
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -290,10 +289,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
||||||
|
|
||||||
Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
|
Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */
|
||||||
Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
|
Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */
|
||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
||||||
@ -301,6 +298,7 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +307,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
|
static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s,
|
||||||
|
REMDESK_CHANNEL_HEADER* header, UINT32* pResult)
|
||||||
{
|
{
|
||||||
UINT32 result;
|
UINT32 result;
|
||||||
|
|
||||||
@ -320,7 +319,6 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMD
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stream_Read_UINT32(s, result); /* result (4 bytes) */
|
Stream_Read_UINT32(s, result); /* result (4 bytes) */
|
||||||
|
|
||||||
*pResult = result;
|
*pResult = result;
|
||||||
//WLog_DBG(TAG, "RemdeskRecvResult: 0x%04X", result);
|
//WLog_DBG(TAG, "RemdeskRecvResult: 0x%04X", result);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
@ -350,8 +348,8 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
pdu.expertBlob = remdesk->ExpertBlob;
|
pdu.expertBlob = remdesk->ExpertBlob;
|
||||||
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
|
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
|
||||||
|
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1,
|
||||||
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0);
|
&raConnectionStringW, 0);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
@ -360,7 +358,6 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cbRaConnectionStringW = status * 2;
|
cbRaConnectionStringW = status * 2;
|
||||||
|
|
||||||
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
|
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
@ -371,11 +368,10 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cbExpertBlobW = status * 2;
|
cbExpertBlobW = status * 2;
|
||||||
|
|
||||||
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE,
|
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE,
|
||||||
cbRaConnectionStringW + cbExpertBlobW);
|
cbRaConnectionStringW + cbExpertBlobW);
|
||||||
|
|
||||||
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -384,10 +380,8 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
||||||
|
|
||||||
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
|
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
|
||||||
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
|
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
|
||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
||||||
@ -396,6 +390,7 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
|
|||||||
out:
|
out:
|
||||||
free(raConnectionStringW);
|
free(raConnectionStringW);
|
||||||
free(expertBlobW);
|
free(expertBlobW);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
@ -415,10 +410,9 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
|
|||||||
int cbRaConnectionStringW = 0;
|
int cbRaConnectionStringW = 0;
|
||||||
WCHAR* raConnectionStringW = NULL;
|
WCHAR* raConnectionStringW = NULL;
|
||||||
REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
|
REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu;
|
||||||
|
|
||||||
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
|
pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket;
|
||||||
|
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1,
|
||||||
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0);
|
&raConnectionStringW, 0);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
@ -427,10 +421,10 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cbRaConnectionStringW = status * 2;
|
cbRaConnectionStringW = status * 2;
|
||||||
|
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP,
|
||||||
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, cbRaConnectionStringW);
|
cbRaConnectionStringW);
|
||||||
|
|
||||||
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -439,9 +433,7 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
||||||
|
|
||||||
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
|
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
|
||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
||||||
@ -449,6 +441,7 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
free(raConnectionStringW);
|
free(raConnectionStringW);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
@ -476,7 +469,6 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pdu.expertBlob = remdesk->ExpertBlob;
|
pdu.expertBlob = remdesk->ExpertBlob;
|
||||||
|
|
||||||
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
|
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
@ -486,10 +478,10 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cbExpertBlobW = status * 2;
|
cbExpertBlobW = status * 2;
|
||||||
|
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD,
|
||||||
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, cbExpertBlobW);
|
cbExpertBlobW);
|
||||||
|
|
||||||
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -498,9 +490,7 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
||||||
|
|
||||||
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
|
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
|
||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
if ((error = remdesk_virtual_channel_write(remdesk, s)))
|
||||||
@ -508,6 +498,7 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
free(expertBlobW);
|
free(expertBlobW);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
@ -533,11 +524,10 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
pdu.EncryptedPasswordLength = remdesk->EncryptedPassStubSize;
|
pdu.EncryptedPasswordLength = remdesk->EncryptedPassStubSize;
|
||||||
pdu.EncryptedPassword = remdesk->EncryptedPassStub;
|
pdu.EncryptedPassword = remdesk->EncryptedPassStub;
|
||||||
|
|
||||||
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA,
|
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA,
|
||||||
pdu.EncryptedPasswordLength);
|
pdu.EncryptedPasswordLength);
|
||||||
|
|
||||||
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -545,11 +535,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
|
||||||
|
|
||||||
Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength);
|
Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength);
|
||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
return remdesk_virtual_channel_write(remdesk, s);
|
return remdesk_virtual_channel_write(remdesk, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +545,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
|
static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s,
|
||||||
|
REMDESK_CHANNEL_HEADER* header)
|
||||||
{
|
{
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
UINT32 msgType = 0;
|
UINT32 msgType = 0;
|
||||||
@ -582,6 +570,7 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
|
|||||||
case REMDESK_CTL_RESULT:
|
case REMDESK_CTL_RESULT:
|
||||||
if ((error = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result)))
|
if ((error = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result)))
|
||||||
WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %lu", error);
|
WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %lu", error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMDESK_CTL_AUTHENTICATE:
|
case REMDESK_CTL_AUTHENTICATE:
|
||||||
@ -589,7 +578,9 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
|
|||||||
|
|
||||||
case REMDESK_CTL_SERVER_ANNOUNCE:
|
case REMDESK_CTL_SERVER_ANNOUNCE:
|
||||||
if ((error = remdesk_recv_ctl_server_announce_pdu(remdesk, s, header)))
|
if ((error = remdesk_recv_ctl_server_announce_pdu(remdesk, s, header)))
|
||||||
WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu", error);
|
WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu",
|
||||||
|
error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMDESK_CTL_DISCONNECT:
|
case REMDESK_CTL_DISCONNECT:
|
||||||
@ -618,7 +609,8 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
|
|||||||
|
|
||||||
if ((error = remdesk_send_ctl_remote_control_desktop_pdu(remdesk)))
|
if ((error = remdesk_send_ctl_remote_control_desktop_pdu(remdesk)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error);
|
WLog_ERR(TAG,
|
||||||
|
"remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,13 +618,15 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA
|
|||||||
{
|
{
|
||||||
if ((error = remdesk_send_ctl_expert_on_vista_pdu(remdesk)))
|
if ((error = remdesk_send_ctl_expert_on_vista_pdu(remdesk)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu", error);
|
WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu",
|
||||||
|
error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = remdesk_send_ctl_verify_password_pdu(remdesk)))
|
if ((error = remdesk_send_ctl_verify_password_pdu(remdesk)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu", error);
|
WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu",
|
||||||
|
error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +669,6 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
|
|||||||
{
|
{
|
||||||
UINT status;
|
UINT status;
|
||||||
REMDESK_CHANNEL_HEADER header;
|
REMDESK_CHANNEL_HEADER header;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
WLog_DBG(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s));
|
WLog_DBG(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s));
|
||||||
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
|
winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s));
|
||||||
@ -693,27 +686,21 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s)
|
|||||||
}
|
}
|
||||||
else if (strcmp(header.ChannelName, "70") == 0)
|
else if (strcmp(header.ChannelName, "70") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(header.ChannelName, "71") == 0)
|
else if (strcmp(header.ChannelName, "71") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(header.ChannelName, ".") == 0)
|
else if (strcmp(header.ChannelName, ".") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(header.ChannelName, "1000.") == 0)
|
else if (strcmp(header.ChannelName, "1000.") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(header.ChannelName, "RA_FX") == 0)
|
else if (strcmp(header.ChannelName, "RA_FX") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -724,89 +711,12 @@ static void remdesk_process_connect(remdeskPlugin* remdesk)
|
|||||||
remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData;
|
remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
static wListDictionary* g_InitHandles = NULL;
|
|
||||||
static wListDictionary* g_OpenHandles = NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT remdesk_add_init_handle_data(void* pInitHandle, void* pUserData)
|
static UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
|
||||||
{
|
|
||||||
if (!g_InitHandles)
|
|
||||||
{
|
|
||||||
g_InitHandles = ListDictionary_New(TRUE);
|
|
||||||
if (!g_InitHandles)
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* remdesk_get_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remdesk_remove_init_handle_data(void* pInitHandle)
|
|
||||||
{
|
|
||||||
ListDictionary_Remove(g_InitHandles, pInitHandle);
|
|
||||||
if (ListDictionary_Count(g_InitHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_InitHandles);
|
|
||||||
g_InitHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT remdesk_add_open_handle_data(DWORD openHandle, void* pUserData)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
{
|
|
||||||
g_OpenHandles = ListDictionary_New(TRUE);
|
|
||||||
if (!g_OpenHandles)
|
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* remdesk_get_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pUserData = NULL;
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
|
|
||||||
return pUserData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remdesk_remove_open_handle_data(DWORD openHandle)
|
|
||||||
{
|
|
||||||
void* pOpenHandle = (void*) (size_t) openHandle;
|
|
||||||
ListDictionary_Remove(g_OpenHandles, pOpenHandle);
|
|
||||||
if (ListDictionary_Count(g_OpenHandles) < 1)
|
|
||||||
{
|
|
||||||
ListDictionary_Free(g_OpenHandles);
|
|
||||||
g_OpenHandles = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
|
|
||||||
{
|
{
|
||||||
UINT status = 0;
|
UINT status = 0;
|
||||||
remdeskPlugin* plugin = (remdeskPlugin*) remdesk;
|
remdeskPlugin* plugin = (remdeskPlugin*) remdesk;
|
||||||
@ -818,14 +728,14 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
|
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
|
||||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -837,7 +747,7 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s)
|
|||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
|
static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
|
||||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
wStream* data_in;
|
wStream* data_in;
|
||||||
|
|
||||||
@ -852,6 +762,7 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
|
|||||||
Stream_Free(remdesk->data_in, TRUE);
|
Stream_Free(remdesk->data_in, TRUE);
|
||||||
|
|
||||||
remdesk->data_in = Stream_New(NULL, totalLength);
|
remdesk->data_in = Stream_New(NULL, totalLength);
|
||||||
|
|
||||||
if (!remdesk->data_in)
|
if (!remdesk->data_in)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
@ -860,11 +771,13 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data_in = remdesk->data_in;
|
data_in = remdesk->data_in;
|
||||||
|
|
||||||
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream_Write(data_in, pData, dataLength);
|
Stream_Write(data_in, pData, dataLength);
|
||||||
|
|
||||||
if (dataFlags & CHANNEL_FLAG_LAST)
|
if (dataFlags & CHANNEL_FLAG_LAST)
|
||||||
@ -885,18 +798,18 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
|
|||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT event,
|
static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle,
|
||||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
UINT event,
|
||||||
|
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||||
{
|
{
|
||||||
remdeskPlugin* remdesk;
|
remdeskPlugin* remdesk = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
remdesk = (remdeskPlugin*) remdesk_get_open_handle_data(openHandle);
|
if (!remdesk || (remdesk->OpenHandle != openHandle))
|
||||||
|
|
||||||
if (!remdesk)
|
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "error no match");
|
WLog_ERR(TAG, "error no match");
|
||||||
return;
|
return;
|
||||||
@ -905,8 +818,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT
|
|||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||||
if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, dataLength, totalLength, dataFlags)))
|
if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData,
|
||||||
WLog_ERR(TAG, "remdesk_virtual_channel_event_data_received failed with error %lu!", error);
|
dataLength, totalLength, dataFlags)))
|
||||||
|
WLog_ERR(TAG,
|
||||||
|
"remdesk_virtual_channel_event_data_received failed with error %lu!", error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||||
@ -919,11 +835,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT
|
|||||||
default:
|
default:
|
||||||
WLog_ERR(TAG, "unhandled event %lu!", event);
|
WLog_ERR(TAG, "unhandled event %lu!", event);
|
||||||
error = ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (error && remdesk->rdpcontext)
|
|
||||||
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_open_event reported an error");
|
|
||||||
|
|
||||||
|
if (error && remdesk->rdpcontext)
|
||||||
|
setChannelError(remdesk->rdpcontext, error,
|
||||||
|
"remdesk_virtual_channel_open_event reported an error");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* remdesk_virtual_channel_client_thread(void* arg)
|
static void* remdesk_virtual_channel_client_thread(void* arg)
|
||||||
@ -932,7 +848,6 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
|
|||||||
wMessage message;
|
wMessage message;
|
||||||
remdeskPlugin* remdesk = (remdeskPlugin*) arg;
|
remdeskPlugin* remdesk = (remdeskPlugin*) arg;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
remdesk_process_connect(remdesk);
|
remdesk_process_connect(remdesk);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -944,17 +859,20 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) {
|
if (!MessageQueue_Peek(remdesk->queue, &message, TRUE))
|
||||||
|
{
|
||||||
WLog_ERR(TAG, "MessageQueue_Peek failed!");
|
WLog_ERR(TAG, "MessageQueue_Peek failed!");
|
||||||
error = ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.id == WMQ_QUIT)
|
if (message.id == WMQ_QUIT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (message.id == 0)
|
if (message.id == 0)
|
||||||
{
|
{
|
||||||
data = (wStream*) message.wParam;
|
data = (wStream*) message.wParam;
|
||||||
|
|
||||||
if ((error = remdesk_process_receive(remdesk, data)))
|
if ((error = remdesk_process_receive(remdesk, data)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error);
|
WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error);
|
||||||
@ -964,7 +882,8 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error && remdesk->rdpcontext)
|
if (error && remdesk->rdpcontext)
|
||||||
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_client_thread reported an error");
|
setChannelError(remdesk->rdpcontext, error,
|
||||||
|
"remdesk_virtual_channel_client_thread reported an error");
|
||||||
|
|
||||||
ExitThread((DWORD)error);
|
ExitThread((DWORD)error);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -975,28 +894,24 @@ static void* remdesk_virtual_channel_client_thread(void* arg)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVOID pData, UINT32 dataLength)
|
static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk,
|
||||||
|
LPVOID pData, UINT32 dataLength)
|
||||||
{
|
{
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
UINT error;
|
UINT error;
|
||||||
|
|
||||||
status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle,
|
status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle,
|
||||||
&remdesk->OpenHandle, remdesk->channelDef.name, remdesk_virtual_channel_open_event);
|
&remdesk->OpenHandle, remdesk->channelDef.name,
|
||||||
|
remdesk_virtual_channel_open_event);
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||||
WTSErrorToString(status), status);
|
WTSErrorToString(status), status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = remdesk_add_open_handle_data(remdesk->OpenHandle, remdesk)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "remdesk_add_open_handle_data failed with error %lu", error);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
remdesk->queue = MessageQueue_New(NULL);
|
remdesk->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
if (!remdesk->queue)
|
if (!remdesk->queue)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "MessageQueue_New failed!");
|
WLog_ERR(TAG, "MessageQueue_New failed!");
|
||||||
@ -1005,16 +920,18 @@ static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVO
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk->thread = CreateThread(NULL, 0,
|
remdesk->thread = CreateThread(NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, 0, NULL);
|
(LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
if (!remdesk->thread)
|
if (!remdesk->thread)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "CreateThread failed");
|
WLog_ERR(TAG, "CreateThread failed");
|
||||||
error = ERROR_INTERNAL_ERROR;
|
error = ERROR_INTERNAL_ERROR;
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
error_out:
|
error_out:
|
||||||
remdesk_remove_open_handle_data(remdesk->OpenHandle);
|
|
||||||
MessageQueue_Free(remdesk->queue);
|
MessageQueue_Free(remdesk->queue);
|
||||||
remdesk->queue = NULL;
|
remdesk->queue = NULL;
|
||||||
return error;
|
return error;
|
||||||
@ -1029,7 +946,8 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk)
|
|||||||
{
|
{
|
||||||
UINT rc;
|
UINT rc;
|
||||||
|
|
||||||
if (MessageQueue_PostQuit(remdesk->queue, 0) && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED))
|
if (MessageQueue_PostQuit(remdesk->queue, 0)
|
||||||
|
&& (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED))
|
||||||
{
|
{
|
||||||
rc = GetLastError();
|
rc = GetLastError();
|
||||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
|
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc);
|
||||||
@ -1038,44 +956,41 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk)
|
|||||||
|
|
||||||
MessageQueue_Free(remdesk->queue);
|
MessageQueue_Free(remdesk->queue);
|
||||||
CloseHandle(remdesk->thread);
|
CloseHandle(remdesk->thread);
|
||||||
|
|
||||||
remdesk->queue = NULL;
|
remdesk->queue = NULL;
|
||||||
remdesk->thread = NULL;
|
remdesk->thread = NULL;
|
||||||
|
|
||||||
rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle);
|
rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle);
|
||||||
|
|
||||||
if (CHANNEL_RC_OK != rc)
|
if (CHANNEL_RC_OK != rc)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
|
||||||
WTSErrorToString(rc), rc);
|
WTSErrorToString(rc), rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remdesk->OpenHandle = 0;
|
||||||
|
|
||||||
if (remdesk->data_in)
|
if (remdesk->data_in)
|
||||||
{
|
{
|
||||||
Stream_Free(remdesk->data_in, TRUE);
|
Stream_Free(remdesk->data_in, TRUE);
|
||||||
remdesk->data_in = NULL;
|
remdesk->data_in = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
remdesk_remove_open_handle_data(remdesk->OpenHandle);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk)
|
static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk)
|
||||||
{
|
{
|
||||||
remdesk_remove_init_handle_data(remdesk->InitHandle);
|
remdesk->InitHandle = 0;
|
||||||
|
|
||||||
free(remdesk);
|
free(remdesk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
|
static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
|
||||||
UINT event, LPVOID pData,
|
UINT event, LPVOID pData,
|
||||||
UINT dataLength)
|
UINT dataLength)
|
||||||
{
|
{
|
||||||
remdeskPlugin* remdesk;
|
remdeskPlugin* remdesk = s_TLSPluginContext;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
remdesk = (remdeskPlugin*) remdesk_get_init_handle_data(pInitHandle);
|
if (!remdesk || (remdesk->InitHandle != pInitHandle))
|
||||||
|
|
||||||
if (!remdesk)
|
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "error no match");
|
WLog_ERR(TAG, "error no match");
|
||||||
return;
|
return;
|
||||||
@ -1084,21 +999,28 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
|
|||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case CHANNEL_EVENT_CONNECTED:
|
case CHANNEL_EVENT_CONNECTED:
|
||||||
if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, dataLength)))
|
if ((error = remdesk_virtual_channel_event_connected(remdesk, pData,
|
||||||
WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu", error);
|
dataLength)))
|
||||||
|
WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu",
|
||||||
|
error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_DISCONNECTED:
|
case CHANNEL_EVENT_DISCONNECTED:
|
||||||
if ((error = remdesk_virtual_channel_event_disconnected(remdesk)))
|
if ((error = remdesk_virtual_channel_event_disconnected(remdesk)))
|
||||||
WLog_ERR(TAG, "remdesk_virtual_channel_event_disconnected failed with error %lu", error);
|
WLog_ERR(TAG,
|
||||||
|
"remdesk_virtual_channel_event_disconnected failed with error %lu", error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANNEL_EVENT_TERMINATED:
|
case CHANNEL_EVENT_TERMINATED:
|
||||||
remdesk_virtual_channel_event_terminated(remdesk);
|
remdesk_virtual_channel_event_terminated(remdesk);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error && remdesk->rdpcontext)
|
if (error && remdesk->rdpcontext)
|
||||||
setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_init_event reported an error");
|
setChannelError(remdesk->rdpcontext, error,
|
||||||
|
"remdesk_virtual_channel_init_event reported an error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remdesk is always built-in */
|
/* remdesk is always built-in */
|
||||||
@ -1107,12 +1029,9 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle,
|
|||||||
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||||
{
|
{
|
||||||
UINT rc;
|
UINT rc;
|
||||||
UINT error;
|
|
||||||
|
|
||||||
remdeskPlugin* remdesk;
|
remdeskPlugin* remdesk;
|
||||||
RemdeskClientContext* context = NULL;
|
RemdeskClientContext* context = NULL;
|
||||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||||
|
|
||||||
remdesk = (remdeskPlugin*) calloc(1, sizeof(remdeskPlugin));
|
remdesk = (remdeskPlugin*) calloc(1, sizeof(remdeskPlugin));
|
||||||
|
|
||||||
if (!remdesk)
|
if (!remdesk)
|
||||||
@ -1122,21 +1041,19 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
}
|
}
|
||||||
|
|
||||||
remdesk->channelDef.options =
|
remdesk->channelDef.options =
|
||||||
CHANNEL_OPTION_INITIALIZED |
|
CHANNEL_OPTION_INITIALIZED |
|
||||||
CHANNEL_OPTION_ENCRYPT_RDP |
|
CHANNEL_OPTION_ENCRYPT_RDP |
|
||||||
CHANNEL_OPTION_COMPRESS_RDP |
|
CHANNEL_OPTION_COMPRESS_RDP |
|
||||||
CHANNEL_OPTION_SHOW_PROTOCOL;
|
CHANNEL_OPTION_SHOW_PROTOCOL;
|
||||||
|
|
||||||
strcpy(remdesk->channelDef.name, "remdesk");
|
strcpy(remdesk->channelDef.name, "remdesk");
|
||||||
|
|
||||||
remdesk->Version = 2;
|
remdesk->Version = 2;
|
||||||
|
|
||||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
||||||
|
|
||||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
||||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||||
{
|
{
|
||||||
context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext));
|
context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext));
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -1144,31 +1061,29 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
}
|
}
|
||||||
|
|
||||||
context->handle = (void*) remdesk;
|
context->handle = (void*) remdesk;
|
||||||
|
|
||||||
*(pEntryPointsEx->ppInterface) = (void*) context;
|
*(pEntryPointsEx->ppInterface) = (void*) context;
|
||||||
remdesk->context = context;
|
remdesk->context = context;
|
||||||
remdesk->rdpcontext = pEntryPointsEx->context;
|
remdesk->rdpcontext = pEntryPointsEx->context;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints,
|
||||||
|
sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||||
rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle,
|
rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle,
|
||||||
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, remdesk_virtual_channel_init_event);
|
&remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
|
||||||
|
remdesk_virtual_channel_init_event);
|
||||||
|
|
||||||
if (CHANNEL_RC_OK != rc)
|
if (CHANNEL_RC_OK != rc)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
|
||||||
WTSErrorToString(rc), rc);
|
WTSErrorToString(rc), rc);
|
||||||
goto error_out;
|
goto error_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
remdesk->channelEntryPoints.pInterface = *(remdesk->channelEntryPoints.ppInterface);
|
remdesk->channelEntryPoints.pInterface = *
|
||||||
remdesk->channelEntryPoints.ppInterface = &(remdesk->channelEntryPoints.pInterface);
|
(remdesk->channelEntryPoints.ppInterface);
|
||||||
|
remdesk->channelEntryPoints.ppInterface = &
|
||||||
if ((error = remdesk_add_init_handle_data(remdesk->InitHandle, (void*) remdesk)))
|
(remdesk->channelEntryPoints.pInterface);
|
||||||
{
|
s_TLSPluginContext = remdesk;
|
||||||
WLog_ERR(TAG, "remdesk_add_init_handle_data failed with error %lu!", error);
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error_out:
|
error_out:
|
||||||
free(remdesk);
|
free(remdesk);
|
||||||
|
@ -721,7 +721,7 @@ static BOOL android_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!instance || !context)
|
if (!instance || !context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!android_event_queue_init(instance))
|
if (!android_event_queue_init(instance))
|
||||||
|
@ -51,7 +51,7 @@ struct thread_data
|
|||||||
|
|
||||||
BOOL df_context_new(freerdp* instance, rdpContext* context)
|
BOOL df_context_new(freerdp* instance, rdpContext* context)
|
||||||
{
|
{
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -77,7 +77,6 @@ void df_end_paint(rdpContext* context)
|
|||||||
{
|
{
|
||||||
rdpGdi* gdi;
|
rdpGdi* gdi;
|
||||||
dfInfo* dfi;
|
dfInfo* dfi;
|
||||||
|
|
||||||
gdi = context->gdi;
|
gdi = context->gdi;
|
||||||
dfi = ((dfContext*) context)->dfi;
|
dfi = ((dfContext*) context)->dfi;
|
||||||
|
|
||||||
@ -95,26 +94,23 @@ void df_end_paint(rdpContext* context)
|
|||||||
dfi->update_rect.w = gdi->width;
|
dfi->update_rect.w = gdi->width;
|
||||||
dfi->update_rect.h = gdi->height;
|
dfi->update_rect.h = gdi->height;
|
||||||
#endif
|
#endif
|
||||||
|
dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect),
|
||||||
dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y);
|
dfi->update_rect.x, dfi->update_rect.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
|
BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds,
|
||||||
|
int* wcount)
|
||||||
{
|
{
|
||||||
dfInfo* dfi;
|
dfInfo* dfi;
|
||||||
|
|
||||||
dfi = ((dfContext*) instance->context)->dfi;
|
dfi = ((dfContext*) instance->context)->dfi;
|
||||||
|
|
||||||
rfds[*rcount] = (void*)(long)(dfi->read_fds);
|
rfds[*rcount] = (void*)(long)(dfi->read_fds);
|
||||||
(*rcount)++;
|
(*rcount)++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL df_check_fds(freerdp* instance, fd_set* set)
|
BOOL df_check_fds(freerdp* instance, fd_set* set)
|
||||||
{
|
{
|
||||||
dfInfo* dfi;
|
dfInfo* dfi;
|
||||||
|
|
||||||
dfi = ((dfContext*) instance->context)->dfi;
|
dfi = ((dfContext*) instance->context)->dfi;
|
||||||
|
|
||||||
if (!FD_ISSET(dfi->read_fds, set))
|
if (!FD_ISSET(dfi->read_fds, set))
|
||||||
@ -132,16 +128,12 @@ BOOL df_pre_connect(freerdp* instance)
|
|||||||
BOOL bitmap_cache;
|
BOOL bitmap_cache;
|
||||||
dfContext* context;
|
dfContext* context;
|
||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
|
|
||||||
dfi = (dfInfo*) malloc(sizeof(dfInfo));
|
dfi = (dfInfo*) malloc(sizeof(dfInfo));
|
||||||
ZeroMemory(dfi, sizeof(dfInfo));
|
ZeroMemory(dfi, sizeof(dfInfo));
|
||||||
|
|
||||||
context = ((dfContext*) instance->context);
|
context = ((dfContext*) instance->context);
|
||||||
context->dfi = dfi;
|
context->dfi = dfi;
|
||||||
|
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
bitmap_cache = settings->BitmapCacheEnabled;
|
bitmap_cache = settings->BitmapCacheEnabled;
|
||||||
|
|
||||||
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
|
||||||
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
|
||||||
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
|
||||||
@ -166,18 +158,16 @@ BOOL df_pre_connect(freerdp* instance)
|
|||||||
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
|
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
|
||||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
||||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||||
|
|
||||||
dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV));
|
dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV));
|
||||||
ZeroMemory(dfi->clrconv, sizeof(CLRCONV));
|
ZeroMemory(dfi->clrconv, sizeof(CLRCONV));
|
||||||
|
|
||||||
dfi->clrconv->alpha = 1;
|
dfi->clrconv->alpha = 1;
|
||||||
dfi->clrconv->invert = 0;
|
dfi->clrconv->invert = 0;
|
||||||
dfi->clrconv->rgb555 = 0;
|
dfi->clrconv->rgb555 = 0;
|
||||||
|
|
||||||
dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette));
|
dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette));
|
||||||
ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette));
|
ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette));
|
||||||
|
|
||||||
if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK)
|
if (freerdp_channels_pre_connect(instance->context->channels,
|
||||||
|
instance) != CHANNEL_RC_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (instance->context->cache = cache_new(instance->settings)) != NULL;
|
return (instance->context->cache = cache_new(instance->settings)) != NULL;
|
||||||
@ -188,29 +178,27 @@ BOOL df_post_connect(freerdp* instance)
|
|||||||
rdpGdi* gdi;
|
rdpGdi* gdi;
|
||||||
dfInfo* dfi;
|
dfInfo* dfi;
|
||||||
dfContext* context;
|
dfContext* context;
|
||||||
|
|
||||||
context = ((dfContext*) instance->context);
|
context = ((dfContext*) instance->context);
|
||||||
dfi = context->dfi;
|
dfi = context->dfi;
|
||||||
|
|
||||||
if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL))
|
if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP |
|
||||||
|
CLRBUF_32BPP, NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
gdi = instance->context->gdi;
|
gdi = instance->context->gdi;
|
||||||
|
|
||||||
dfi->err = DirectFBCreate(&(dfi->dfb));
|
dfi->err = DirectFBCreate(&(dfi->dfb));
|
||||||
|
|
||||||
dfi->dsc.flags = DSDESC_CAPS;
|
dfi->dsc.flags = DSDESC_CAPS;
|
||||||
dfi->dsc.caps = DSCAPS_PRIMARY;
|
dfi->dsc.caps = DSCAPS_PRIMARY;
|
||||||
dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary));
|
dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary));
|
||||||
dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height));
|
dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height));
|
||||||
dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp);
|
dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp);
|
||||||
dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, &(dfi->event_buffer));
|
dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE,
|
||||||
|
&(dfi->event_buffer));
|
||||||
dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds));
|
dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds));
|
||||||
|
|
||||||
dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer));
|
dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer));
|
||||||
dfi->layer->EnableCursor(dfi->layer, 1);
|
dfi->layer->EnableCursor(dfi->layer, 1);
|
||||||
|
dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT |
|
||||||
dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT;
|
DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT;
|
||||||
dfi->dsc.caps = DSCAPS_SYSTEMONLY;
|
dfi->dsc.caps = DSCAPS_SYSTEMONLY;
|
||||||
dfi->dsc.width = gdi->width;
|
dfi->dsc.width = gdi->width;
|
||||||
dfi->dsc.height = gdi->height;
|
dfi->dsc.height = gdi->height;
|
||||||
@ -227,28 +215,27 @@ BOOL df_post_connect(freerdp* instance)
|
|||||||
dfi->dsc.preallocated[0].data = gdi->primary_buffer;
|
dfi->dsc.preallocated[0].data = gdi->primary_buffer;
|
||||||
dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel;
|
dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel;
|
||||||
dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface));
|
dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface));
|
||||||
|
|
||||||
instance->update->BeginPaint = df_begin_paint;
|
instance->update->BeginPaint = df_begin_paint;
|
||||||
instance->update->EndPaint = df_end_paint;
|
instance->update->EndPaint = df_end_paint;
|
||||||
|
|
||||||
df_keyboard_init();
|
df_keyboard_init();
|
||||||
|
|
||||||
pointer_cache_register_callbacks(instance->update);
|
pointer_cache_register_callbacks(instance->update);
|
||||||
df_register_graphics(instance->context->graphics);
|
df_register_graphics(instance->context->graphics);
|
||||||
|
return freerdp_channels_post_connect(instance->context->channels,
|
||||||
return freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK;
|
instance) == CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer,
|
||||||
|
char* fingerprint)
|
||||||
{
|
{
|
||||||
char answer;
|
char answer;
|
||||||
WLog_INFO(TAG, "Certificate details:");
|
WLog_INFO(TAG, "Certificate details:");
|
||||||
WLog_INFO(TAG, "\tSubject: %s", subject);
|
WLog_INFO(TAG, "\tSubject: %s", subject);
|
||||||
WLog_INFO(TAG, "\tIssuer: %s", issuer);
|
WLog_INFO(TAG, "\tIssuer: %s", issuer);
|
||||||
WLog_INFO(TAG, "\tThumbprint: %s", fingerprint);
|
WLog_INFO(TAG, "\tThumbprint: %s", fingerprint);
|
||||||
WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have "
|
WLog_INFO(TAG,
|
||||||
"the CA certificate in your certificate store, or the certificate has expired. "
|
"The above X.509 certificate could not be verified, possibly because you do not have "
|
||||||
"Please look at the documentation on how to create local certificate store for a private CA.");
|
"the CA certificate in your certificate store, or the certificate has expired. "
|
||||||
|
"Please look at the documentation on how to create local certificate store for a private CA.");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -268,28 +255,28 @@ BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char*
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int df_receive_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int total_size)
|
static int df_receive_channel_data(freerdp* instance, UINT16 channelId,
|
||||||
|
BYTE* data, int size, int flags, int total_size)
|
||||||
{
|
{
|
||||||
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
|
return freerdp_channels_data(instance, channelId, data, size, flags,
|
||||||
|
total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void df_process_cb_monitor_ready_event(rdpChannels* channels, freerdp* instance)
|
static void df_process_cb_monitor_ready_event(rdpChannels* channels,
|
||||||
|
freerdp* instance)
|
||||||
{
|
{
|
||||||
wMessage* event;
|
wMessage* event;
|
||||||
RDP_CB_FORMAT_LIST_EVENT* format_list_event;
|
RDP_CB_FORMAT_LIST_EVENT* format_list_event;
|
||||||
|
event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL,
|
||||||
event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL);
|
NULL);
|
||||||
|
|
||||||
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
|
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
|
||||||
format_list_event->num_formats = 0;
|
format_list_event->num_formats = 0;
|
||||||
|
|
||||||
freerdp_channels_send_event(channels, event);
|
freerdp_channels_send_event(channels, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void df_process_channel_event(rdpChannels* channels, freerdp* instance)
|
static void df_process_channel_event(rdpChannels* channels, freerdp* instance)
|
||||||
{
|
{
|
||||||
wMessage* event;
|
wMessage* event;
|
||||||
|
|
||||||
event = freerdp_channels_pop_event(channels);
|
event = freerdp_channels_pop_event(channels);
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
@ -301,7 +288,8 @@ static void df_process_channel_event(rdpChannels* channels, freerdp* instance)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WLog_ERR(TAG, "df_process_channel_event: unknown event type %d", GetMessageType(event->id));
|
WLog_ERR(TAG, "df_process_channel_event: unknown event type %d",
|
||||||
|
GetMessageType(event->id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +317,6 @@ int dfreerdp_run(freerdp* instance)
|
|||||||
dfInfo* dfi;
|
dfInfo* dfi;
|
||||||
dfContext* context;
|
dfContext* context;
|
||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
|
|
||||||
ZeroMemory(rfds, sizeof(rfds));
|
ZeroMemory(rfds, sizeof(rfds));
|
||||||
ZeroMemory(wfds, sizeof(wfds));
|
ZeroMemory(wfds, sizeof(wfds));
|
||||||
|
|
||||||
@ -337,7 +324,6 @@ int dfreerdp_run(freerdp* instance)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
context = (dfContext*) instance->context;
|
context = (dfContext*) instance->context;
|
||||||
|
|
||||||
dfi = context->dfi;
|
dfi = context->dfi;
|
||||||
channels = instance->context->channels;
|
channels = instance->context->channels;
|
||||||
|
|
||||||
@ -351,11 +337,14 @@ int dfreerdp_run(freerdp* instance)
|
|||||||
WLog_ERR(TAG, "Failed to get FreeRDP file descriptor");
|
WLog_ERR(TAG, "Failed to get FreeRDP file descriptor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
|
||||||
|
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds,
|
||||||
|
&wcount) != TRUE)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to get channel manager file descriptor");
|
WLog_ERR(TAG, "Failed to get channel manager file descriptor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to get dfreerdp file descriptor");
|
WLog_ERR(TAG, "Failed to get dfreerdp file descriptor");
|
||||||
@ -383,9 +372,9 @@ int dfreerdp_run(freerdp* instance)
|
|||||||
{
|
{
|
||||||
/* these are not really errors */
|
/* these are not really errors */
|
||||||
if (!((errno == EAGAIN) ||
|
if (!((errno == EAGAIN) ||
|
||||||
(errno == EWOULDBLOCK) ||
|
(errno == EWOULDBLOCK) ||
|
||||||
(errno == EINPROGRESS) ||
|
(errno == EINPROGRESS) ||
|
||||||
(errno == EINTR))) /* signal occurred */
|
(errno == EINTR))) /* signal occurred */
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "dfreerdp_run: select failed");
|
WLog_ERR(TAG, "dfreerdp_run: select failed");
|
||||||
break;
|
break;
|
||||||
@ -397,29 +386,30 @@ int dfreerdp_run(freerdp* instance)
|
|||||||
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
|
WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (df_check_fds(instance, &rfds_set) != TRUE)
|
if (df_check_fds(instance, &rfds_set) != TRUE)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to check dfreerdp file descriptor");
|
WLog_ERR(TAG, "Failed to check dfreerdp file descriptor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (freerdp_channels_check_fds(channels, instance) != TRUE)
|
if (freerdp_channels_check_fds(channels, instance) != TRUE)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to check channel manager file descriptor");
|
WLog_ERR(TAG, "Failed to check channel manager file descriptor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
df_process_channel_event(channels, instance);
|
df_process_channel_event(channels, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
freerdp_channels_disconnect(channels, instance);
|
freerdp_channels_disconnect(channels, instance);
|
||||||
freerdp_disconnect(instance);
|
freerdp_disconnect(instance);
|
||||||
|
|
||||||
freerdp_channels_close(channels, instance);
|
freerdp_channels_close(channels, instance);
|
||||||
freerdp_channels_free(channels);
|
freerdp_channels_free(channels);
|
||||||
df_free(dfi);
|
df_free(dfi);
|
||||||
gdi_free(instance);
|
gdi_free(instance);
|
||||||
freerdp_disconnect(instance);
|
freerdp_disconnect(instance);
|
||||||
freerdp_free(instance);
|
freerdp_free(instance);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,17 +417,13 @@ void* thread_func(void* param)
|
|||||||
{
|
{
|
||||||
struct thread_data* data;
|
struct thread_data* data;
|
||||||
data = (struct thread_data*) param;
|
data = (struct thread_data*) param;
|
||||||
|
|
||||||
dfreerdp_run(data->instance);
|
dfreerdp_run(data->instance);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
pthread_detach(pthread_self());
|
pthread_detach(pthread_self());
|
||||||
|
|
||||||
g_thread_count--;
|
g_thread_count--;
|
||||||
|
|
||||||
if (g_thread_count < 1)
|
if (g_thread_count < 1)
|
||||||
ReleaseSemaphore(g_sem, 1, NULL);
|
ReleaseSemaphore(g_sem, 1, NULL);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -450,7 +436,6 @@ int main(int argc, char* argv[])
|
|||||||
dfContext* context;
|
dfContext* context;
|
||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
struct thread_data* data;
|
struct thread_data* data;
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
if (!(g_sem = CreateSemaphore(NULL, 0, 1, NULL)))
|
if (!(g_sem = CreateSemaphore(NULL, 0, 1, NULL)))
|
||||||
@ -464,7 +449,6 @@ int main(int argc, char* argv[])
|
|||||||
instance->PostConnect = df_post_connect;
|
instance->PostConnect = df_post_connect;
|
||||||
instance->VerifyCertificate = df_verify_certificate;
|
instance->VerifyCertificate = df_verify_certificate;
|
||||||
instance->ReceiveChannelData = df_receive_channel_data;
|
instance->ReceiveChannelData = df_receive_channel_data;
|
||||||
|
|
||||||
instance->ContextSize = sizeof(dfContext);
|
instance->ContextSize = sizeof(dfContext);
|
||||||
instance->ContextNew = df_context_new;
|
instance->ContextNew = df_context_new;
|
||||||
instance->ContextFree = df_context_free;
|
instance->ContextFree = df_context_free;
|
||||||
@ -477,25 +461,22 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
context = (dfContext*) instance->context;
|
context = (dfContext*) instance->context;
|
||||||
channels = instance->context->channels;
|
channels = instance->context->channels;
|
||||||
|
|
||||||
DirectFBInit(&argc, &argv);
|
DirectFBInit(&argc, &argv);
|
||||||
|
|
||||||
instance->context->argc = argc;
|
instance->context->argc = argc;
|
||||||
instance->context->argv = argv;
|
instance->context->argv = argv;
|
||||||
|
status = freerdp_client_settings_parse_command_line(instance->settings, argc,
|
||||||
status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE);
|
argv, FALSE);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
if (!freerdp_client_load_addins(instance->context->channels, instance->settings))
|
if (!freerdp_client_load_addins(instance->context->channels,
|
||||||
|
instance->settings))
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
||||||
data = (struct thread_data*) malloc(sizeof(struct thread_data));
|
data = (struct thread_data*) malloc(sizeof(struct thread_data));
|
||||||
ZeroMemory(data, sizeof(sizeof(struct thread_data)));
|
ZeroMemory(data, sizeof(sizeof(struct thread_data)));
|
||||||
|
|
||||||
data->instance = instance;
|
data->instance = instance;
|
||||||
|
|
||||||
g_thread_count++;
|
g_thread_count++;
|
||||||
pthread_create(&thread, 0, thread_func, data);
|
pthread_create(&thread, 0, thread_func, data);
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ static BOOL mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
context->instance->PreConnect = mac_pre_connect;
|
context->instance->PreConnect = mac_pre_connect;
|
||||||
context->instance->PostConnect = mac_post_connect;
|
context->instance->PostConnect = mac_post_connect;
|
||||||
context->instance->Authenticate = mac_authenticate;
|
context->instance->Authenticate = mac_authenticate;
|
||||||
context->channels = freerdp_channels_new();
|
context->channels = freerdp_channels_new(instance);
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
settings->AsyncTransport = TRUE;
|
settings->AsyncTransport = TRUE;
|
||||||
settings->AsyncUpdate = TRUE;
|
settings->AsyncUpdate = TRUE;
|
||||||
|
@ -49,7 +49,7 @@ typedef struct tf_context tfContext;
|
|||||||
|
|
||||||
static BOOL tf_context_new(freerdp* instance, rdpContext* context)
|
static BOOL tf_context_new(freerdp* instance, rdpContext* context)
|
||||||
{
|
{
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -69,7 +69,7 @@ static BOOL tf_begin_paint(rdpContext* context)
|
|||||||
{
|
{
|
||||||
rdpGdi* gdi = context->gdi;
|
rdpGdi* gdi = context->gdi;
|
||||||
gdi->primary->hdc->hwnd->invalid->null = 1;
|
gdi->primary->hdc->hwnd->invalid->null = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL tf_end_paint(rdpContext* context)
|
static BOOL tf_end_paint(rdpContext* context)
|
||||||
@ -78,16 +78,14 @@ static BOOL tf_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
if (gdi->primary->hdc->hwnd->invalid->null)
|
if (gdi->primary->hdc->hwnd->invalid->null)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL tf_pre_connect(freerdp* instance)
|
static BOOL tf_pre_connect(freerdp* instance)
|
||||||
{
|
{
|
||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
|
|
||||||
|
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
|
|
||||||
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
|
||||||
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
|
||||||
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
|
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
|
||||||
@ -111,7 +109,8 @@ static BOOL tf_pre_connect(freerdp* instance)
|
|||||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE;
|
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE;
|
||||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE;
|
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE;
|
||||||
|
|
||||||
if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK)
|
if (freerdp_channels_pre_connect(instance->context->channels,
|
||||||
|
instance) != CHANNEL_RC_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -124,8 +123,8 @@ static BOOL tf_post_connect(freerdp* instance)
|
|||||||
|
|
||||||
instance->update->BeginPaint = tf_begin_paint;
|
instance->update->BeginPaint = tf_begin_paint;
|
||||||
instance->update->EndPaint = tf_end_paint;
|
instance->update->EndPaint = tf_end_paint;
|
||||||
|
return (freerdp_channels_post_connect(instance->context->channels,
|
||||||
return (freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK);
|
instance) == CHANNEL_RC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* tf_client_thread_proc(freerdp* instance)
|
static void* tf_client_thread_proc(freerdp* instance)
|
||||||
@ -146,16 +145,17 @@ static void* tf_client_thread_proc(freerdp* instance)
|
|||||||
|
|
||||||
if (nCount == 0)
|
if (nCount == 0)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__);
|
WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
||||||
|
|
||||||
if (status == WAIT_FAILED)
|
if (status == WAIT_FAILED)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__, status);
|
WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__,
|
||||||
break;
|
status);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!freerdp_check_event_handles(instance->context))
|
if (!freerdp_check_event_handles(instance->context))
|
||||||
@ -166,7 +166,6 @@ static void* tf_client_thread_proc(freerdp* instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
freerdp_disconnect(instance);
|
freerdp_disconnect(instance);
|
||||||
|
|
||||||
ExitThread(0);
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -176,16 +175,16 @@ int main(int argc, char* argv[])
|
|||||||
int status;
|
int status;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
freerdp* instance;
|
freerdp* instance;
|
||||||
|
|
||||||
instance = freerdp_new();
|
instance = freerdp_new();
|
||||||
|
|
||||||
if (!instance)
|
if (!instance)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Couldn't create instance");
|
WLog_ERR(TAG, "Couldn't create instance");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->PreConnect = tf_pre_connect;
|
instance->PreConnect = tf_pre_connect;
|
||||||
instance->PostConnect = tf_post_connect;
|
instance->PostConnect = tf_post_connect;
|
||||||
|
|
||||||
instance->ContextSize = sizeof(tfContext);
|
instance->ContextSize = sizeof(tfContext);
|
||||||
instance->ContextNew = tf_context_new;
|
instance->ContextNew = tf_context_new;
|
||||||
instance->ContextFree = tf_context_free;
|
instance->ContextFree = tf_context_free;
|
||||||
@ -196,18 +195,20 @@ int main(int argc, char* argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE);
|
status = freerdp_client_settings_parse_command_line(instance->settings, argc,
|
||||||
|
argv, FALSE);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!freerdp_client_load_addins(instance->context->channels, instance->settings))
|
if (!freerdp_client_load_addins(instance->context->channels,
|
||||||
exit (-1);
|
instance->settings))
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
||||||
tf_client_thread_proc, instance, 0, NULL)))
|
tf_client_thread_proc, instance, 0, NULL)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to create client thread");
|
WLog_ERR(TAG, "Failed to create client thread");
|
||||||
}
|
}
|
||||||
@ -218,6 +219,5 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
freerdp_context_free(instance);
|
freerdp_context_free(instance);
|
||||||
freerdp_free(instance);
|
freerdp_free(instance);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!instance || !context)
|
if (!instance || !context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
instance->PreConnect = wl_pre_connect;
|
instance->PreConnect = wl_pre_connect;
|
||||||
|
@ -145,7 +145,7 @@ static BOOL wf_sw_desktop_resize(rdpContext* context)
|
|||||||
{
|
{
|
||||||
wf_image_free(wfc->primary);
|
wf_image_free(wfc->primary);
|
||||||
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
||||||
settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL);
|
settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -190,7 +190,7 @@ static BOOL wf_hw_desktop_resize(rdpContext* context)
|
|||||||
same = (wfc->primary == wfc->drawing) ? TRUE : FALSE;
|
same = (wfc->primary == wfc->drawing) ? TRUE : FALSE;
|
||||||
wf_image_free(wfc->primary);
|
wf_image_free(wfc->primary);
|
||||||
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
||||||
settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL);
|
settings->DesktopHeight, wfc->context.gdi->dstFormat, NULL);
|
||||||
|
|
||||||
if (same)
|
if (same)
|
||||||
wfc->drawing = wfc->primary;
|
wfc->drawing = wfc->primary;
|
||||||
@ -200,7 +200,7 @@ static BOOL wf_hw_desktop_resize(rdpContext* context)
|
|||||||
{
|
{
|
||||||
if (wfc->hwnd)
|
if (wfc->hwnd)
|
||||||
SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, settings->DesktopWidth + wfc->diff.x,
|
SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, settings->DesktopWidth + wfc->diff.x,
|
||||||
settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE);
|
settings->DesktopHeight + wfc->diff.y, SWP_NOMOVE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -296,22 +296,22 @@ static BOOL wf_pre_connect(freerdp* instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) ||
|
if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) ||
|
||||||
(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
|
(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth,
|
WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth,
|
||||||
settings->DesktopHeight);
|
settings->DesktopHeight);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout,
|
freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout,
|
||||||
(int) GetKeyboardLayout(0) & 0x0000FFFF);
|
(int) GetKeyboardLayout(0) & 0x0000FFFF);
|
||||||
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
||||||
(pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler);
|
(pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler);
|
||||||
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
|
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
|
||||||
(pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler);
|
(pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler);
|
||||||
|
|
||||||
if (freerdp_channels_pre_connect(instance->context->channels,
|
if (freerdp_channels_pre_connect(instance->context->channels,
|
||||||
instance) != CHANNEL_RC_OK)
|
instance) != CHANNEL_RC_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -323,7 +323,7 @@ static void wf_add_system_menu(wfContext* wfc)
|
|||||||
MENUITEMINFO item_info;
|
MENUITEMINFO item_info;
|
||||||
ZeroMemory(&item_info, sizeof(MENUITEMINFO));
|
ZeroMemory(&item_info, sizeof(MENUITEMINFO));
|
||||||
item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING |
|
item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING |
|
||||||
MIIM_DATA;
|
MIIM_DATA;
|
||||||
item_info.cbSize = sizeof(MENUITEMINFO);
|
item_info.cbSize = sizeof(MENUITEMINFO);
|
||||||
item_info.wID = SYSCOMMAND_ID_SMARTSIZING;
|
item_info.wID = SYSCOMMAND_ID_SMARTSIZING;
|
||||||
item_info.fType = MFT_STRING;
|
item_info.fType = MFT_STRING;
|
||||||
@ -349,13 +349,12 @@ static BOOL wf_post_connect(freerdp* instance)
|
|||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
EmbedWindowEventArgs e;
|
EmbedWindowEventArgs e;
|
||||||
const UINT32 format = PIXEL_FORMAT_BGRX32;
|
const UINT32 format = PIXEL_FORMAT_BGRX32;
|
||||||
|
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
context = instance->context;
|
context = instance->context;
|
||||||
wfc = (wfContext*) instance->context;
|
wfc = (wfContext*) instance->context;
|
||||||
cache = instance->context->cache;
|
cache = instance->context->cache;
|
||||||
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
wfc->primary = wf_image_new(wfc, settings->DesktopWidth,
|
||||||
settings->DesktopHeight, format, NULL);
|
settings->DesktopHeight, format, NULL);
|
||||||
|
|
||||||
if (!gdi_init_ex(instance, format, 0, wfc->primary->pdata, wf_image_free))
|
if (!gdi_init_ex(instance, format, 0, wfc->primary->pdata, wf_image_free))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -371,10 +370,10 @@ static BOOL wf_post_connect(freerdp* instance)
|
|||||||
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"%S", settings->WindowTitle);
|
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"%S", settings->WindowTitle);
|
||||||
else if (settings->ServerPort == 3389)
|
else if (settings->ServerPort == 3389)
|
||||||
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S",
|
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S",
|
||||||
settings->ServerHostname);
|
settings->ServerHostname);
|
||||||
else
|
else
|
||||||
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S:%d",
|
_snwprintf(lpWindowName, ARRAYSIZE(lpWindowName), L"FreeRDP: %S:%d",
|
||||||
settings->ServerHostname, settings->ServerPort);
|
settings->ServerHostname, settings->ServerPort);
|
||||||
|
|
||||||
if (settings->EmbeddedWindow)
|
if (settings->EmbeddedWindow)
|
||||||
settings->Decorations = FALSE;
|
settings->Decorations = FALSE;
|
||||||
@ -385,20 +384,20 @@ static BOOL wf_post_connect(freerdp* instance)
|
|||||||
dwStyle = WS_CHILD | WS_BORDER;
|
dwStyle = WS_CHILD | WS_BORDER;
|
||||||
else
|
else
|
||||||
dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX
|
dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX
|
||||||
| WS_MAXIMIZEBOX;
|
| WS_MAXIMIZEBOX;
|
||||||
|
|
||||||
if (!wfc->hwnd)
|
if (!wfc->hwnd)
|
||||||
{
|
{
|
||||||
wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName,
|
wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName,
|
||||||
dwStyle,
|
dwStyle,
|
||||||
0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL);
|
0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL);
|
||||||
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
|
SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc);
|
||||||
}
|
}
|
||||||
|
|
||||||
wf_resize_window(wfc);
|
wf_resize_window(wfc);
|
||||||
wf_add_system_menu(wfc);
|
wf_add_system_menu(wfc);
|
||||||
BitBlt(wfc->primary->hdc, 0, 0, settings->DesktopWidth, settings->DesktopHeight,
|
BitBlt(wfc->primary->hdc, 0, 0, settings->DesktopWidth, settings->DesktopHeight,
|
||||||
NULL, 0, 0, BLACKNESS);
|
NULL, 0, 0, BLACKNESS);
|
||||||
wfc->drawing = wfc->primary;
|
wfc->drawing = wfc->primary;
|
||||||
EventArgsInit(&e, "wfreerdp");
|
EventArgsInit(&e, "wfreerdp");
|
||||||
e.embed = FALSE;
|
e.embed = FALSE;
|
||||||
@ -453,7 +452,7 @@ static CREDUI_INFOA wfUiInfo =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static BOOL wf_authenticate_raw(freerdp* instance, const char* title,
|
static BOOL wf_authenticate_raw(freerdp* instance, const char* title,
|
||||||
char** username, char** password, char** domain)
|
char** username, char** password, char** domain)
|
||||||
{
|
{
|
||||||
BOOL fSave;
|
BOOL fSave;
|
||||||
DWORD status;
|
DWORD status;
|
||||||
@ -467,8 +466,8 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title,
|
|||||||
ZeroMemory(Password, sizeof(Password));
|
ZeroMemory(Password, sizeof(Password));
|
||||||
dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES;
|
dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES;
|
||||||
status = CredUIPromptForCredentialsA(&wfUiInfo, title, NULL, 0,
|
status = CredUIPromptForCredentialsA(&wfUiInfo, title, NULL, 0,
|
||||||
UserName, CREDUI_MAX_USERNAME_LENGTH + 1,
|
UserName, CREDUI_MAX_USERNAME_LENGTH + 1,
|
||||||
Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
||||||
|
|
||||||
if (status != NO_ERROR)
|
if (status != NO_ERROR)
|
||||||
{
|
{
|
||||||
@ -479,7 +478,7 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title,
|
|||||||
ZeroMemory(User, sizeof(User));
|
ZeroMemory(User, sizeof(User));
|
||||||
ZeroMemory(Domain, sizeof(Domain));
|
ZeroMemory(Domain, sizeof(Domain));
|
||||||
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain,
|
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain,
|
||||||
sizeof(Domain));
|
sizeof(Domain));
|
||||||
//WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
|
//WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
|
||||||
*username = _strdup(User);
|
*username = _strdup(User);
|
||||||
|
|
||||||
@ -514,14 +513,14 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BOOL wf_authenticate(freerdp* instance,
|
static BOOL wf_authenticate(freerdp* instance,
|
||||||
char** username, char** password, char** domain)
|
char** username, char** password, char** domain)
|
||||||
{
|
{
|
||||||
return wf_authenticate_raw(instance, instance->settings->ServerHostname,
|
return wf_authenticate_raw(instance, instance->settings->ServerHostname,
|
||||||
username, password, domain);
|
username, password, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL wf_gw_authenticate(freerdp* instance,
|
static BOOL wf_gw_authenticate(freerdp* instance,
|
||||||
char** username, char** password, char** domain)
|
char** username, char** password, char** domain)
|
||||||
{
|
{
|
||||||
char tmp[MAX_PATH];
|
char tmp[MAX_PATH];
|
||||||
sprintf_s(tmp, sizeof(tmp), "Gateway %s", instance->settings->GatewayHostname);
|
sprintf_s(tmp, sizeof(tmp), "Gateway %s", instance->settings->GatewayHostname);
|
||||||
@ -529,11 +528,11 @@ static BOOL wf_gw_authenticate(freerdp* instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DWORD wf_verify_certificate(freerdp* instance,
|
static DWORD wf_verify_certificate(freerdp* instance,
|
||||||
const char* common_name,
|
const char* common_name,
|
||||||
const char* subject,
|
const char* subject,
|
||||||
const char* issuer,
|
const char* issuer,
|
||||||
const char* fingerprint,
|
const char* fingerprint,
|
||||||
BOOL host_mismatch)
|
BOOL host_mismatch)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
@ -550,9 +549,9 @@ static DWORD wf_verify_certificate(freerdp* instance,
|
|||||||
WLog_INFO(TAG, "\tThumbprint: %s", fingerprint);
|
WLog_INFO(TAG, "\tThumbprint: %s", fingerprint);
|
||||||
WLog_INFO(TAG, "\tHostMismatch: %s", host_mismatch ? "Yes" : "No");
|
WLog_INFO(TAG, "\tHostMismatch: %s", host_mismatch ? "Yes" : "No");
|
||||||
WLog_INFO(TAG,
|
WLog_INFO(TAG,
|
||||||
"The above X.509 certificate could not be verified, possibly because you do not have "
|
"The above X.509 certificate could not be verified, possibly because you do not have "
|
||||||
"the CA certificate in your certificate store, or the certificate has expired. "
|
"the CA certificate in your certificate store, or the certificate has expired. "
|
||||||
"Please look at the documentation on how to create local certificate store for a private CA.");
|
"Please look at the documentation on how to create local certificate store for a private CA.");
|
||||||
/* TODO: ask for user validation */
|
/* TODO: ask for user validation */
|
||||||
#if 0
|
#if 0
|
||||||
input_handle = GetStdHandle(STD_INPUT_HANDLE);
|
input_handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
@ -566,11 +565,11 @@ static DWORD wf_verify_certificate(freerdp* instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DWORD wf_verify_changed_certificate(freerdp* instance,
|
static DWORD wf_verify_changed_certificate(freerdp* instance,
|
||||||
const char* common_name,
|
const char* common_name,
|
||||||
const char* subject, const char* issuer,
|
const char* subject, const char* issuer,
|
||||||
const char* fingerprint,
|
const char* fingerprint,
|
||||||
const char* old_subject, const char* old_issuer,
|
const char* old_subject, const char* old_issuer,
|
||||||
const char* old_fingerprint)
|
const char* old_fingerprint)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "!!! Certificate has changed !!!");
|
WLog_ERR(TAG, "!!! Certificate has changed !!!");
|
||||||
WLog_ERR(TAG, "New Certificate details:");
|
WLog_ERR(TAG, "New Certificate details:");
|
||||||
@ -582,9 +581,9 @@ static DWORD wf_verify_changed_certificate(freerdp* instance,
|
|||||||
WLog_ERR(TAG, "\tIssuer: %s", old_issuer);
|
WLog_ERR(TAG, "\tIssuer: %s", old_issuer);
|
||||||
WLog_ERR(TAG, "\tThumbprint: %s", old_fingerprint);
|
WLog_ERR(TAG, "\tThumbprint: %s", old_fingerprint);
|
||||||
WLog_ERR(TAG,
|
WLog_ERR(TAG,
|
||||||
"The above X.509 certificate does not match the certificate used for previous connections. "
|
"The above X.509 certificate does not match the certificate used for previous connections. "
|
||||||
"This may indicate that the certificate has been tampered with."
|
"This may indicate that the certificate has been tampered with."
|
||||||
"Please contact the administrator of the RDP server and clarify.");
|
"Please contact the administrator of the RDP server and clarify.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,7 +644,7 @@ static void* wf_input_thread(void* arg)
|
|||||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||||
{
|
{
|
||||||
status = freerdp_message_queue_process_message(instance,
|
status = freerdp_message_queue_process_message(instance,
|
||||||
FREERDP_INPUT_MESSAGE_QUEUE, &message);
|
FREERDP_INPUT_MESSAGE_QUEUE, &message);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
@ -691,8 +690,8 @@ static DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
|||||||
if (async_input)
|
if (async_input)
|
||||||
{
|
{
|
||||||
if (!(input_thread = CreateThread(NULL, 0,
|
if (!(input_thread = CreateThread(NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE) wf_input_thread,
|
(LPTHREAD_START_ROUTINE) wf_input_thread,
|
||||||
instance, 0, NULL)))
|
instance, 0, NULL)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to create async input thread.");
|
WLog_ERR(TAG, "Failed to create async input thread.");
|
||||||
goto disconnect;
|
goto disconnect;
|
||||||
@ -723,10 +722,10 @@ static DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000,
|
if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000,
|
||||||
QS_ALLINPUT) == WAIT_FAILED)
|
QS_ALLINPUT) == WAIT_FAILED)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X",
|
WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X",
|
||||||
GetLastError());
|
GetLastError());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,7 +813,7 @@ static DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
|
|||||||
wfc = (wfContext*) lpParam;
|
wfc = (wfContext*) lpParam;
|
||||||
assert(NULL != wfc);
|
assert(NULL != wfc);
|
||||||
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance,
|
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (hook_handle)
|
if (hook_handle)
|
||||||
{
|
{
|
||||||
@ -868,14 +867,14 @@ static int freerdp_client_set_window_size(wfContext* wfc, int width, int height)
|
|||||||
if ((width != wfc->client_width) || (height != wfc->client_height))
|
if ((width != wfc->client_width) || (height != wfc->client_height))
|
||||||
{
|
{
|
||||||
PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED,
|
PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED,
|
||||||
((UINT) height << 16) | (UINT) width);
|
((UINT) height << 16) | (UINT) width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
|
void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
|
||||||
UINT32 client_height)
|
UINT32 client_height)
|
||||||
{
|
{
|
||||||
if (wfc->disablewindowtracking)
|
if (wfc->disablewindowtracking)
|
||||||
return;
|
return;
|
||||||
@ -908,8 +907,8 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
|
|||||||
horiz = TRUE;
|
horiz = TRUE;
|
||||||
}
|
}
|
||||||
else if (horiz
|
else if (horiz
|
||||||
&& client_width >=
|
&& client_width >=
|
||||||
wfc->context.settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/)
|
wfc->context.settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/)
|
||||||
{
|
{
|
||||||
horiz = FALSE;
|
horiz = FALSE;
|
||||||
}
|
}
|
||||||
@ -919,14 +918,14 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
|
|||||||
vert = TRUE;
|
vert = TRUE;
|
||||||
}
|
}
|
||||||
else if (vert
|
else if (vert
|
||||||
&& client_height >=
|
&& client_height >=
|
||||||
wfc->context.settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/)
|
wfc->context.settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/)
|
||||||
{
|
{
|
||||||
vert = FALSE;
|
vert = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (horiz == vert && (horiz != wfc->xScrollVisible
|
if (horiz == vert && (horiz != wfc->xScrollVisible
|
||||||
&& vert != wfc->yScrollVisible))
|
&& vert != wfc->yScrollVisible))
|
||||||
{
|
{
|
||||||
if (ShowScrollBar(wfc->hwnd, SB_BOTH, horiz))
|
if (ShowScrollBar(wfc->hwnd, SB_BOTH, horiz))
|
||||||
{
|
{
|
||||||
@ -973,7 +972,7 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
|
|||||||
// (bitmap_height) - (client_height). The current vertical
|
// (bitmap_height) - (client_height). The current vertical
|
||||||
// scroll value remains within the vertical scrolling range.
|
// scroll value remains within the vertical scrolling range.
|
||||||
wfc->yMaxScroll = MAX(wfc->context.settings->DesktopHeight - client_height,
|
wfc->yMaxScroll = MAX(wfc->context.settings->DesktopHeight - client_height,
|
||||||
0);
|
0);
|
||||||
wfc->yCurrentScroll = MIN(wfc->yCurrentScroll, wfc->yMaxScroll);
|
wfc->yCurrentScroll = MIN(wfc->yCurrentScroll, wfc->yMaxScroll);
|
||||||
si.cbSize = sizeof(si);
|
si.cbSize = sizeof(si);
|
||||||
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
||||||
@ -1019,7 +1018,7 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!(wfreerdp_client_global_init()))
|
if (!(wfreerdp_client_global_init()))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
instance->PreConnect = wf_pre_connect;
|
instance->PreConnect = wf_pre_connect;
|
||||||
@ -1028,7 +1027,6 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
instance->GatewayAuthenticate = wf_gw_authenticate;
|
instance->GatewayAuthenticate = wf_gw_authenticate;
|
||||||
instance->VerifyCertificate = wf_verify_certificate;
|
instance->VerifyCertificate = wf_verify_certificate;
|
||||||
instance->VerifyChangedCertificate = wf_verify_changed_certificate;
|
instance->VerifyChangedCertificate = wf_verify_changed_certificate;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,7 +1071,7 @@ static int wfreerdp_client_start(rdpContext* context)
|
|||||||
wfc->wndClass.hIconSm = wfc->icon;
|
wfc->wndClass.hIconSm = wfc->icon;
|
||||||
RegisterClassEx(&(wfc->wndClass));
|
RegisterClassEx(&(wfc->wndClass));
|
||||||
wfc->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfc, 0,
|
wfc->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfc, 0,
|
||||||
&wfc->keyboardThreadId);
|
&wfc->keyboardThreadId);
|
||||||
|
|
||||||
if (!wfc->keyboardThread)
|
if (!wfc->keyboardThread)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1082,7 +1080,7 @@ static int wfreerdp_client_start(rdpContext* context)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
wfc->thread = CreateThread(NULL, 0, wf_client_thread, (void*) instance, 0,
|
wfc->thread = CreateThread(NULL, 0, wf_client_thread, (void*) instance, 0,
|
||||||
&wfc->mainThreadId);
|
&wfc->mainThreadId);
|
||||||
|
|
||||||
if (!wfc->thread)
|
if (!wfc->thread)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1758,7 +1758,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
assert(!xfc->mutex);
|
assert(!xfc->mutex);
|
||||||
assert(!xfc->x11event);
|
assert(!xfc->x11event);
|
||||||
|
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
goto fail_channels_new;
|
goto fail_channels_new;
|
||||||
|
|
||||||
instance->PreConnect = xf_pre_connect;
|
instance->PreConnect = xf_pre_connect;
|
||||||
|
@ -435,7 +435,7 @@ static BOOL ios_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!instance || !context)
|
if (!instance || !context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!(context->channels = freerdp_channels_new()))
|
if (!(context->channels = freerdp_channels_new(instance)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == NULL)
|
if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == NULL)
|
||||||
|
@ -32,27 +32,36 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FREERDP_API rdpChannels* freerdp_channels_new(void);
|
FREERDP_API rdpChannels* freerdp_channels_new(freerdp* instance);
|
||||||
FREERDP_API void freerdp_channels_free(rdpChannels* channels);
|
FREERDP_API void freerdp_channels_free(rdpChannels* channels);
|
||||||
FREERDP_API int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings,
|
FREERDP_API int freerdp_channels_client_load(rdpChannels* channels,
|
||||||
PVIRTUALCHANNELENTRY entry, void* data);
|
rdpSettings* settings,
|
||||||
FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings,
|
PVIRTUALCHANNELENTRY entry, void* data);
|
||||||
const char* name, void* data);
|
FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels,
|
||||||
FREERDP_API UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance);
|
rdpSettings* settings,
|
||||||
FREERDP_API UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance);
|
const char* name, void* data);
|
||||||
FREERDP_API UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance);
|
FREERDP_API UINT freerdp_channels_pre_connect(rdpChannels* channels,
|
||||||
FREERDP_API BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds,
|
freerdp* instance);
|
||||||
int* read_count, void** write_fds, int* write_count);
|
FREERDP_API UINT freerdp_channels_post_connect(rdpChannels* channels,
|
||||||
FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance);
|
freerdp* instance);
|
||||||
FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance);
|
FREERDP_API UINT freerdp_channels_disconnect(rdpChannels* channels,
|
||||||
|
freerdp* instance);
|
||||||
|
FREERDP_API BOOL freerdp_channels_get_fds(rdpChannels* channels,
|
||||||
|
freerdp* instance, void** read_fds,
|
||||||
|
int* read_count, void** write_fds, int* write_count);
|
||||||
|
FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels,
|
||||||
|
freerdp* instance);
|
||||||
|
FREERDP_API void freerdp_channels_close(rdpChannels* channels,
|
||||||
|
freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API void* freerdp_channels_get_static_channel_interface(rdpChannels* channels, const char* name);
|
FREERDP_API void* freerdp_channels_get_static_channel_interface(
|
||||||
|
rdpChannels* channels, const char* name);
|
||||||
|
|
||||||
FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance);
|
FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance);
|
||||||
FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance);
|
FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API int freerdp_channels_data(freerdp* instance,
|
FREERDP_API int freerdp_channels_data(freerdp* instance,
|
||||||
UINT16 channelId, BYTE* data, int dataSize, int flags, int totalSize);
|
UINT16 channelId, BYTE* data, int dataSize, int flags, int totalSize);
|
||||||
|
|
||||||
FREERDP_API PWtsApiFunctionTable FreeRDP_InitWtsApi(void);
|
FREERDP_API PWtsApiFunctionTable FreeRDP_InitWtsApi(void);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ typedef BOOL (*pPreConnect)(freerdp* instance);
|
|||||||
typedef BOOL (*pPostConnect)(freerdp* instance);
|
typedef BOOL (*pPostConnect)(freerdp* instance);
|
||||||
typedef void (*pPostDisconnect)(freerdp* instance);
|
typedef void (*pPostDisconnect)(freerdp* instance);
|
||||||
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username,
|
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username,
|
||||||
char** password, char** domain);
|
char** password, char** domain);
|
||||||
|
|
||||||
/** @brief Callback used if user interaction is required to accept
|
/** @brief Callback used if user interaction is required to accept
|
||||||
* an unknown certificate.
|
* an unknown certificate.
|
||||||
@ -82,11 +82,11 @@ typedef BOOL (*pAuthenticate)(freerdp* instance, char** username,
|
|||||||
* a certificate only for this session, 0 otherwise.
|
* a certificate only for this session, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
typedef DWORD (*pVerifyCertificate)(freerdp* instance,
|
typedef DWORD (*pVerifyCertificate)(freerdp* instance,
|
||||||
const char* common_name,
|
const char* common_name,
|
||||||
const char* subject,
|
const char* subject,
|
||||||
const char* issuer,
|
const char* issuer,
|
||||||
const char* fingerprint,
|
const char* fingerprint,
|
||||||
BOOL host_mismatch);
|
BOOL host_mismatch);
|
||||||
|
|
||||||
/** @brief Callback used if user interaction is required to accept
|
/** @brief Callback used if user interaction is required to accept
|
||||||
* a changed certificate.
|
* a changed certificate.
|
||||||
@ -104,21 +104,23 @@ typedef DWORD (*pVerifyCertificate)(freerdp* instance,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance,
|
typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance,
|
||||||
const char* common_name,
|
const char* common_name,
|
||||||
const char* subject,
|
const char* subject,
|
||||||
const char* issuer,
|
const char* issuer,
|
||||||
const char* new_fingerprint,
|
const char* new_fingerprint,
|
||||||
const char* old_subject,
|
const char* old_subject,
|
||||||
const char* old_issuer,
|
const char* old_issuer,
|
||||||
const char* old_fingerprint);
|
const char* old_fingerprint);
|
||||||
typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data,
|
typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data,
|
||||||
int length, const char* hostname,
|
int length, const char* hostname,
|
||||||
int port, DWORD flags);
|
int port, DWORD flags);
|
||||||
|
|
||||||
typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
||||||
|
|
||||||
typedef int (*pSendChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size);
|
typedef int (*pSendChannelData)(freerdp* instance, UINT16 channelId, BYTE* data,
|
||||||
typedef int (*pReceiveChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
|
int size);
|
||||||
|
typedef int (*pReceiveChannelData)(freerdp* instance, UINT16 channelId,
|
||||||
|
BYTE* data, int size, int flags, int totalSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the context for a given instance of RDP connection.
|
* Defines the context for a given instance of RDP connection.
|
||||||
@ -261,9 +263,11 @@ struct rdp_freerdp
|
|||||||
Used when a certificate differs from stored fingerprint.
|
Used when a certificate differs from stored fingerprint.
|
||||||
If returns TRUE, the new fingerprint will be trusted and old thrown out. */
|
If returns TRUE, the new fingerprint will be trusted and old thrown out. */
|
||||||
|
|
||||||
ALIGN64 pVerifyX509Certificate VerifyX509Certificate; /**< (offset 53) Callback for X509 certificate verification (PEM format) */
|
ALIGN64 pVerifyX509Certificate
|
||||||
|
VerifyX509Certificate; /**< (offset 53) Callback for X509 certificate verification (PEM format) */
|
||||||
|
|
||||||
ALIGN64 pLogonErrorInfo LogonErrorInfo; /**< (offset 54) Callback for logon error info, important for logon system messages with RemoteApp */
|
ALIGN64 pLogonErrorInfo
|
||||||
|
LogonErrorInfo; /**< (offset 54) Callback for logon error info, important for logon system messages with RemoteApp */
|
||||||
|
|
||||||
ALIGN64 pPostDisconnect PostDisconnect; /**< (offset 55)
|
ALIGN64 pPostDisconnect PostDisconnect; /**< (offset 55)
|
||||||
Callback for cleaning up resources allocated
|
Callback for cleaning up resources allocated
|
||||||
@ -296,16 +300,27 @@ FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance);
|
|||||||
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
|
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
|
||||||
FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
|
FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount);
|
FREERDP_API void freerdp_channel_init_thread_context(rdpContext* context);
|
||||||
|
FREERDP_API freerdp* freerdp_channel_get_instance(void);
|
||||||
|
FREERDP_API rdpContext* freerdp_channel_get_context(void);
|
||||||
|
FREERDP_API rdpChannels* freerdp_channel_get_channels_context(void);
|
||||||
|
|
||||||
|
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount,
|
||||||
|
void** wfds, int* wcount);
|
||||||
FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
|
FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count);
|
FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events,
|
||||||
|
DWORD count);
|
||||||
FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context);
|
FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context);
|
||||||
|
|
||||||
FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id);
|
FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance,
|
||||||
FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id);
|
DWORD id);
|
||||||
FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message);
|
FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance,
|
||||||
FREERDP_API int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id);
|
DWORD id);
|
||||||
|
FREERDP_API int freerdp_message_queue_process_message(freerdp* instance,
|
||||||
|
DWORD id, wMessage* message);
|
||||||
|
FREERDP_API int freerdp_message_queue_process_pending_messages(
|
||||||
|
freerdp* instance, DWORD id);
|
||||||
|
|
||||||
FREERDP_API UINT32 freerdp_error_info(freerdp* instance);
|
FREERDP_API UINT32 freerdp_error_info(freerdp* instance);
|
||||||
FREERDP_API void freerdp_set_error_info(rdpRdp* rdp, UINT32 error);
|
FREERDP_API void freerdp_set_error_info(rdpRdp* rdp, UINT32 error);
|
||||||
@ -327,13 +342,15 @@ FREERDP_API const char* freerdp_get_last_error_name(UINT32 error);
|
|||||||
FREERDP_API const char* freerdp_get_last_error_string(UINT32 error);
|
FREERDP_API const char* freerdp_get_last_error_string(UINT32 error);
|
||||||
FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError);
|
FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError);
|
||||||
|
|
||||||
FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount);
|
FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context,
|
||||||
|
BOOL resetCount);
|
||||||
|
|
||||||
FREERDP_API void clearChannelError(rdpContext* context);
|
FREERDP_API void clearChannelError(rdpContext* context);
|
||||||
FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context);
|
FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context);
|
||||||
FREERDP_API UINT getChannelError(rdpContext* context);
|
FREERDP_API UINT getChannelError(rdpContext* context);
|
||||||
FREERDP_API const char* getChannelErrorDescription(rdpContext* context);
|
FREERDP_API const char* getChannelErrorDescription(rdpContext* context);
|
||||||
FREERDP_API void setChannelError(rdpContext* context, UINT errorNum, char* description);
|
FREERDP_API void setChannelError(rdpContext* context, UINT errorNum,
|
||||||
|
char* description);
|
||||||
FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context);
|
FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -31,18 +31,9 @@
|
|||||||
|
|
||||||
#define TAG FREERDP_TAG("core.client")
|
#define TAG FREERDP_TAG("core.client")
|
||||||
|
|
||||||
static void* g_pInterface = NULL;
|
static WINPR_TLS void* g_pInterface = NULL;
|
||||||
static CHANNEL_INIT_DATA g_ChannelInitData;
|
|
||||||
|
|
||||||
static wHashTable* g_OpenHandles = NULL;
|
static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(
|
||||||
|
|
||||||
/* To generate unique sequence for all open handles */
|
|
||||||
int g_open_handle_sequence = 1;
|
|
||||||
|
|
||||||
/* For locking the global resources */
|
|
||||||
static CRITICAL_SECTION g_channels_lock;
|
|
||||||
|
|
||||||
CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(
|
|
||||||
rdpChannels* channels, const char* name)
|
rdpChannels* channels, const char* name)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
@ -60,7 +51,7 @@ CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns rdpChannel for the channel name passed in */
|
/* returns rdpChannel for the channel name passed in */
|
||||||
rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp,
|
static rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp,
|
||||||
const char* name)
|
const char* name)
|
||||||
{
|
{
|
||||||
UINT32 index;
|
UINT32 index;
|
||||||
@ -80,7 +71,7 @@ rdpMcsChannel* freerdp_channels_find_channel_by_name(rdpRdp* rdp,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpChannels* freerdp_channels_new(void)
|
rdpChannels* freerdp_channels_new(freerdp* instance)
|
||||||
{
|
{
|
||||||
rdpChannels* channels;
|
rdpChannels* channels;
|
||||||
channels = (rdpChannels*) calloc(1, sizeof(rdpChannels));
|
channels = (rdpChannels*) calloc(1, sizeof(rdpChannels));
|
||||||
@ -88,40 +79,37 @@ rdpChannels* freerdp_channels_new(void)
|
|||||||
if (!channels)
|
if (!channels)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (!InitializeCriticalSectionAndSpinCount(&channels->channelsLock, 4000))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
channels->instance = instance;
|
||||||
|
channels->openHandleSeq = 1;
|
||||||
channels->queue = MessageQueue_New(NULL);
|
channels->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
if (!channels->queue)
|
if (!channels->queue)
|
||||||
goto error_queue;
|
goto error;
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
channels->openHandles = HashTable_New(TRUE);
|
||||||
{
|
|
||||||
g_OpenHandles = HashTable_New(TRUE);
|
|
||||||
|
|
||||||
if (!g_OpenHandles)
|
if (!channels->openHandles)
|
||||||
goto error_open_handles;
|
goto error;
|
||||||
|
|
||||||
if (!InitializeCriticalSectionAndSpinCount(&g_channels_lock, 4000))
|
|
||||||
goto error_open_handles;
|
|
||||||
}
|
|
||||||
|
|
||||||
return channels;
|
return channels;
|
||||||
error_open_handles:
|
error:
|
||||||
MessageQueue_Free(channels->queue);
|
freerdp_channels_free(channels);
|
||||||
error_queue:
|
|
||||||
free(channels);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freerdp_channels_free(rdpChannels* channels)
|
void freerdp_channels_free(rdpChannels* channels)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
int nkeys;
|
|
||||||
ULONG_PTR* pKeys = NULL;
|
|
||||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
|
|
||||||
if (!channels)
|
if (!channels)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
DeleteCriticalSection(&channels->channelsLock);
|
||||||
|
|
||||||
if (channels->queue)
|
if (channels->queue)
|
||||||
{
|
{
|
||||||
MessageQueue_Free(channels->queue);
|
MessageQueue_Free(channels->queue);
|
||||||
@ -138,22 +126,13 @@ void freerdp_channels_free(rdpChannels* channels)
|
|||||||
pChannelOpenData->pInterface = NULL;
|
pChannelOpenData->pInterface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashTable_Remove(g_OpenHandles, (void*)(UINT_PTR)pChannelOpenData->OpenHandle);
|
if (channels->openHandles)
|
||||||
|
HashTable_Remove(channels->openHandles,
|
||||||
|
(void*)(UINT_PTR)pChannelOpenData->OpenHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_OpenHandles)
|
if (channels->openHandles)
|
||||||
{
|
HashTable_Free(channels->openHandles);
|
||||||
nkeys = HashTable_GetKeys(g_OpenHandles, &pKeys);
|
|
||||||
|
|
||||||
if (nkeys == 0)
|
|
||||||
{
|
|
||||||
HashTable_Free(g_OpenHandles);
|
|
||||||
DeleteCriticalSection(&g_channels_lock);
|
|
||||||
g_OpenHandles = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(channels);
|
free(channels);
|
||||||
}
|
}
|
||||||
@ -163,7 +142,7 @@ void freerdp_channels_free(rdpChannels* channels)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context,
|
static UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context,
|
||||||
const char* name, void* pInterface)
|
const char* name, void* pInterface)
|
||||||
{
|
{
|
||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
@ -182,7 +161,8 @@ UINT freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context,
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context,
|
static UINT freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext*
|
||||||
|
context,
|
||||||
const char* name, void* pInterface)
|
const char* name, void* pInterface)
|
||||||
{
|
{
|
||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
@ -205,7 +185,6 @@ UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance)
|
|||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
int index;
|
int index;
|
||||||
CHANNEL_CLIENT_DATA* pChannelClientData;
|
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||||
channels->instance = instance;
|
|
||||||
|
|
||||||
for (index = 0; index < channels->clientDataCount; index++)
|
for (index = 0; index < channels->clientDataCount; index++)
|
||||||
{
|
{
|
||||||
@ -522,7 +501,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
|||||||
MessageQueue_PostQuit(channels->queue, 0);
|
MessageQueue_PostQuit(channels->queue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
static UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
||||||
PCHANNEL_DEF pChannel,
|
PCHANNEL_DEF pChannel,
|
||||||
INT channelCount, ULONG versionRequested,
|
INT channelCount, ULONG versionRequested,
|
||||||
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc)
|
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc)
|
||||||
@ -531,20 +510,19 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
|||||||
void* pInterface;
|
void* pInterface;
|
||||||
DWORD OpenHandle;
|
DWORD OpenHandle;
|
||||||
CHANNEL_DEF* channel;
|
CHANNEL_DEF* channel;
|
||||||
rdpChannels* channels;
|
rdpChannels* channels = freerdp_channel_get_channels_context();
|
||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
PCHANNEL_DEF pChannelDef;
|
PCHANNEL_DEF pChannelDef;
|
||||||
CHANNEL_INIT_DATA* pChannelInitData;
|
CHANNEL_INIT_DATA* pChannelInitData;
|
||||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
CHANNEL_CLIENT_DATA* pChannelClientData;
|
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||||
|
|
||||||
if (!ppInitHandle)
|
if (!ppInitHandle || !channels)
|
||||||
return CHANNEL_RC_BAD_INIT_HANDLE;
|
return CHANNEL_RC_BAD_INIT_HANDLE;
|
||||||
|
|
||||||
if (!pChannel || (channelCount <= 0) || !pChannelInitEventProc)
|
if (!pChannel || (channelCount <= 0) || !pChannelInitEventProc)
|
||||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||||
|
|
||||||
channels = g_ChannelInitData.channels;
|
|
||||||
pInterface = g_pInterface;
|
pInterface = g_pInterface;
|
||||||
pChannelInitData = &(channels->initDataList[channels->initDataCount]);
|
pChannelInitData = &(channels->initDataList[channels->initDataCount]);
|
||||||
*ppInitHandle = pChannelInitData;
|
*ppInitHandle = pChannelInitData;
|
||||||
@ -583,16 +561,16 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
|||||||
pChannelClientData->pChannelInitEventProc = pChannelInitEventProc;
|
pChannelClientData->pChannelInitEventProc = pChannelInitEventProc;
|
||||||
pChannelClientData->pInitHandle = *ppInitHandle;
|
pChannelClientData->pInitHandle = *ppInitHandle;
|
||||||
channels->clientDataCount++;
|
channels->clientDataCount++;
|
||||||
settings = channels->settings;
|
settings = channels->instance->context->settings;
|
||||||
|
|
||||||
for (index = 0; index < channelCount; index++)
|
for (index = 0; index < channelCount; index++)
|
||||||
{
|
{
|
||||||
pChannelDef = &pChannel[index];
|
pChannelDef = &pChannel[index];
|
||||||
pChannelOpenData = &channels->openDataList[channels->openDataCount];
|
pChannelOpenData = &channels->openDataList[channels->openDataCount];
|
||||||
OpenHandle = g_open_handle_sequence++;
|
OpenHandle = channels->openHandleSeq++;
|
||||||
pChannelOpenData->OpenHandle = OpenHandle;
|
pChannelOpenData->OpenHandle = OpenHandle;
|
||||||
pChannelOpenData->channels = channels;
|
pChannelOpenData->channels = channels;
|
||||||
HashTable_Add(g_OpenHandles, (void*)(UINT_PTR) OpenHandle,
|
HashTable_Add(channels->openHandles, (void*)(UINT_PTR) OpenHandle,
|
||||||
(void*) pChannelOpenData);
|
(void*) pChannelOpenData);
|
||||||
pChannelOpenData->flags = 1; /* init */
|
pChannelOpenData->flags = 1; /* init */
|
||||||
strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN);
|
strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN);
|
||||||
@ -603,7 +581,7 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
|||||||
channel = &settings->ChannelDefArray[settings->ChannelCount];
|
channel = &settings->ChannelDefArray[settings->ChannelCount];
|
||||||
strncpy(channel->name, pChannelDef->name, 7);
|
strncpy(channel->name, pChannelDef->name, 7);
|
||||||
channel->options = pChannelDef->options;
|
channel->options = pChannelDef->options;
|
||||||
channels->settings->ChannelCount++;
|
settings->ChannelCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
channels->openDataCount++;
|
channels->openDataCount++;
|
||||||
@ -612,7 +590,7 @@ UINT VCAPITYPE FreeRDP_VirtualChannelInit(LPVOID* ppInitHandle,
|
|||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
|
static UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
|
||||||
LPDWORD pOpenHandle,
|
LPDWORD pOpenHandle,
|
||||||
PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc)
|
PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc)
|
||||||
{
|
{
|
||||||
@ -649,10 +627,15 @@ UINT VCAPITYPE FreeRDP_VirtualChannelOpen(LPVOID pInitHandle,
|
|||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
|
static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
|
||||||
{
|
{
|
||||||
|
rdpChannels* channels = freerdp_channel_get_channels_context();
|
||||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
pChannelOpenData = HashTable_GetItemValue(g_OpenHandles,
|
|
||||||
|
if (!channels)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
pChannelOpenData = HashTable_GetItemValue(channels->openHandles,
|
||||||
(void*)(UINT_PTR) openHandle);
|
(void*)(UINT_PTR) openHandle);
|
||||||
|
|
||||||
if (!pChannelOpenData)
|
if (!pChannelOpenData)
|
||||||
@ -665,23 +648,23 @@ UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
|
|||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, LPVOID pData,
|
static UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle,
|
||||||
|
LPVOID pData,
|
||||||
ULONG dataLength, LPVOID pUserData)
|
ULONG dataLength, LPVOID pUserData)
|
||||||
{
|
{
|
||||||
rdpChannels* channels;
|
rdpChannels* channels = freerdp_channel_get_channels_context();
|
||||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
CHANNEL_OPEN_EVENT* pChannelOpenEvent;
|
CHANNEL_OPEN_EVENT* pChannelOpenEvent;
|
||||||
pChannelOpenData = HashTable_GetItemValue(g_OpenHandles,
|
|
||||||
|
if (!channels)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
pChannelOpenData = HashTable_GetItemValue(channels->openHandles,
|
||||||
(void*)(UINT_PTR) openHandle);
|
(void*)(UINT_PTR) openHandle);
|
||||||
|
|
||||||
if (!pChannelOpenData)
|
if (!pChannelOpenData)
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
channels = pChannelOpenData->channels;
|
|
||||||
|
|
||||||
if (!channels)
|
|
||||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
|
||||||
|
|
||||||
if (!channels->connected)
|
if (!channels->connected)
|
||||||
return CHANNEL_RC_NOT_CONNECTED;
|
return CHANNEL_RC_NOT_CONNECTED;
|
||||||
|
|
||||||
@ -764,14 +747,11 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings,
|
|||||||
EntryPoints.context = ((freerdp*)settings->instance)->context;
|
EntryPoints.context = ((freerdp*)settings->instance)->context;
|
||||||
/* enable VirtualChannelInit */
|
/* enable VirtualChannelInit */
|
||||||
channels->can_call_init = TRUE;
|
channels->can_call_init = TRUE;
|
||||||
channels->settings = settings;
|
EnterCriticalSection(&channels->channelsLock);
|
||||||
EnterCriticalSection(&g_channels_lock);
|
|
||||||
g_pInterface = NULL;
|
g_pInterface = NULL;
|
||||||
g_ChannelInitData.channels = channels;
|
|
||||||
status = pChannelClientData->entry((PCHANNEL_ENTRY_POINTS) &EntryPoints);
|
status = pChannelClientData->entry((PCHANNEL_ENTRY_POINTS) &EntryPoints);
|
||||||
LeaveCriticalSection(&g_channels_lock);
|
LeaveCriticalSection(&channels->channelsLock);
|
||||||
/* disable MyVirtualChannelInit */
|
/* disable MyVirtualChannelInit */
|
||||||
channels->settings = NULL;
|
|
||||||
channels->can_call_init = FALSE;
|
channels->can_call_init = FALSE;
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
|
@ -93,7 +93,6 @@ struct rdp_channels
|
|||||||
|
|
||||||
/* control for entry into MyVirtualChannelInit */
|
/* control for entry into MyVirtualChannelInit */
|
||||||
int can_call_init;
|
int can_call_init;
|
||||||
rdpSettings* settings;
|
|
||||||
|
|
||||||
/* true once freerdp_channels_post_connect is called */
|
/* true once freerdp_channels_post_connect is called */
|
||||||
BOOL connected;
|
BOOL connected;
|
||||||
@ -104,6 +103,9 @@ struct rdp_channels
|
|||||||
wMessageQueue* queue;
|
wMessageQueue* queue;
|
||||||
|
|
||||||
DrdynvcClientContext* drdynvc;
|
DrdynvcClientContext* drdynvc;
|
||||||
|
UINT64 openHandleSeq;
|
||||||
|
CRITICAL_SECTION channelsLock;
|
||||||
|
wHashTable* openHandles;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FREERDP_CORE_CLIENT_H */
|
#endif /* FREERDP_CORE_CLIENT_H */
|
||||||
|
@ -50,6 +50,37 @@
|
|||||||
|
|
||||||
/* connectErrorCode is 'extern' in error.h. See comment there.*/
|
/* connectErrorCode is 'extern' in error.h. See comment there.*/
|
||||||
|
|
||||||
|
/* Thread local storage variables.
|
||||||
|
* They need to be initialized in every thread that
|
||||||
|
* has to use them. */
|
||||||
|
static WINPR_TLS rdpContext* s_TLSContext = NULL;
|
||||||
|
|
||||||
|
void freerdp_channel_init_thread_context(rdpContext* context)
|
||||||
|
{
|
||||||
|
s_TLSContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
freerdp* freerdp_channel_get_instance(void)
|
||||||
|
{
|
||||||
|
if (!s_TLSContext)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return s_TLSContext->instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdpContext* freerdp_channel_get_context(void)
|
||||||
|
{
|
||||||
|
return s_TLSContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdpChannels* freerdp_channel_get_channels_context(void)
|
||||||
|
{
|
||||||
|
if (!s_TLSContext)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return s_TLSContext->channels;
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates a new connection based on the settings found in the "instance" parameter
|
/** Creates a new connection based on the settings found in the "instance" parameter
|
||||||
* It will use the callbacks registered on the structure to process the pre/post connect operations
|
* It will use the callbacks registered on the structure to process the pre/post connect operations
|
||||||
* that the caller requires.
|
* that the caller requires.
|
||||||
@ -68,15 +99,17 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
ConnectionResultEventArgs e;
|
ConnectionResultEventArgs e;
|
||||||
|
|
||||||
|
if (!instance)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
freerdp_channel_init_thread_context(instance->context);
|
||||||
/* We always set the return code to 0 before we start the connect sequence*/
|
/* We always set the return code to 0 before we start the connect sequence*/
|
||||||
connectErrorCode = 0;
|
connectErrorCode = 0;
|
||||||
freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);
|
||||||
clearChannelError(instance->context);
|
clearChannelError(instance->context);
|
||||||
ResetEvent(instance->context->abortEvent);
|
ResetEvent(instance->context->abortEvent);
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
|
|
||||||
instance->context->codecs = codecs_new(instance->context);
|
instance->context->codecs = codecs_new(instance->context);
|
||||||
IFCALLRET(instance->PreConnect, status, instance);
|
IFCALLRET(instance->PreConnect, status, instance);
|
||||||
|
|
||||||
@ -112,7 +145,9 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
{
|
{
|
||||||
if (instance->settings->DumpRemoteFx)
|
if (instance->settings->DumpRemoteFx)
|
||||||
{
|
{
|
||||||
instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE);
|
instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
if (instance->update->pcap_rfx)
|
if (instance->update->pcap_rfx)
|
||||||
instance->update->dump_rfx = TRUE;
|
instance->update->dump_rfx = TRUE;
|
||||||
}
|
}
|
||||||
@ -135,9 +170,7 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
wStream* s;
|
wStream* s;
|
||||||
rdpUpdate* update;
|
rdpUpdate* update;
|
||||||
pcap_record record;
|
pcap_record record;
|
||||||
|
|
||||||
update = instance->update;
|
update = instance->update;
|
||||||
|
|
||||||
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||||
|
|
||||||
if (!update->pcap_rfx)
|
if (!update->pcap_rfx)
|
||||||
@ -152,18 +185,15 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
|
|
||||||
while (pcap_has_next_record(update->pcap_rfx))
|
while (pcap_has_next_record(update->pcap_rfx))
|
||||||
{
|
{
|
||||||
|
|
||||||
pcap_get_next_record_header(update->pcap_rfx, &record);
|
pcap_get_next_record_header(update->pcap_rfx, &record);
|
||||||
|
|
||||||
if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length)))
|
if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
record.data = Stream_Buffer(s);
|
record.data = Stream_Buffer(s);
|
||||||
|
|
||||||
pcap_get_next_record_content(update->pcap_rfx, &record);
|
pcap_get_next_record_content(update->pcap_rfx, &record);
|
||||||
Stream_SetLength(s,record.length);
|
Stream_SetLength(s, record.length);
|
||||||
Stream_SetPosition(s, 0);
|
Stream_SetPosition(s, 0);
|
||||||
|
|
||||||
update->BeginPaint(update->context);
|
update->BeginPaint(update->context);
|
||||||
update_recv_surfcmds(update, Stream_Length(s) , s);
|
update_recv_surfcmds(update, Stream_Length(s) , s);
|
||||||
update->EndPaint(update->context);
|
update->EndPaint(update->context);
|
||||||
@ -178,14 +208,14 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
|
if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
|
||||||
freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
|
freerdp_set_last_error(instance->context,
|
||||||
|
FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
|
||||||
|
|
||||||
SetEvent(rdp->transport->connectedEvent);
|
SetEvent(rdp->transport->connectedEvent);
|
||||||
freerdp_connect_finally:
|
freerdp_connect_finally:
|
||||||
EventArgsInit(&e, "freerdp");
|
EventArgsInit(&e, "freerdp");
|
||||||
e.result = status ? 0 : -1;
|
e.result = status ? 0 : -1;
|
||||||
PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e);
|
PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +227,8 @@ BOOL freerdp_abort_connect(freerdp* instance)
|
|||||||
return SetEvent(instance->context->abortEvent);
|
return SetEvent(instance->context->abortEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
|
BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds,
|
||||||
|
int* wcount)
|
||||||
{
|
{
|
||||||
rdpRdp* rdp = instance->context->rdp;
|
rdpRdp* rdp = instance->context->rdp;
|
||||||
transport_get_fds(rdp->transport, rfds, rcount);
|
transport_get_fds(rdp->transport, rfds, rcount);
|
||||||
@ -219,29 +250,26 @@ BOOL freerdp_check_fds(freerdp* instance)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
|
|
||||||
status = rdp_check_fds(rdp);
|
status = rdp_check_fds(rdp);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
TerminateEventArgs e;
|
TerminateEventArgs e;
|
||||||
rdpContext* context = instance->context;
|
rdpContext* context = instance->context;
|
||||||
|
|
||||||
WLog_DBG(TAG, "rdp_check_fds() - %i", status);
|
WLog_DBG(TAG, "rdp_check_fds() - %i", status);
|
||||||
EventArgsInit(&e, "freerdp");
|
EventArgsInit(&e, "freerdp");
|
||||||
e.code = 0;
|
e.code = 0;
|
||||||
PubSub_OnTerminate(context->pubSub, context, &e);
|
PubSub_OnTerminate(context->pubSub, context, &e);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count)
|
DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events,
|
||||||
|
DWORD count)
|
||||||
{
|
{
|
||||||
DWORD nCount = 0;
|
DWORD nCount = 0;
|
||||||
|
|
||||||
nCount += transport_get_event_handles(context->rdp->transport, events, count);
|
nCount += transport_get_event_handles(context->rdp->transport, events, count);
|
||||||
|
|
||||||
if (nCount == 0)
|
if (nCount == 0)
|
||||||
@ -261,7 +289,6 @@ DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count
|
|||||||
BOOL freerdp_check_event_handles(rdpContext* context)
|
BOOL freerdp_check_event_handles(rdpContext* context)
|
||||||
{
|
{
|
||||||
BOOL status;
|
BOOL status;
|
||||||
|
|
||||||
status = freerdp_check_fds(context->instance);
|
status = freerdp_check_fds(context->instance);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
@ -271,6 +298,7 @@ BOOL freerdp_check_event_handles(rdpContext* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = freerdp_channels_check_fds(context->channels, context->instance);
|
status = freerdp_channels_check_fds(context->channels, context->instance);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "freerdp_channels_check_fds() failed - %i", status);
|
WLog_ERR(TAG, "freerdp_channels_check_fds() failed - %i", status);
|
||||||
@ -281,7 +309,6 @@ BOOL freerdp_check_event_handles(rdpContext* context)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
status = checkChannelErrorEvent(context);
|
status = checkChannelErrorEvent(context);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +334,6 @@ HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id)
|
|||||||
{
|
{
|
||||||
HANDLE event = NULL;
|
HANDLE event = NULL;
|
||||||
wMessageQueue* queue = NULL;
|
wMessageQueue* queue = NULL;
|
||||||
|
|
||||||
queue = freerdp_get_message_queue(instance, id);
|
queue = freerdp_get_message_queue(instance, id);
|
||||||
|
|
||||||
if (queue)
|
if (queue)
|
||||||
@ -316,7 +342,8 @@ HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id)
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message)
|
int freerdp_message_queue_process_message(freerdp* instance, DWORD id,
|
||||||
|
wMessage* message)
|
||||||
{
|
{
|
||||||
int status = -1;
|
int status = -1;
|
||||||
|
|
||||||
@ -352,7 +379,8 @@ int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size)
|
static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId,
|
||||||
|
BYTE* data, int size)
|
||||||
{
|
{
|
||||||
return rdp_send_channel_data(instance->context->rdp, channelId, data, size);
|
return rdp_send_channel_data(instance->context->rdp, channelId, data, size);
|
||||||
}
|
}
|
||||||
@ -360,12 +388,9 @@ static int freerdp_send_channel_data(freerdp* instance, UINT16 channelId, BYTE*
|
|||||||
BOOL freerdp_disconnect(freerdp* instance)
|
BOOL freerdp_disconnect(freerdp* instance)
|
||||||
{
|
{
|
||||||
rdpRdp* rdp;
|
rdpRdp* rdp;
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
|
|
||||||
rdp_client_disconnect(rdp);
|
rdp_client_disconnect(rdp);
|
||||||
update_post_disconnect(instance->update);
|
update_post_disconnect(instance->update);
|
||||||
|
|
||||||
IFCALL(instance->PostDisconnect, instance);
|
IFCALL(instance->PostDisconnect, instance);
|
||||||
|
|
||||||
if (instance->update->pcap_rfx)
|
if (instance->update->pcap_rfx)
|
||||||
@ -383,10 +408,8 @@ BOOL freerdp_reconnect(freerdp* instance)
|
|||||||
{
|
{
|
||||||
BOOL status;
|
BOOL status;
|
||||||
rdpRdp* rdp = instance->context->rdp;
|
rdpRdp* rdp = instance->context->rdp;
|
||||||
|
|
||||||
ResetEvent(instance->context->abortEvent);
|
ResetEvent(instance->context->abortEvent);
|
||||||
status = rdp_client_reconnect(rdp);
|
status = rdp_client_reconnect(rdp);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,8 +417,10 @@ BOOL freerdp_shall_disconnect(freerdp* instance)
|
|||||||
{
|
{
|
||||||
if (!instance || !instance->context)
|
if (!instance || !instance->context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (WaitForSingleObject(instance->context->abortEvent, 0) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(instance->context->abortEvent, 0) != WAIT_OBJECT_0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +428,6 @@ BOOL freerdp_focus_required(freerdp* instance)
|
|||||||
{
|
{
|
||||||
rdpRdp* rdp;
|
rdpRdp* rdp;
|
||||||
BOOL bRetCode = FALSE;
|
BOOL bRetCode = FALSE;
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
|
|
||||||
if (rdp->resendFocus)
|
if (rdp->resendFocus)
|
||||||
@ -418,7 +442,6 @@ BOOL freerdp_focus_required(freerdp* instance)
|
|||||||
void freerdp_set_focus(freerdp* instance)
|
void freerdp_set_focus(freerdp* instance)
|
||||||
{
|
{
|
||||||
rdpRdp* rdp;
|
rdpRdp* rdp;
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
rdp->resendFocus = TRUE;
|
rdp->resendFocus = TRUE;
|
||||||
}
|
}
|
||||||
@ -443,19 +466,17 @@ const char* freerdp_get_version_string(void)
|
|||||||
const char* freerdp_get_build_date(void)
|
const char* freerdp_get_build_date(void)
|
||||||
{
|
{
|
||||||
static char build_date[] = __DATE__ " " __TIME__;
|
static char build_date[] = __DATE__ " " __TIME__;
|
||||||
|
|
||||||
return build_date;
|
return build_date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* freerdp_get_build_config(void)
|
const char* freerdp_get_build_config(void)
|
||||||
{
|
{
|
||||||
static const char build_config[] =
|
static const char build_config[] =
|
||||||
"Build configuration: " BUILD_CONFIG "\n"
|
"Build configuration: " BUILD_CONFIG "\n"
|
||||||
"Build type: " BUILD_TYPE "\n"
|
"Build type: " BUILD_TYPE "\n"
|
||||||
"CFLAGS: " CFLAGS "\n"
|
"CFLAGS: " CFLAGS "\n"
|
||||||
"Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n"
|
"Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n"
|
||||||
"Target architecture: " TARGET_ARCH "\n";
|
"Target architecture: " TARGET_ARCH "\n";
|
||||||
|
|
||||||
return build_config;
|
return build_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,27 +514,29 @@ BOOL freerdp_context_new(freerdp* instance)
|
|||||||
rdpRdp* rdp;
|
rdpRdp* rdp;
|
||||||
rdpContext* context;
|
rdpContext* context;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
instance->context = (rdpContext*) calloc(1, instance->ContextSize);
|
instance->context = (rdpContext*) calloc(1, instance->ContextSize);
|
||||||
|
|
||||||
if (!instance->context)
|
if (!instance->context)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
context = instance->context;
|
context = instance->context;
|
||||||
context->instance = instance;
|
context->instance = instance;
|
||||||
|
|
||||||
context->ServerMode = FALSE;
|
context->ServerMode = FALSE;
|
||||||
context->settings = instance->settings;
|
context->settings = instance->settings;
|
||||||
|
|
||||||
context->pubSub = PubSub_New(TRUE);
|
context->pubSub = PubSub_New(TRUE);
|
||||||
if(!context->pubSub)
|
|
||||||
goto out_error_pubsub;
|
|
||||||
PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEventType));
|
|
||||||
|
|
||||||
|
if (!context->pubSub)
|
||||||
|
goto out_error_pubsub;
|
||||||
|
|
||||||
|
PubSub_AddEventTypes(context->pubSub, FreeRDP_Events,
|
||||||
|
sizeof(FreeRDP_Events) / sizeof(wEventType));
|
||||||
context->metrics = metrics_new(context);
|
context->metrics = metrics_new(context);
|
||||||
|
|
||||||
if (!context->metrics)
|
if (!context->metrics)
|
||||||
goto out_error_metrics_new;
|
goto out_error_metrics_new;
|
||||||
|
|
||||||
rdp = rdp_new(context);
|
rdp = rdp_new(context);
|
||||||
|
|
||||||
if (!rdp)
|
if (!rdp)
|
||||||
goto out_error_rdp_new;
|
goto out_error_rdp_new;
|
||||||
|
|
||||||
@ -521,26 +544,22 @@ BOOL freerdp_context_new(freerdp* instance)
|
|||||||
instance->update = rdp->update;
|
instance->update = rdp->update;
|
||||||
instance->settings = rdp->settings;
|
instance->settings = rdp->settings;
|
||||||
instance->autodetect = rdp->autodetect;
|
instance->autodetect = rdp->autodetect;
|
||||||
|
|
||||||
context->graphics = graphics_new(context);
|
context->graphics = graphics_new(context);
|
||||||
if(!context->graphics)
|
|
||||||
|
if (!context->graphics)
|
||||||
goto out_error_graphics_new;
|
goto out_error_graphics_new;
|
||||||
|
|
||||||
context->rdp = rdp;
|
context->rdp = rdp;
|
||||||
|
|
||||||
context->input = instance->input;
|
context->input = instance->input;
|
||||||
context->update = instance->update;
|
context->update = instance->update;
|
||||||
context->settings = instance->settings;
|
context->settings = instance->settings;
|
||||||
context->autodetect = instance->autodetect;
|
context->autodetect = instance->autodetect;
|
||||||
|
|
||||||
instance->update->context = instance->context;
|
instance->update->context = instance->context;
|
||||||
instance->update->pointer->context = instance->context;
|
instance->update->pointer->context = instance->context;
|
||||||
instance->update->primary->context = instance->context;
|
instance->update->primary->context = instance->context;
|
||||||
instance->update->secondary->context = instance->context;
|
instance->update->secondary->context = instance->context;
|
||||||
instance->update->altsec->context = instance->context;
|
instance->update->altsec->context = instance->context;
|
||||||
|
|
||||||
instance->input->context = context;
|
instance->input->context = context;
|
||||||
|
|
||||||
instance->autodetect->context = context;
|
instance->autodetect->context = context;
|
||||||
|
|
||||||
if (!(context->errorDescription = calloc(1, 500)))
|
if (!(context->errorDescription = calloc(1, 500)))
|
||||||
@ -556,8 +575,8 @@ BOOL freerdp_context_new(freerdp* instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_register_client_callbacks(rdp->update);
|
update_register_client_callbacks(rdp->update);
|
||||||
|
|
||||||
instance->context->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
instance->context->abortEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
if (!instance->context->abortEvent)
|
if (!instance->context->abortEvent)
|
||||||
goto out_error_abort_event;
|
goto out_error_abort_event;
|
||||||
|
|
||||||
@ -601,26 +620,18 @@ void freerdp_context_free(freerdp* instance)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
IFCALL(instance->ContextFree, instance, instance->context);
|
IFCALL(instance->ContextFree, instance, instance->context);
|
||||||
|
|
||||||
rdp_free(instance->context->rdp);
|
rdp_free(instance->context->rdp);
|
||||||
instance->context->rdp = NULL;
|
instance->context->rdp = NULL;
|
||||||
|
|
||||||
graphics_free(instance->context->graphics);
|
graphics_free(instance->context->graphics);
|
||||||
instance->context->graphics = NULL;
|
instance->context->graphics = NULL;
|
||||||
|
|
||||||
PubSub_Free(instance->context->pubSub);
|
PubSub_Free(instance->context->pubSub);
|
||||||
|
|
||||||
metrics_free(instance->context->metrics);
|
metrics_free(instance->context->metrics);
|
||||||
|
|
||||||
CloseHandle(instance->context->channelErrorEvent);
|
CloseHandle(instance->context->channelErrorEvent);
|
||||||
free(instance->context->errorDescription);
|
free(instance->context->errorDescription);
|
||||||
|
|
||||||
CloseHandle(instance->context->abortEvent);
|
CloseHandle(instance->context->abortEvent);
|
||||||
instance->context->abortEvent = NULL;
|
instance->context->abortEvent = NULL;
|
||||||
|
|
||||||
free(instance->context);
|
free(instance->context);
|
||||||
instance->context = NULL;
|
instance->context = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 freerdp_error_info(freerdp* instance)
|
UINT32 freerdp_error_info(freerdp* instance)
|
||||||
@ -643,21 +654,24 @@ UINT32 freerdp_get_last_error(rdpContext* context)
|
|||||||
|
|
||||||
const char* freerdp_get_last_error_name(UINT32 code)
|
const char* freerdp_get_last_error_name(UINT32 code)
|
||||||
{
|
{
|
||||||
const char *name = NULL;
|
const char* name = NULL;
|
||||||
const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
|
const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
|
||||||
const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
|
const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
|
||||||
|
|
||||||
switch(cls)
|
switch (cls)
|
||||||
{
|
{
|
||||||
case FREERDP_ERROR_ERRBASE_CLASS:
|
case FREERDP_ERROR_ERRBASE_CLASS:
|
||||||
name = freerdp_get_error_base_name(type);
|
name = freerdp_get_error_base_name(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FREERDP_ERROR_ERRINFO_CLASS:
|
case FREERDP_ERROR_ERRINFO_CLASS:
|
||||||
name = freerdp_get_error_info_name(type);
|
name = freerdp_get_error_info_name(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FREERDP_ERROR_CONNECT_CLASS:
|
case FREERDP_ERROR_CONNECT_CLASS:
|
||||||
name = freerdp_get_error_connect_name(type);
|
name = freerdp_get_error_connect_name(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
name = "Unknown error class";
|
name = "Unknown error class";
|
||||||
break;
|
break;
|
||||||
@ -672,17 +686,20 @@ const char* freerdp_get_last_error_string(UINT32 code)
|
|||||||
const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
|
const UINT32 cls = GET_FREERDP_ERROR_CLASS(code);
|
||||||
const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
|
const UINT32 type = GET_FREERDP_ERROR_TYPE(code);
|
||||||
|
|
||||||
switch(cls)
|
switch (cls)
|
||||||
{
|
{
|
||||||
case FREERDP_ERROR_ERRBASE_CLASS:
|
case FREERDP_ERROR_ERRBASE_CLASS:
|
||||||
string = freerdp_get_error_base_string(type);
|
string = freerdp_get_error_base_string(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FREERDP_ERROR_ERRINFO_CLASS:
|
case FREERDP_ERROR_ERRINFO_CLASS:
|
||||||
string = freerdp_get_error_info_string(type);
|
string = freerdp_get_error_info_string(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FREERDP_ERROR_CONNECT_CLASS:
|
case FREERDP_ERROR_CONNECT_CLASS:
|
||||||
string = freerdp_get_error_connect_string(type);
|
string = freerdp_get_error_connect_string(type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
string = "Unknown error class";
|
string = "Unknown error class";
|
||||||
break;
|
break;
|
||||||
@ -695,7 +712,7 @@ void freerdp_set_last_error(rdpContext* context, UINT32 lastError)
|
|||||||
{
|
{
|
||||||
if (lastError)
|
if (lastError)
|
||||||
WLog_ERR(TAG, "freerdp_set_last_error %s [0x%04X]",
|
WLog_ERR(TAG, "freerdp_set_last_error %s [0x%04X]",
|
||||||
freerdp_get_last_error_name(lastError), lastError);
|
freerdp_get_last_error_name(lastError), lastError);
|
||||||
|
|
||||||
context->LastError = lastError;
|
context->LastError = lastError;
|
||||||
|
|
||||||
@ -761,7 +778,6 @@ void freerdp_set_last_error(rdpContext* context, UINT32 lastError)
|
|||||||
freerdp* freerdp_new()
|
freerdp* freerdp_new()
|
||||||
{
|
{
|
||||||
freerdp* instance;
|
freerdp* instance;
|
||||||
|
|
||||||
instance = (freerdp*) calloc(1, sizeof(freerdp));
|
instance = (freerdp*) calloc(1, sizeof(freerdp));
|
||||||
|
|
||||||
if (!instance)
|
if (!instance)
|
||||||
@ -770,7 +786,6 @@ freerdp* freerdp_new()
|
|||||||
instance->ContextSize = sizeof(rdpContext);
|
instance->ContextSize = sizeof(rdpContext);
|
||||||
instance->SendChannelData = freerdp_send_channel_data;
|
instance->SendChannelData = freerdp_send_channel_data;
|
||||||
instance->ReceiveChannelData = freerdp_channels_data;
|
instance->ReceiveChannelData = freerdp_channels_data;
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,10 +798,13 @@ void freerdp_free(freerdp* instance)
|
|||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount) {
|
ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount)
|
||||||
|
{
|
||||||
ULONG written = context->rdp->transport->written;
|
ULONG written = context->rdp->transport->written;
|
||||||
|
|
||||||
if (resetCount)
|
if (resetCount)
|
||||||
context->rdp->transport->written = 0;
|
context->rdp->transport->written = 0;
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,11 +815,13 @@ HANDLE getChannelErrorEventHandle(rdpContext* context)
|
|||||||
|
|
||||||
BOOL checkChannelErrorEvent(rdpContext* context)
|
BOOL checkChannelErrorEvent(rdpContext* context)
|
||||||
{
|
{
|
||||||
if (WaitForSingleObject( context->channelErrorEvent, 0) == WAIT_OBJECT_0)
|
if (WaitForSingleObject(context->channelErrorEvent, 0) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s. Error was %lu", context->errorDescription, context->channelErrorNum);
|
WLog_ERR(TAG, "%s. Error was %lu", context->errorDescription,
|
||||||
|
context->channelErrorNum);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,26 +20,38 @@
|
|||||||
#define WINPR_H
|
#define WINPR_H
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
#ifdef WINPR_EXPORTS
|
#ifdef WINPR_EXPORTS
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define WINPR_API __attribute__((dllexport))
|
#define WINPR_API __attribute__((dllexport))
|
||||||
#else
|
|
||||||
#define WINPR_API __declspec(dllexport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define WINPR_API __attribute__((dllimport))
|
|
||||||
#else
|
|
||||||
#define WINPR_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#if __GNUC__ >= 4
|
#define WINPR_API __declspec(dllexport)
|
||||||
#define WINPR_API __attribute__ ((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define WINPR_API
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define WINPR_API __attribute__((dllimport))
|
||||||
|
#else
|
||||||
|
#define WINPR_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define WINPR_API __attribute__ ((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define WINPR_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Thread local storage keyword define */
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define WINPR_TLS __thread
|
||||||
|
#else
|
||||||
|
#define WINPR_TLS __declspec(thread)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define WINPR_TLS __thread
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define INLINE __inline
|
#define INLINE __inline
|
||||||
|
Loading…
Reference in New Issue
Block a user