mirror of https://github.com/FreeRDP/FreeRDP
Added callback to handle printer custom components in printer backend.
This commit is contained in:
parent
4dac07667c
commit
192680a001
|
@ -293,6 +293,44 @@ static UINT printer_irp_request(DEVICE* device, IRP* irp)
|
|||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
static UINT printer_custom_component(DEVICE* device, UINT16 component, UINT16 packetId, wStream* s)
|
||||
{
|
||||
switch (component)
|
||||
{
|
||||
case RDPDR_CTYP_PRN:
|
||||
switch (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%08"PRIX32")", 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%04"PRIX16"", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -357,6 +395,7 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints,
|
|||
printer_dev->device.type = RDPDR_DTYP_PRINT;
|
||||
printer_dev->device.name = printer_dev->port;
|
||||
printer_dev->device.IRPRequest = printer_irp_request;
|
||||
printer_dev->device.CustomComponentRequest = printer_custom_component;
|
||||
printer_dev->device.Free = printer_free;
|
||||
printer_dev->rdpcontext = pEntryPoints->rdpcontext;
|
||||
printer_dev->printer = printer;
|
||||
|
|
|
@ -68,8 +68,8 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
|||
|
||||
devman->plugin = (void*) rdpdr;
|
||||
devman->id_sequence = 1;
|
||||
|
||||
devman->devices = ListDictionary_New(TRUE);
|
||||
|
||||
if (!devman->devices)
|
||||
{
|
||||
WLog_INFO(TAG, "ListDictionary_New failed!");
|
||||
|
@ -78,7 +78,6 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
|||
}
|
||||
|
||||
ListDictionary_ValueObject(devman->devices)->fnObjectFree = devman_device_free;
|
||||
|
||||
return devman;
|
||||
}
|
||||
|
||||
|
@ -114,26 +113,57 @@ static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
|
|||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
device->id = devman->id_sequence++;
|
||||
key = (void*) (size_t) device->id;
|
||||
key = (void*)(size_t) device->id;
|
||||
|
||||
if (!ListDictionary_Add(devman->devices, key, device))
|
||||
{
|
||||
WLog_INFO(TAG, "ListDictionary_Add failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
|
||||
{
|
||||
DEVICE* device = NULL;
|
||||
void* key = (void*) (size_t) id;
|
||||
void* key = (void*)(size_t) id;
|
||||
|
||||
if (!devman)
|
||||
return NULL;
|
||||
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);
|
||||
return device;
|
||||
}
|
||||
|
||||
DEVICE* devman_get_device_by_type(DEVMAN* devman, UINT32 type)
|
||||
{
|
||||
DEVICE* device = NULL;
|
||||
ULONG_PTR* keys;
|
||||
int count, x;
|
||||
|
||||
if (!devman)
|
||||
return NULL;
|
||||
|
||||
ListDictionary_Lock(devman->devices);
|
||||
count = ListDictionary_GetKeys(devman->devices, &keys);
|
||||
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
DEVICE* cur = (DEVICE*) ListDictionary_GetItemValue(devman->devices, keys[x]);
|
||||
|
||||
if (!cur)
|
||||
continue;
|
||||
|
||||
if (cur->type != type)
|
||||
continue;
|
||||
|
||||
device = cur;
|
||||
break;
|
||||
}
|
||||
|
||||
free(keys);
|
||||
ListDictionary_Unlock(devman->devices);
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@ -178,7 +208,9 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext
|
|||
WLog_INFO(TAG, "Loading device service %s [%s] (static)", ServiceName, device->Name);
|
||||
else
|
||||
WLog_INFO(TAG, "Loading device service %s (static)", ServiceName);
|
||||
entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
|
||||
|
||||
entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL,
|
||||
"DeviceServiceEntry", 0);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
|
@ -190,6 +222,5 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext
|
|||
ep.RegisterDevice = devman_register_device;
|
||||
ep.device = device;
|
||||
ep.rdpcontext = rdpcontext;
|
||||
|
||||
return entry(&ep);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
void devman_unregister_device(DEVMAN* devman, void* key);
|
||||
UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext* rdpcontext);
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id);
|
||||
DEVICE* devman_get_device_by_type(DEVMAN* devman, UINT32 type);
|
||||
|
||||
DEVMAN* devman_new(rdpdrPlugin* rdpdr);
|
||||
void devman_free(DEVMAN* devman);
|
||||
|
|
|
@ -135,7 +135,8 @@ BOOL check_path(char* path)
|
|||
{
|
||||
UINT type = GetDriveTypeA(path);
|
||||
|
||||
if (!(type == DRIVE_FIXED ||type == DRIVE_REMOVABLE || type == DRIVE_CDROM || type == DRIVE_REMOTE))
|
||||
if (!(type == DRIVE_FIXED || type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
|
||||
type == DRIVE_REMOTE))
|
||||
return FALSE;
|
||||
|
||||
return GetVolumeInformationA(path, NULL, 0, NULL, NULL, NULL, NULL, 0);
|
||||
|
@ -1324,6 +1325,31 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
|||
return error;
|
||||
}
|
||||
|
||||
static UINT rdpdr_process_component(rdpdrPlugin* rdpdr, UINT16 component, UINT16 packetId,
|
||||
wStream* s)
|
||||
{
|
||||
UINT32 type;
|
||||
DEVICE* device;
|
||||
|
||||
switch (component)
|
||||
{
|
||||
case RDPDR_CTYP_PRN:
|
||||
type = RDPDR_DTYP_PRINT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
device = devman_get_device_by_type(rdpdr->devman, type);
|
||||
|
||||
if (!device)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return IFCALLRESULT(ERROR_INVALID_PARAMETER, device->CustomComponentRequest, device, component,
|
||||
packetId, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -1368,141 +1394,114 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||
UINT16 packetId;
|
||||
UINT32 deviceId;
|
||||
UINT32 status;
|
||||
UINT error;
|
||||
UINT error = ERROR_INVALID_DATA;
|
||||
|
||||
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) */
|
||||
|
||||
if (component == RDPDR_CTYP_CORE)
|
||||
if (Stream_GetRemainingLength(s) >= 4)
|
||||
{
|
||||
switch (packetId)
|
||||
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
|
||||
Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */
|
||||
|
||||
if (component == RDPDR_CTYP_CORE)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
||||
return error;
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
||||
{
|
||||
}
|
||||
else if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %"PRIu32"", error);
|
||||
}
|
||||
else if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %"PRIu32"", error);
|
||||
}
|
||||
else if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
if ((error = rdpdr_process_capability_request(rdpdr, s)))
|
||||
{
|
||||
}
|
||||
else if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %"PRIu32"", error);
|
||||
}
|
||||
|
||||
if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
||||
{
|
||||
}
|
||||
else if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %"PRIu32"",
|
||||
error);
|
||||
}
|
||||
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
if ((error = rdpdr_process_capability_request(rdpdr, s)))
|
||||
return error;
|
||||
break;
|
||||
|
||||
if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %"PRIu32"", error);
|
||||
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 %"PRIu32"",
|
||||
error);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
||||
return error;
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %"PRIu32"",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
/* connect to a specific resource */
|
||||
if (Stream_GetRemainingLength(s) >= 8)
|
||||
{
|
||||
Stream_Read_UINT32(s, deviceId);
|
||||
Stream_Read_UINT32(s, status);
|
||||
error = CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
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 %"PRIu32"",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
else
|
||||
s = NULL;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
|
||||
/* connect to a specific resource */
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
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 %"PRIu32"", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04"PRIX16"", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04"PRIX16"", packetId);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (component == RDPDR_CTYP_PRN)
|
||||
{
|
||||
switch (packetId)
|
||||
else
|
||||
{
|
||||
case PAKID_PRN_CACHE_DATA:
|
||||
{
|
||||
UINT32 eventID;
|
||||
error = rdpdr_process_component(rdpdr, component, packetId, s);
|
||||
|
||||
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%08"PRIX32")", 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%04"PRIX16"", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "Unknown message: Component: 0x%04"PRIX16" PacketId: 0x%04"PRIX16"", component,
|
||||
packetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Unknown message: Component: 0x%04"PRIX16" PacketId: 0x%04"PRIX16"", component,
|
||||
packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
return CHANNEL_RC_OK;
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -316,6 +316,8 @@ typedef struct _DEVICE DEVICE;
|
|||
typedef struct _IRP IRP;
|
||||
typedef struct _DEVMAN DEVMAN;
|
||||
|
||||
typedef UINT(*pcCustomComponentRequest)(DEVICE* device, UINT16 component, UINT16 packetId,
|
||||
wStream* s);
|
||||
typedef UINT(*pcIRPRequest)(DEVICE* device, IRP* irp);
|
||||
typedef UINT(*pcInitDevice)(DEVICE* device);
|
||||
typedef UINT(*pcFreeDevice)(DEVICE* device);
|
||||
|
@ -328,6 +330,7 @@ struct _DEVICE
|
|||
const char* name;
|
||||
wStream* data;
|
||||
|
||||
pcCustomComponentRequest CustomComponentRequest;
|
||||
pcIRPRequest IRPRequest;
|
||||
pcInitDevice Init;
|
||||
pcFreeDevice Free;
|
||||
|
|
Loading…
Reference in New Issue