Merge pull request #3079 from akallabeth/drive_hotplug_fix
Fixed argument checks for drive channel.
This commit is contained in:
commit
13df05be78
@ -6,6 +6,7 @@
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -42,6 +43,9 @@
|
||||
|
||||
void devman_device_free(DEVICE* device)
|
||||
{
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
IFCALL(device->Free, device);
|
||||
}
|
||||
|
||||
@ -49,6 +53,9 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
DEVMAN* devman;
|
||||
|
||||
if (!rdpdr)
|
||||
return NULL;
|
||||
|
||||
devman = (DEVMAN*) calloc(1, sizeof(DEVMAN));
|
||||
|
||||
if (!devman)
|
||||
@ -84,6 +91,9 @@ void devman_unregister_device(DEVMAN* devman, void* key)
|
||||
{
|
||||
DEVICE* device;
|
||||
|
||||
if (!devman || !key)
|
||||
return;
|
||||
|
||||
device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
|
||||
|
||||
if (device)
|
||||
@ -99,6 +109,12 @@ static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
|
||||
{
|
||||
void* key = NULL;
|
||||
|
||||
if (!devman || !device)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (device->type != RDPDR_DTYP_FILESYSTEM)
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
device->id = devman->id_sequence++;
|
||||
key = (void*) (size_t) device->id;
|
||||
|
||||
@ -115,6 +131,9 @@ DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
|
||||
DEVICE* device = NULL;
|
||||
void* key = (void*) (size_t) id;
|
||||
|
||||
if (!devman)
|
||||
return NULL;
|
||||
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);
|
||||
|
||||
return device;
|
||||
@ -137,6 +156,9 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext
|
||||
DEVICE_SERVICE_ENTRY_POINTS ep;
|
||||
PDEVICE_SERVICE_ENTRY entry = NULL;
|
||||
|
||||
if (!devman || !device || !rdpcontext)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (device->Type == RDPDR_DTYP_FILESYSTEM)
|
||||
ServiceName = DRIVE_SERVICE_NAME;
|
||||
else if (device->Type == RDPDR_DTYP_PRINT)
|
||||
|
@ -77,18 +77,28 @@ static UINT irp_complete(IRP* irp)
|
||||
return error;
|
||||
}
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
{
|
||||
IRP* irp;
|
||||
DEVICE* device;
|
||||
UINT32 DeviceId;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
{
|
||||
if (error)
|
||||
*error = ERROR_INVALID_DATA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
|
||||
device = devman_get_device_by_id(devman, DeviceId);
|
||||
|
||||
if (!device)
|
||||
{
|
||||
WLog_ERR(TAG, "devman_get_device_by_id failed!");
|
||||
WLog_WARN(TAG, "devman_get_device_by_id failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_OK;
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
@ -97,6 +107,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "_aligned_malloc failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -117,6 +129,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
_aligned_free(irp);
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||
@ -131,5 +145,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
irp->thread = NULL;
|
||||
irp->cancelled = FALSE;
|
||||
|
||||
if (error)
|
||||
*error = CHANNEL_RC_OK;
|
||||
|
||||
return irp;
|
||||
}
|
||||
|
@ -23,6 +23,6 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s);
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */
|
||||
|
@ -4,8 +4,9 @@
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015-2016 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -60,12 +61,21 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process device direction general capability set */
|
||||
static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output printer direction capability set */
|
||||
@ -75,12 +85,21 @@ static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process printer direction capability set */
|
||||
static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output port redirection capability set */
|
||||
@ -90,12 +109,21 @@ static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process port redirection capability set */
|
||||
static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output drive redirection capability set */
|
||||
@ -105,12 +133,21 @@ static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process drive redirection capability set */
|
||||
static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output smart card redirection capability set */
|
||||
@ -120,53 +157,77 @@ static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process smartcard redirection capability set */
|
||||
static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT status = CHANNEL_RC_OK;
|
||||
UINT16 i;
|
||||
UINT16 numCapabilities;
|
||||
UINT16 capabilityType;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, numCapabilities);
|
||||
Stream_Seek(s, 2); /* pad (2 bytes) */
|
||||
|
||||
for (i = 0; i < numCapabilities; i++)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < sizeof(UINT16))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityType);
|
||||
|
||||
switch (capabilityType)
|
||||
{
|
||||
case CAP_GENERAL_TYPE:
|
||||
rdpdr_process_general_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_GENERAL_TYPE:
|
||||
status = rdpdr_process_general_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_PRINTER_TYPE:
|
||||
rdpdr_process_printer_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_PRINTER_TYPE:
|
||||
status = rdpdr_process_printer_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_PORT_TYPE:
|
||||
rdpdr_process_port_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_PORT_TYPE:
|
||||
status = rdpdr_process_port_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_DRIVE_TYPE:
|
||||
rdpdr_process_drive_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_DRIVE_TYPE:
|
||||
status = rdpdr_process_drive_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_SMARTCARD_TYPE:
|
||||
rdpdr_process_smartcard_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_SMARTCARD_TYPE:
|
||||
status = rdpdr_process_smartcard_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
|
||||
UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
|
||||
UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */
|
||||
|
@ -4,8 +4,9 @@
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015-2016 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -81,7 +82,7 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou
|
||||
UINT32 i;
|
||||
wStream* s;
|
||||
|
||||
s = Stream_New(NULL, 256);
|
||||
s = Stream_New(NULL, count * sizeof(UINT32) + 8);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
@ -429,7 +430,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
BOOL dev_found = FALSE;
|
||||
|
||||
device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
|
||||
if (!device_ext)
|
||||
if (!device_ext || !device_ext->path)
|
||||
continue;
|
||||
|
||||
/* not plugable device */
|
||||
@ -496,7 +497,6 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
free(drive->Path);
|
||||
free(drive->Name);
|
||||
free(drive);
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@ -517,15 +517,15 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
UINT error;
|
||||
DWORD status;
|
||||
DWORD status;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) arg;
|
||||
|
||||
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateEvent failed!");
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mfd = open("/proc/mounts", O_RDONLY, 0);
|
||||
@ -533,8 +533,8 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if (mfd < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "ERROR: Unable to open /proc/mounts.");
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
@ -545,18 +545,18 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((rv = select(mfd+1, NULL, NULL, &rfds, &tv)) >= 0)
|
||||
{
|
||||
status = WaitForSingleObject(rdpdr->stopEvent, 0);
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
goto out;
|
||||
}
|
||||
status = WaitForSingleObject(rdpdr->stopEvent, 0);
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
goto out;
|
||||
}
|
||||
if (status == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
@ -566,7 +566,7 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,11 +577,11 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
}
|
||||
|
||||
out:
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "drive_hotplug_thread_func reported an error");
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "drive_hotplug_thread_func reported an error");
|
||||
|
||||
ExitThread((DWORD)error);
|
||||
return NULL;
|
||||
ExitThread((DWORD)error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,21 +591,22 @@ out:
|
||||
*/
|
||||
static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
UINT error;
|
||||
UINT error;
|
||||
|
||||
if (rdpdr->hotplugThread)
|
||||
{
|
||||
if (rdpdr->stopEvent)
|
||||
SetEvent(rdpdr->stopEvent);
|
||||
|
||||
if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
rdpdr->hotplugThread = NULL;
|
||||
}
|
||||
return CHANNEL_RC_OK;
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -661,13 +662,18 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
return error;
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, rdpdr->versionMajor);
|
||||
Stream_Read_UINT16(s, rdpdr->versionMinor);
|
||||
Stream_Read_UINT32(s, rdpdr->clientID);
|
||||
|
||||
rdpdr->sequenceId++;
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -683,7 +689,7 @@ static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return CHANNEL_RC_OK;
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||
@ -733,12 +739,15 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
return rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 versionMajor;
|
||||
UINT16 versionMinor;
|
||||
UINT32 clientID;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, versionMajor);
|
||||
Stream_Read_UINT16(s, versionMinor);
|
||||
Stream_Read_UINT32(s, clientID);
|
||||
@ -750,9 +759,9 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s
|
||||
}
|
||||
|
||||
if (clientID != rdpdr->clientID)
|
||||
{
|
||||
rdpdr->clientID = clientID;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -804,13 +813,13 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
*/
|
||||
|
||||
if ((rdpdr->versionMinor == 0x0005) ||
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
{
|
||||
data_len = (int) (device->data == NULL ? 0 : Stream_GetPosition(device->data));
|
||||
if (!Stream_EnsureRemainingCapacity(s, 20 + data_len))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, device->type); /* deviceType */
|
||||
@ -859,20 +868,20 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||
IRP* irp;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
irp = irp_new(rdpdr->devman, s);
|
||||
irp = irp_new(rdpdr->devman, s, &error);
|
||||
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "irp_new failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
WLog_ERR(TAG, "irp_new failed with %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
IFCALLRET(irp->device->IRPRequest, error, irp->device, irp);
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "device->IRPRequest failed with error %lu", error);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "device->IRPRequest failed with error %lu", error);
|
||||
|
||||
return error;
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -921,6 +930,12 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT32 status;
|
||||
UINT error;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
|
||||
Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */
|
||||
|
||||
@ -928,70 +943,77 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
rdpdr_process_server_announce_request(rdpdr, s);
|
||||
if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
||||
return error;
|
||||
if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
rdpdr_process_capability_request(rdpdr, s);
|
||||
if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
if ((error = rdpdr_process_capability_request(rdpdr, s)))
|
||||
return error;
|
||||
if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
rdpdr_process_server_clientid_confirm(rdpdr, s);
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
||||
return error;
|
||||
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
/* connect to a specific resource */
|
||||
Stream_Read_UINT32(s, deviceId);
|
||||
Stream_Read_UINT32(s, status);
|
||||
break;
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId);
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
/* connect to a specific resource */
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
break;
|
||||
|
||||
Stream_Read_UINT32(s, deviceId);
|
||||
Stream_Read_UINT32(s, status);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@ -999,21 +1021,24 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_PRN_CACHE_DATA:
|
||||
{
|
||||
UINT32 eventID;
|
||||
Stream_Read_UINT32(s, eventID);
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_PRN_USING_XPS:
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS");
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId);
|
||||
case PAKID_PRN_CACHE_DATA:
|
||||
{
|
||||
UINT32 eventID;
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT32(s, eventID);
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_PRN_USING_XPS:
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS");
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1132,14 +1157,15 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT status;
|
||||
rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (!plugin)
|
||||
{
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
@ -1158,7 +1184,7 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
wStream* data_in;
|
||||
|
||||
@ -1190,7 +1216,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
Stream_Write(data_in, pData, dataLength);
|
||||
|
||||
@ -1216,14 +1242,14 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
}
|
||||
|
||||
static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT event,
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle);
|
||||
|
||||
if (!rdpdr)
|
||||
if (!rdpdr || !pData)
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match");
|
||||
return;
|
||||
@ -1231,17 +1257,17 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT ev
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received failed with error %lu!", error );
|
||||
break;
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received failed with error %lu!", error );
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
}
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_open_event reported an error");
|
||||
@ -1256,6 +1282,12 @@ static void* rdpdr_virtual_channel_client_thread(void* arg)
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg;
|
||||
UINT error;
|
||||
|
||||
if (!rdpdr)
|
||||
{
|
||||
ExitThread((DWORD) CHANNEL_RC_NULL_DATA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((error = rdpdr_process_connect(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error);
|
||||
@ -1305,16 +1337,16 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
UINT error;
|
||||
|
||||
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);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||
WTSErrorToString(status), status);
|
||||
return status;
|
||||
}
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||
WTSErrorToString(status), status);
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr)))
|
||||
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;
|
||||
@ -1346,11 +1378,11 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
UINT error;
|
||||
|
||||
if (MessageQueue_PostQuit(rdpdr->queue, 0) && (WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED))
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
MessageQueue_Free(rdpdr->queue);
|
||||
CloseHandle(rdpdr->thread);
|
||||
@ -1359,10 +1391,10 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
rdpdr->thread = NULL;
|
||||
|
||||
if ((error = drive_hotplug_thread_terminate(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle);
|
||||
if (CHANNEL_RC_OK != error)
|
||||
@ -1409,25 +1441,25 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_INITIALIZED:
|
||||
break;
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %lu!", error);
|
||||
break;
|
||||
case CHANNEL_EVENT_INITIALIZED:
|
||||
break;
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %lu!", error);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %lu!", error);
|
||||
break;
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %lu!", error);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown event %d!", event);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown event %d!", event);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error && rdpdr->rdpcontext)
|
||||
@ -1444,7 +1476,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
rdpdrPlugin* rdpdr;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
|
||||
rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin));
|
||||
|
||||
if (!rdpdr)
|
||||
@ -1473,7 +1504,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||
|
||||
|
||||
rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,
|
||||
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user