rdpdr: add device list announce.

This commit is contained in:
Vic Lee 2011-08-05 22:44:06 +08:00
parent 667d78206d
commit 9faf581341
3 changed files with 105 additions and 7 deletions

View File

@ -32,13 +32,6 @@
#include "rdpdr_types.h"
#include "devman.h"
struct _DEVMAN
{
rdpSvcPlugin* plugin;
uint32 id_sequence; /* generate unique device id */
LIST* devices;
};
DEVMAN* devman_new(rdpSvcPlugin* plugin)
{
DEVMAN* devman;

View File

@ -113,6 +113,100 @@ static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);
}
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, STREAM* data_in)
{
uint16 versionMajor;
uint16 versionMinor;
uint32 clientID;
stream_read_uint16(data_in, versionMajor);
stream_read_uint16(data_in, versionMinor);
stream_read_uint32(data_in, clientID);
if (versionMajor != rdpdr->versionMajor || versionMinor != rdpdr->versionMinor)
{
DEBUG_WARN("unmatched version %d.%d", versionMajor, versionMinor);
rdpdr->versionMajor = versionMajor;
rdpdr->versionMinor = versionMinor;
}
if (clientID != rdpdr->clientID)
{
DEBUG_WARN("unmatched clientID %d", clientID);
rdpdr->clientID = clientID;
}
}
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean user_loggedon)
{
STREAM* data_out;
DEVICE* device;
LIST_ITEM* item;
uint32 count;
uint8 c;
int data_len;
int i;
int count_pos;
int pos;
data_out = stream_new(256);
stream_write_uint16(data_out, RDPDR_CTYP_CORE);
stream_write_uint16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE);
count_pos = stream_get_pos(data_out);
count = 0;
stream_seek_uint32(out_data); /* deviceCount */
for (item = rdpdr->devman->devices->head; item; item = item->next)
{
device = (DEVICE*)item->data;
/**
* 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON
* so all devices should be sent regardless of user_loggedon
* 2. smartcard devices should be always sent
* 3. other devices are sent only after user_loggedon
*/
if (rdpdr->versionMinor == 0x0005 ||
device->type == RDPDR_DTYP_SMARTCARD ||
user_loggedon)
{
data_len = stream_get_length(device->data);
stream_check_size(data_out, 20 + data_len);
stream_write_uint32(data_out, device->type); /* deviceType */
stream_write_uint32(data_out, device->id); /* deviceID */
strncpy(stream_get_tail(data_out), device->name, 8);
for (i = 0; i < 8; i++)
{
stream_peek_uint8(data_out, c);
if (c > 0x7F)
stream_write_uint8(data_out, '_');
else
streak_seek_uint8(data_out);
}
stream_write_uint32(data_out, data_len);
if (data_len > 0)
stream_write(data_out, stream_get_data(device->data), data_len);
count++;
printf("registered device #%d: %s (type=%d id=%d)\n",
count, device->name, device->type, device->id);
}
}
pos = stream_get_pos(data_out);
stream_set_pos(data_out, count_pos);
stream_write_uint32(data_out, count);
stream_set_pos(data_out, pos);
stream_seal(data_out);
svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);
}
static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
rdpdrPlugin* rdpdr = (rdpdrPlugin*)plugin;
@ -143,10 +237,13 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
case PAKID_CORE_CLIENTID_CONFIRM:
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_CLIENTID_CONFIRM");
rdpdr_process_server_clientid_confirm(rdpdr, data_in);
rdpdr_send_device_list_announce_request(rdpdr, False);
break;
case PAKID_CORE_USER_LOGGEDON:
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_USER_LOGGEDON");
rdpdr_send_device_list_announce_request(rdpdr, True);
break;
case PAKID_CORE_DEVICE_REPLY:

View File

@ -23,6 +23,7 @@
#include "config.h"
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
typedef struct _DEVICE DEVICE;
typedef struct _IRP IRP;
@ -65,6 +66,13 @@ struct _IRP
pcIRPResponse Discard;
};
struct _DEVMAN
{
rdpSvcPlugin* plugin;
uint32 id_sequence; /* generate unique device id */
LIST* devices;
};
typedef void (*pcRegisterDevice)(DEVMAN* devman, DEVICE* device);
struct _DEVICE_SERVICE_ENTRY_POINTS