Refactored rdpdr and dependent channels

* Move parsing code to core library
* Move definitions to public API to allow access from outside
* Move smartcard related parsing to core library
This commit is contained in:
Armin Novak 2021-12-14 12:59:16 +01:00 committed by akallabeth
parent 803dd8f6ff
commit 3c72cc3306
22 changed files with 4191 additions and 3718 deletions

View File

@ -31,6 +31,8 @@
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/utils/rdpdr_utils.h>
#include "rdpdr_main.h"
#include "devman.h"
#include "irp.h"
@ -132,11 +134,15 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
*error = CHANNEL_RC_NO_MEMORY;
return NULL;
}
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
Stream_Write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */
Stream_Write_UINT32(irp->output, DeviceId); /* DeviceId (4 bytes) */
Stream_Write_UINT32(irp->output, irp->CompletionId); /* CompletionId (4 bytes) */
Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */
if (!rdpdr_write_iocompletion_header(irp->output, DeviceId, irp->CompletionId, 0))
{
Stream_Free(irp->output, TRUE);
_aligned_free(irp);
if (error)
*error = CHANNEL_RC_NO_MEMORY;
return NULL;
}
irp->Complete = irp_complete;
irp->Discard = irp_free;

View File

@ -51,8 +51,8 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
rdpdr_write_capset_header(s, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02);
Stream_Write_UINT32(s, 0); /* osType, ignored on receipt */
Stream_Write_UINT32(s, 0); /* osVersion, unused and must be set to zero */
Stream_Write_UINT16(s, RDPDR_MAJOR_RDP_VERSION); /* protocolMajorVersion, must be set to 1 */
Stream_Write_UINT16(s, RDPDR_MINOR_RDP_VERSION_13); /* protocolMinorVersion */
Stream_Write_UINT16(s, rdpdr->versionMajor); /* protocolMajorVersion, must be set to 1 */
Stream_Write_UINT16(s, rdpdr->versionMinor); /* protocolMinorVersion */
Stream_Write_UINT32(s, 0x0000FFFF); /* ioCode1 */
Stream_Write_UINT32(s, 0); /* ioCode2, must be set to zero, reserved for future use */
Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU |

View File

@ -34,10 +34,13 @@
#include <winpr/assert.h>
#include <winpr/stream.h>
#include <winpr/print.h>
#include <freerdp/types.h>
#include <freerdp/constants.h>
#include <freerdp/channels/log.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/utils/rdpdr_utils.h>
#ifdef _WIN32
#include <windows.h>
@ -1362,16 +1365,9 @@ static UINT dummy_irp_response(rdpdrPlugin* rdpdr, wStream* s)
Stream_Read_UINT32(s, FileId); /* FileId (4 bytes) */
Stream_Read_UINT32(s, CompletionId); /* CompletionId (4 bytes) */
Stream_Write_UINT16(output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
Stream_Write_UINT16(output, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */
Stream_Write_UINT32(output, DeviceId); /* DeviceId (4 bytes) */
Stream_Write_UINT32(output, CompletionId); /* CompletionId (4 bytes) */
Stream_Write_UINT32(output, (UINT32)STATUS_UNSUCCESSFUL); /* IoStatus (4 bytes) */
Stream_Zero(output, 256 - RDPDR_DEVICE_IO_RESPONSE_LENGTH);
// or usage
// Stream_Write_UINT32(output, 0); /* Length */
// Stream_Write_UINT8(output, 0); /* Padding */
if (!rdpdr_write_iocompletion_header(output, DeviceId, CompletionId,
(UINT32)STATUS_UNSUCCESSFUL))
return CHANNEL_RC_NO_MEMORY;
return rdpdr_send(rdpdr, output);
}
@ -1488,6 +1484,7 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
rdpdr_dump_received_packet(s, "rdpdr-channel");
if (Stream_GetRemainingLength(s) >= 4)
{
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
@ -1630,9 +1627,10 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
}
else
{
const size_t pos = Stream_GetPosition(s);
rdpdr_dump_send_packet(s, "rdpdr-channel");
status = plugin->channelEntryPoints.pVirtualChannelWriteEx(
plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), (UINT32)Stream_GetPosition(s),
s);
plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), pos, s);
}
if (status != CHANNEL_RC_OK)

View File

@ -78,6 +78,7 @@ static UINT rdpdr_seal_send_free_request(RdpdrServerContext* context, wStream* s
Stream_Free(s, TRUE);
return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
/**
* Function description
*

View File

@ -57,13 +57,6 @@ struct _RDPDR_HEADER
};
typedef struct _RDPDR_HEADER RDPDR_HEADER;
#define RDPDR_VERSION_MAJOR 0x0001
#define RDPDR_VERSION_MINOR_RDP50 0x0002
#define RDPDR_VERSION_MINOR_RDP51 0x0005
#define RDPDR_VERSION_MINOR_RDP52 0x000A
#define RDPDR_VERSION_MINOR_RDP6X 0x000C
#define RDPDR_CAPABILITY_HEADER_LENGTH 8
struct _RDPDR_CAPABILITY_HEADER

View File

@ -41,6 +41,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/channels/log.h>
#include <freerdp/utils/rdpdr_utils.h>
#define TAG CHANNELS_TAG("serial.client")
@ -447,9 +448,8 @@ error_handle:
static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp)
{
UINT error = CHANNEL_RC_OK;
WLog_Print(serial->log, WLOG_DEBUG,
"IRP MajorFunction: 0x%08" PRIX32 " MinorFunction: 0x%08" PRIX32 "\n",
irp->MajorFunction, irp->MinorFunction);
WLog_Print(serial->log, WLOG_DEBUG, "IRP MajorFunction: s, MinorFunction: 0x%08" PRIX32 "\n",
rdpdr_irp_string(irp->MajorFunction), irp->MinorFunction);
switch (irp->MajorFunction)
{

View File

@ -20,10 +20,7 @@ define_channel_client("smartcard")
set(${MODULE_PREFIX}_SRCS
smartcard_main.c
smartcard_main.h
smartcard_pack.c
smartcard_pack.h
smartcard_operations.h
smartcard_operations.c)
)
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DeviceServiceEntry")

View File

@ -31,21 +31,27 @@
#include <winpr/environment.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/channels/scard.h>
#include <freerdp/utils/smartcard_call.h>
#include <freerdp/utils/smartcard_operations.h>
#include <freerdp/utils/rdpdr_utils.h>
#include "smartcard_main.h"
#define CAST_FROM_DEVICE(device) cast_device_from(device, __FUNCTION__, __FILE__, __LINE__)
#if defined(WITH_SMARTCARD_EMULATE)
#include <freerdp/emulate/scard/smartcard_emulate.h>
#define str(x) #x
#define wrap(smartcard, fkt, ...) Emulate_##fkt(smartcard->emulation, ##__VA_ARGS__)
#else
#define wrap(smartcard, fkt, ...) fkt(__VA_ARGS__)
#endif
typedef struct
{
SMARTCARD_OPERATION operation;
IRP* irp;
} scard_irp_queue_element;
static SMARTCARD_DEVICE* sSmartcard = NULL;
static void smartcard_context_free(void* pCtx);
static UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
static SMARTCARD_DEVICE* cast_device_from(DEVICE* device, const char* fkt, const char* file,
int line)
{
@ -74,7 +80,6 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
HANDLE hEvents[2];
wMessage message;
SMARTCARD_DEVICE* smartcard;
SMARTCARD_OPERATION* operation;
UINT error = CHANNEL_RC_OK;
smartcard = pContext->smartcard;
nCount = 0;
@ -102,6 +107,8 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
if (waitStatus == WAIT_OBJECT_0)
{
scard_irp_queue_element* element;
if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE))
{
WLog_ERR(TAG, "MessageQueue_Peek failed!");
@ -112,25 +119,32 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
if (message.id == WMQ_QUIT)
break;
operation = (SMARTCARD_OPERATION*)message.wParam;
element = (scard_irp_queue_element*)message.wParam;
if (operation)
if (element)
{
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
UINT error;
WINPR_ASSERT(smartcard);
if ((status = smartcard_irp_device_control_call(
smartcard->callctx, element->irp->output, &element->irp->IoStatus,
&element->operation)))
{
smartcard_operation_free(&element->operation, TRUE);
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %" PRIu32 "",
status);
break;
}
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)operation->irp))
if ((error = smartcard_complete_irp(smartcard, element->irp)))
{
smartcard_operation_free(&element->operation, TRUE);
WLog_ERR(TAG, "Queue_Enqueue failed!");
status = ERROR_INTERNAL_ERROR;
break;
}
free(operation);
smartcard_operation_free(&element->operation, TRUE);
}
}
}
@ -142,7 +156,7 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
return error;
}
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext)
static void* smartcard_context_new(void* smartcard, SCARDCONTEXT hContext)
{
SMARTCARD_CONTEXT* pContext;
pContext = (SMARTCARD_CONTEXT*)calloc(1, sizeof(SMARTCARD_CONTEXT));
@ -185,7 +199,8 @@ void smartcard_context_free(void* pCtx)
return;
/* cancel blocking calls like SCardGetStatusChange */
wrap(pContext->smartcard, SCardCancel, pContext->hContext);
WINPR_ASSERT(pContext->smartcard);
smartcard_call_cancel_context(pContext->smartcard->callctx, pContext->hContext);
if (pContext->IrpQueue)
{
@ -198,77 +213,13 @@ void smartcard_context_free(void* pCtx)
}
MessageQueue_Free(pContext->IrpQueue);
}
wrap(pContext->smartcard, SCardReleaseContext, pContext->hContext);
smartcard_call_release_context(pContext->smartcard->callctx, pContext->hContext);
free(pContext);
}
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
{
int index;
int keyCount;
ULONG_PTR* pKeys;
SCARDCONTEXT hContext;
SMARTCARD_CONTEXT* pContext;
/**
* On protocol termination, the following actions are performed:
* For each context in rgSCardContextList, SCardCancel is called causing all
* SCardGetStatusChange calls to be processed. After that, SCardReleaseContext is called on each
* context and the context MUST be removed from rgSCardContextList.
*/
/**
* Call SCardCancel on existing contexts, unblocking all outstanding SCardGetStatusChange calls.
*/
ListDictionary_Lock(smartcard->rgSCardContextList);
if (ListDictionary_Count(smartcard->rgSCardContextList) > 0)
{
pKeys = NULL;
keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys);
for (index = 0; index < keyCount; index++)
{
pContext = (SMARTCARD_CONTEXT*)ListDictionary_GetItemValue(
smartcard->rgSCardContextList, (void*)pKeys[index]);
if (!pContext)
continue;
hContext = pContext->hContext;
if (wrap(smartcard, SCardIsValidContext, hContext) == SCARD_S_SUCCESS)
{
wrap(smartcard, SCardCancel, hContext);
}
}
free(pKeys);
}
ListDictionary_Unlock(smartcard->rgSCardContextList);
/* Put thread to sleep so that PC/SC can process the cancel requests. This fixes a race
* condition that sometimes caused the pc/sc daemon to crash on MacOS (_xpc_api_misuse) */
SleepEx(100, FALSE);
/**
* Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList.
*/
ListDictionary_Lock(smartcard->rgSCardContextList);
if (ListDictionary_Count(smartcard->rgSCardContextList) > 0)
{
pKeys = NULL;
keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys);
for (index = 0; index < keyCount; index++)
{
ListDictionary_SetItemValue(smartcard->rgSCardContextList, (void*)pKeys[index], NULL);
}
free(pKeys);
}
ListDictionary_Unlock(smartcard->rgSCardContextList);
smartcard_call_cancel_all_context(smartcard->callctx);
}
static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard)
@ -283,17 +234,10 @@ static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard)
}
Stream_Free(smartcard->device.data, TRUE);
LinkedList_Free(smartcard->names);
ListDictionary_Free(smartcard->rgSCardContextList);
ListDictionary_Free(smartcard->rgOutstandingMessages);
Queue_Free(smartcard->CompletedIrpQueue);
if (smartcard->StartedEvent)
wrap(smartcard, SCardReleaseStartedEvent);
smartcard_call_context_free(smartcard->callctx);
#if defined(WITH_SMARTCARD_EMULATE)
Emulate_Free(smartcard->emulation);
#endif
free(smartcard);
return CHANNEL_RC_OK;
}
@ -360,11 +304,17 @@ static UINT smartcard_init(DEVICE* device)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
void* key;
WINPR_ASSERT(smartcard);
WINPR_ASSERT(irp);
key = (void*)(size_t)irp->CompletionId;
ListDictionary_Remove(smartcard->rgOutstandingMessages, key);
WINPR_ASSERT(irp->Complete);
return irp->Complete(irp);
}
@ -384,7 +334,6 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
LONG status;
BOOL asyncIrp = FALSE;
SMARTCARD_CONTEXT* pContext = NULL;
SMARTCARD_OPERATION* operation = NULL;
key = (void*)(size_t)irp->CompletionId;
if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp))
@ -395,35 +344,35 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
operation = (SMARTCARD_OPERATION*)calloc(1, sizeof(SMARTCARD_OPERATION));
scard_irp_queue_element* element = calloc(1, sizeof(scard_irp_queue_element));
if (!element)
return ERROR_OUTOFMEMORY;
if (!operation)
{
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
element->irp = irp;
element->operation.completionID = irp->CompletionId;
operation->irp = irp;
status = smartcard_irp_device_control_decode(smartcard, operation);
status = smartcard_irp_device_control_decode(irp->input, irp->CompletionId, irp->FileId,
&element->operation);
if (status != SCARD_S_SUCCESS)
{
UINT error;
smartcard_operation_free(&element->operation, TRUE);
irp->IoStatus = (UINT32)STATUS_UNSUCCESSFUL;
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp))
if ((error = smartcard_complete_irp(smartcard, irp)))
{
free(operation);
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
return error;
}
free(operation);
return CHANNEL_RC_OK;
}
asyncIrp = TRUE;
switch (operation->ioControlCode)
switch (element->operation.ioControlCode)
{
case SCARD_IOCTL_ESTABLISHCONTEXT:
case SCARD_IOCTL_RELEASECONTEXT:
@ -480,37 +429,40 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
break;
}
pContext =
ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*)operation->hContext);
pContext = smartcard_call_get_context(smartcard->callctx, element->operation.hContext);
if (!pContext)
asyncIrp = FALSE;
if (!asyncIrp)
{
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
UINT error;
status =
smartcard_irp_device_control_call(smartcard->callctx, element->irp->output,
&element->irp->IoStatus, &element->operation);
smartcard_operation_free(&element->operation, TRUE);
if (status)
{
free(operation);
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %" PRId32 "!",
status);
return (UINT32)status;
}
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp))
if ((error = smartcard_complete_irp(smartcard, irp)))
{
free(operation);
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
return error;
}
free(operation);
}
else
{
if (pContext)
{
if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*)operation, NULL))
if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*)element, NULL))
{
smartcard_operation_free(&element->operation, TRUE);
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
@ -519,16 +471,15 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
}
else
{
WLog_ERR(TAG,
"Unexpected SmartCard IRP: MajorFunction 0x%08" PRIX32
" MinorFunction: 0x%08" PRIX32 "",
irp->MajorFunction, irp->MinorFunction);
UINT status;
WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction %s, MinorFunction: 0x%08" PRIX32 "",
rdpdr_irp_string(irp->MajorFunction), irp->MinorFunction);
irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED;
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp))
if ((status = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
return status;
}
}
@ -540,7 +491,7 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
IRP* irp;
DWORD nCount;
DWORD status;
HANDLE hEvents[2];
HANDLE hEvents[1];
wMessage message;
UINT error = CHANNEL_RC_OK;
SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(arg);
@ -550,7 +501,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
nCount = 0;
hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);
while (1)
{
@ -563,15 +513,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
break;
}
status = WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
break;
}
if (status == WAIT_OBJECT_0)
{
if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
@ -582,53 +523,8 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
}
if (message.id == WMQ_QUIT)
{
while (1)
{
status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
goto out;
}
if (status == WAIT_TIMEOUT)
break;
irp = (IRP*)Queue_Dequeue(smartcard->CompletedIrpQueue);
if (irp)
{
if (irp->thread)
{
status = WaitForSingleObject(irp->thread, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!",
error);
goto out;
}
CloseHandle(irp->thread);
irp->thread = NULL;
}
if ((error = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_complete_irp failed with error %" PRIu32 "!",
error);
goto out;
}
}
}
break;
}
irp = (IRP*)message.wParam;
if (irp)
@ -640,50 +536,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
}
}
}
status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
break;
}
if (status == WAIT_OBJECT_0)
{
irp = (IRP*)Queue_Dequeue(smartcard->CompletedIrpQueue);
if (irp)
{
if (irp->thread)
{
status = WaitForSingleObject(irp->thread, INFINITE);
if (status == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
break;
}
CloseHandle(irp->thread);
irp->thread = NULL;
}
if ((error = smartcard_complete_irp(smartcard, irp)))
{
if (error == CHANNEL_RC_NOT_CONNECTED)
{
error = CHANNEL_RC_OK;
goto out;
}
WLog_ERR(TAG, "smartcard_complete_irp failed with error %" PRIu32 "!", error);
goto out;
}
}
}
}
out:
@ -733,7 +585,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (!sSmartcard)
{
wObject* obj;
smartcard = (SMARTCARD_DEVICE*)calloc(1, sizeof(SMARTCARD_DEVICE));
if (!smartcard)
@ -747,12 +598,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
smartcard->device.IRPRequest = smartcard_irp_request;
smartcard->device.Init = smartcard_init;
smartcard->device.Free = smartcard_free;
smartcard->names = LinkedList_New();
smartcard->rdpcontext = pEntryPoints->rdpcontext;
length = strlen(smartcard->device.name);
smartcard->device.data = Stream_New(NULL, length + 1);
if (!smartcard->device.data || !smartcard->names)
if (!smartcard->device.data)
{
WLog_ERR(TAG, "Stream_New failed!");
goto fail;
@ -767,24 +617,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
goto fail;
}
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
if (!smartcard->CompletedIrpQueue)
{
WLog_ERR(TAG, "Queue_New failed!");
goto fail;
}
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
if (!smartcard->rgSCardContextList)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
goto fail;
}
obj = ListDictionary_ValueObject(smartcard->rgSCardContextList);
obj->fnObjectFree = smartcard_context_free;
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
if (!smartcard->rgOutstandingMessages)
@ -793,11 +625,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
goto fail;
}
#if defined(WITH_SMARTCARD_EMULATE)
smartcard->emulation = Emulate_New(smartcard->rdpcontext->settings);
if (!smartcard->emulation)
smartcard->callctx = smartcard_call_context_new(smartcard->rdpcontext->settings);
if (!smartcard->callctx)
goto fail;
#endif
if (!smarcard_call_set_callbacks(smartcard->callctx, smartcard, smartcard_context_new,
smartcard_context_free))
goto fail;
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, &smartcard->device)))
{
WLog_ERR(TAG, "RegisterDevice failed!");
@ -820,7 +655,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
smartcard = sSmartcard;
if (pEntryPoints->device->Name)
LinkedList_AddLast(smartcard->names, pEntryPoints->device->Name);
{
smartcard_call_context_add(smartcard->callctx, pEntryPoints->device->Name);
}
sSmartcard = smartcard;
return CHANNEL_RC_OK;

View File

@ -32,7 +32,8 @@
#include <winpr/smartcard.h>
#include <winpr/collections.h>
#include "smartcard_operations.h"
#include <freerdp/utils/smartcard_operations.h>
#include <freerdp/utils/smartcard_call.h>
#if defined(WITH_SMARTCARD_EMULATE)
#include <freerdp/emulate/scard/smartcard_emulate.h>
@ -56,25 +57,10 @@ struct _SMARTCARD_DEVICE
DEVICE device;
HANDLE thread;
HANDLE StartedEvent;
scard_call_context* callctx;
wMessageQueue* IrpQueue;
wQueue* CompletedIrpQueue;
wListDictionary* rgSCardContextList;
wListDictionary* rgOutstandingMessages;
rdpContext* rdpcontext;
wLinkedList* names;
#if defined(WITH_SMARTCARD_EMULATE)
SmartcardEmulationContext* emulation;
#endif
};
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext);
void smartcard_context_free(void* pContext);
LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard,
SMARTCARD_OPERATION* operation);
LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
#include "smartcard_pack.h"
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,196 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smart Card Structure Packing
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2020 Armin Novak <armin.novak@thincast.com>
* Copyright 2020 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/smartcard.h>
#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8
#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8
#include "smartcard_main.h"
LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
UINT32 alignment);
LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
UINT32 alignment);
SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard,
REDIR_SCARDCONTEXT* context);
void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard,
REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext);
SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard,
REDIR_SCARDHANDLE* handle);
void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle,
SCARDHANDLE hCard);
LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
UINT32 objectBufferLength);
LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s,
EstablishContext_Call* call);
LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const EstablishContext_Return* ret);
LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call,
const char* name);
void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* ret,
const char* name);
LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ListReaderGroups_Call* call, BOOL unicode);
LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const ListReaderGroups_Return* ret, BOOL unicode);
LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ListReaders_Call* call, BOOL unicode);
LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const ListReaders_Return* ret, BOOL unicode);
LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ContextAndTwoStringA_Call* call);
LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ContextAndTwoStringW_Call* call);
LONG smartcard_unpack_context_and_string_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ContextAndStringA_Call* call);
LONG smartcard_unpack_context_and_string_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ContextAndStringW_Call* call);
LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
LocateCardsA_Call* call);
LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const LocateCards_Return* ret);
LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
LocateCardsW_Call* call);
LONG smartcard_pack_locate_cards_w_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const LocateCardsW_Call* ret);
LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call);
LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call);
LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const Connect_Return* ret);
LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call);
LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const Reconnect_Return* ret);
LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s,
HCardAndDisposition_Call* call, const char* name);
LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetStatusChangeA_Call* call);
LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetStatusChangeW_Call* call);
LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const GetStatusChange_Return* ret, BOOL unicode);
LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call);
LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const State_Return* ret);
LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call,
BOOL unicode);
LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Status_Return* ret,
BOOL unicode);
LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetAttrib_Call* call);
LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const GetAttrib_Return* ret, DWORD dwAttrId,
DWORD cbAttrCallLen);
LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s,
SetAttrib_Call* call);
LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call);
LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const Control_Return* ret);
LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call);
LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const Transmit_Return* ret);
LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
LocateCardsByATRA_Call* call);
LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
LocateCardsByATRW_Call* call);
LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ReadCacheA_Call* call);
LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
ReadCacheW_Call* call);
LONG smartcard_pack_read_cache_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const ReadCache_Return* ret);
LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
WriteCacheA_Call* call);
LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
WriteCacheW_Call* call);
LONG smartcard_unpack_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetTransmitCount_Call* call);
LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const GetTransmitCount_Return* call);
LONG smartcard_unpack_get_reader_icon_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetReaderIcon_Call* call);
LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const GetReaderIcon_Return* ret);
LONG smartcard_unpack_get_device_type_id_call(SMARTCARD_DEVICE* smartcard, wStream* s,
GetDeviceTypeId_Call* call);
LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* s,
const GetDeviceTypeId_Return* ret);
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */

View File

@ -43,6 +43,14 @@
#define RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH 32
#define RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH 4
#define RDPDR_VERSION_MAJOR 0x0001
#define RDPDR_VERSION_MINOR_RDP50 0x0002
#define RDPDR_VERSION_MINOR_RDP51 0x0005
#define RDPDR_VERSION_MINOR_RDP52 0x000A
#define RDPDR_VERSION_MINOR_RDP6X 0x000C
#define RDPDR_VERSION_MINOR_RDP10X 0x000D
/* RDPDR_HEADER.Component */
enum RDPDR_CTYP
{

View File

@ -1,11 +1,9 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
* Smartcard Redirection Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2021 Armin Novak <anovak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,10 +18,11 @@
* limitations under the License.
*/
#ifndef FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#define FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#ifndef FREERDP_CHANNEL_SCARD_H
#define FREERDP_CHANNEL_SCARD_H
#include <winpr/crt.h>
#include <winpr/smartcard.h>
#define RDP_SCARD_CTL_CODE(code) \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, (code), METHOD_BUFFERED, FILE_ANY_ACCESS)
@ -493,54 +492,4 @@ typedef struct _WriteCacheW_Call
/* [string] */ WCHAR* szLookupName;
} WriteCacheW_Call;
struct _SMARTCARD_OPERATION
{
IRP* irp;
union
{
Handles_Call handles;
Long_Call lng;
Context_Call context;
ContextAndStringA_Call contextAndStringA;
ContextAndStringW_Call contextAndStringW;
ContextAndTwoStringA_Call contextAndTwoStringA;
ContextAndTwoStringW_Call contextAndTwoStringW;
EstablishContext_Call establishContext;
ListReaderGroups_Call listReaderGroups;
ListReaders_Call listReaders;
GetStatusChangeA_Call getStatusChangeA;
LocateCardsA_Call locateCardsA;
LocateCardsW_Call locateCardsW;
LocateCards_ATRMask locateCardsATRMask;
LocateCardsByATRA_Call locateCardsByATRA;
LocateCardsByATRW_Call locateCardsByATRW;
GetStatusChangeW_Call getStatusChangeW;
GetReaderIcon_Call getReaderIcon;
GetDeviceTypeId_Call getDeviceTypeId;
Connect_Common_Call connect;
ConnectA_Call connectA;
ConnectW_Call connectW;
Reconnect_Call reconnect;
HCardAndDisposition_Call hCardAndDisposition;
State_Call state;
Status_Call status;
SCardIO_Request scardIO;
Transmit_Call transmit;
GetTransmitCount_Call getTransmitCount;
Control_Call control;
GetAttrib_Call getAttrib;
SetAttrib_Call setAttrib;
ReadCache_Common readCache;
ReadCacheA_Call readCacheA;
ReadCacheW_Call readCacheW;
WriteCache_Common writeCache;
WriteCacheA_Call writeCacheA;
WriteCacheW_Call writeCacheW;
} call;
UINT32 ioControlCode;
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
};
typedef struct _SMARTCARD_OPERATION SMARTCARD_OPERATION;
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_OPERATIONS_H */
#endif /* FREERDP_CHANNEL_SCARD_H */

View File

@ -0,0 +1,41 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* RDPDR utility functions
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_UTILS_RDPDR_H
#define FREERDP_UTILS_RDPDR_H
#include <winpr/stream.h>
#include <freerdp/api.h>
FREERDP_API const char* rdpdr_component_string(UINT16 component);
FREERDP_API const char* rdpdr_packetid_string(UINT16 packetid);
FREERDP_API const char* rdpdr_irp_string(UINT32 major);
FREERDP_API const char* rdpdr_cap_type_string(UINT16 capability);
FREERDP_API LONG scard_log_status_error(const char* tag, const char* what, LONG status);
FREERDP_API const char* scard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName);
FREERDP_API BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 CompletionId,
UINT32 ioStatus);
FREERDP_API void rdpdr_dump_received_packet(wStream* out, const char* custom);
FREERDP_API void rdpdr_dump_send_packet(wStream* out, const char* custom);
#endif

View File

@ -0,0 +1,54 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_CHANNEL_SMARTCARD_CALL_H
#define FREERDP_CHANNEL_SMARTCARD_CALL_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/api.h>
#include <freerdp/settings.h>
#include <freerdp/channels/scard.h>
#include <freerdp/utils/smartcard_operations.h>
typedef struct _scard_call_context scard_call_context;
FREERDP_API scard_call_context* smartcard_call_context_new(const rdpSettings* settings);
FREERDP_API void smartcard_call_context_free(scard_call_context* ctx);
FREERDP_API BOOL smartcard_call_context_signal_stop(scard_call_context* ctx);
FREERDP_API BOOL smartcard_call_context_add(scard_call_context* ctx, const char* name);
FREERDP_API BOOL smartcard_call_cancel_context(scard_call_context* ctx, SCARDCONTEXT context);
FREERDP_API BOOL smartcard_call_cancel_all_context(scard_call_context* ctx);
FREERDP_API BOOL smartcard_call_release_context(scard_call_context* ctx, SCARDCONTEXT context);
FREERDP_API BOOL smartcard_call_is_configured(scard_call_context* ctx);
FREERDP_API BOOL smarcard_call_set_callbacks(scard_call_context* ctx, void* userdata,
void* (*fn_new)(void*, SCARDCONTEXT),
void (*fn_free)(void*));
FREERDP_API void* smartcard_call_get_context(scard_call_context* ctx, SCARDCONTEXT hContext);
FREERDP_API LONG smartcard_irp_device_control_call(scard_call_context* context, wStream* out,
UINT32* pIoStatus,
SMARTCARD_OPERATION* operation);
#endif /* FREERDP_CHANNEL_SMARTCARD_CALL_H */

View File

@ -0,0 +1,89 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#define FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/smartcard.h>
#include <freerdp/api.h>
#include <freerdp/channels/scard.h>
struct _SMARTCARD_OPERATION
{
union
{
Handles_Call handles;
Long_Call lng;
Context_Call context;
ContextAndStringA_Call contextAndStringA;
ContextAndStringW_Call contextAndStringW;
ContextAndTwoStringA_Call contextAndTwoStringA;
ContextAndTwoStringW_Call contextAndTwoStringW;
EstablishContext_Call establishContext;
ListReaderGroups_Call listReaderGroups;
ListReaders_Call listReaders;
GetStatusChangeA_Call getStatusChangeA;
LocateCardsA_Call locateCardsA;
LocateCardsW_Call locateCardsW;
LocateCards_ATRMask locateCardsATRMask;
LocateCardsByATRA_Call locateCardsByATRA;
LocateCardsByATRW_Call locateCardsByATRW;
GetStatusChangeW_Call getStatusChangeW;
GetReaderIcon_Call getReaderIcon;
GetDeviceTypeId_Call getDeviceTypeId;
Connect_Common_Call connect;
ConnectA_Call connectA;
ConnectW_Call connectW;
Reconnect_Call reconnect;
HCardAndDisposition_Call hCardAndDisposition;
State_Call state;
Status_Call status;
SCardIO_Request scardIO;
Transmit_Call transmit;
GetTransmitCount_Call getTransmitCount;
Control_Call control;
GetAttrib_Call getAttrib;
SetAttrib_Call setAttrib;
ReadCache_Common readCache;
ReadCacheA_Call readCacheA;
ReadCacheW_Call readCacheW;
WriteCache_Common writeCache;
WriteCacheA_Call writeCacheA;
WriteCacheW_Call writeCacheW;
} call;
UINT32 ioControlCode;
UINT32 completionID;
UINT32 deviceID;
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
const char* ioControlCodeName;
};
typedef struct _SMARTCARD_OPERATION SMARTCARD_OPERATION;
FREERDP_API LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId, UINT32 FileId,
SMARTCARD_OPERATION* operation);
FREERDP_API void smartcard_operation_free(SMARTCARD_OPERATION* op, BOOL allocated);
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_OPERATIONS_H */

View File

@ -0,0 +1,168 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smart Card Structure Packing
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2020 Armin Novak <armin.novak@thincast.com>
* Copyright 2020 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/smartcard.h>
#include <freerdp/api.h>
#include <freerdp/channels/scard.h>
#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8
#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8
FREERDP_API LONG smartcard_pack_write_size_align(wStream* s, size_t size, UINT32 alignment);
FREERDP_API LONG smartcard_unpack_read_size_align(wStream* s, size_t size, UINT32 alignment);
FREERDP_API SCARDCONTEXT smartcard_scard_context_native_from_redir(REDIR_SCARDCONTEXT* context);
FREERDP_API void smartcard_scard_context_native_to_redir(REDIR_SCARDCONTEXT* context,
SCARDCONTEXT hContext);
FREERDP_API SCARDHANDLE smartcard_scard_handle_native_from_redir(REDIR_SCARDHANDLE* handle);
FREERDP_API void smartcard_scard_handle_native_to_redir(REDIR_SCARDHANDLE* handle,
SCARDHANDLE hCard);
FREERDP_API LONG smartcard_unpack_common_type_header(wStream* s);
FREERDP_API void smartcard_pack_common_type_header(wStream* s);
FREERDP_API LONG smartcard_unpack_private_type_header(wStream* s);
FREERDP_API void smartcard_pack_private_type_header(wStream* s, UINT32 objectBufferLength);
FREERDP_API LONG smartcard_unpack_establish_context_call(wStream* s, EstablishContext_Call* call);
FREERDP_API LONG smartcard_pack_establish_context_return(wStream* s,
const EstablishContext_Return* ret);
FREERDP_API LONG smartcard_unpack_context_call(wStream* s, Context_Call* call, const char* name);
FREERDP_API void smartcard_trace_long_return(const Long_Return* ret, const char* name);
FREERDP_API LONG smartcard_unpack_list_reader_groups_call(wStream* s, ListReaderGroups_Call* call,
BOOL unicode);
FREERDP_API LONG smartcard_pack_list_reader_groups_return(wStream* s,
const ListReaderGroups_Return* ret,
BOOL unicode);
FREERDP_API LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call,
BOOL unicode);
FREERDP_API LONG smartcard_pack_list_readers_return(wStream* s, const ListReaders_Return* ret,
BOOL unicode);
FREERDP_API LONG smartcard_unpack_context_and_two_strings_a_call(wStream* s,
ContextAndTwoStringA_Call* call);
FREERDP_API LONG smartcard_unpack_context_and_two_strings_w_call(wStream* s,
ContextAndTwoStringW_Call* call);
FREERDP_API LONG smartcard_unpack_context_and_string_a_call(wStream* s,
ContextAndStringA_Call* call);
FREERDP_API LONG smartcard_unpack_context_and_string_w_call(wStream* s,
ContextAndStringW_Call* call);
FREERDP_API LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call);
FREERDP_API LONG smartcard_pack_locate_cards_return(wStream* s, const LocateCards_Return* ret);
FREERDP_API LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call);
FREERDP_API LONG smartcard_pack_locate_cards_w_return(wStream* s, const LocateCardsW_Call* ret);
FREERDP_API LONG smartcard_unpack_connect_a_call(wStream* s, ConnectA_Call* call);
FREERDP_API LONG smartcard_unpack_connect_w_call(wStream* s, ConnectW_Call* call);
FREERDP_API LONG smartcard_pack_connect_return(wStream* s, const Connect_Return* ret);
FREERDP_API LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call);
FREERDP_API LONG smartcard_pack_reconnect_return(wStream* s, const Reconnect_Return* ret);
FREERDP_API LONG smartcard_unpack_hcard_and_disposition_call(wStream* s,
HCardAndDisposition_Call* call,
const char* name);
FREERDP_API LONG smartcard_unpack_get_status_change_a_call(wStream* s, GetStatusChangeA_Call* call);
FREERDP_API LONG smartcard_unpack_get_status_change_w_call(wStream* s, GetStatusChangeW_Call* call);
FREERDP_API LONG smartcard_pack_get_status_change_return(wStream* s,
const GetStatusChange_Return* ret,
BOOL unicode);
FREERDP_API LONG smartcard_unpack_state_call(wStream* s, State_Call* call);
FREERDP_API LONG smartcard_pack_state_return(wStream* s, const State_Return* ret);
FREERDP_API LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode);
FREERDP_API LONG smartcard_pack_status_return(wStream* s, const Status_Return* ret, BOOL unicode);
FREERDP_API LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call);
FREERDP_API LONG smartcard_pack_get_attrib_return(wStream* s, const GetAttrib_Return* ret,
DWORD dwAttrId, DWORD cbAttrCallLen);
FREERDP_API LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call);
FREERDP_API LONG smartcard_unpack_control_call(wStream* s, Control_Call* call);
FREERDP_API LONG smartcard_pack_control_return(wStream* s, const Control_Return* ret);
FREERDP_API LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call);
FREERDP_API LONG smartcard_pack_transmit_return(wStream* s, const Transmit_Return* ret);
FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s,
LocateCardsByATRA_Call* call);
FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s,
LocateCardsByATRW_Call* call);
FREERDP_API LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call);
FREERDP_API LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call);
FREERDP_API LONG smartcard_pack_read_cache_return(wStream* s, const ReadCache_Return* ret);
FREERDP_API LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call);
FREERDP_API LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call);
FREERDP_API LONG smartcard_unpack_get_transmit_count_call(wStream* s, GetTransmitCount_Call* call);
FREERDP_API LONG smartcard_pack_get_transmit_count_return(wStream* s,
const GetTransmitCount_Return* call);
FREERDP_API LONG smartcard_unpack_get_reader_icon_call(wStream* s, GetReaderIcon_Call* call);
FREERDP_API LONG smartcard_pack_get_reader_icon_return(wStream* s, const GetReaderIcon_Return* ret);
FREERDP_API LONG smartcard_unpack_get_device_type_id_call(wStream* s, GetDeviceTypeId_Call* call);
FREERDP_API LONG smartcard_pack_device_type_id_return(wStream* s,
const GetDeviceTypeId_Return* ret);
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */

View File

@ -20,10 +20,14 @@ set(MODULE_PREFIX "FREERDP_UTILS")
set(${MODULE_PREFIX}_SRCS
passphrase.c
rdpdr_utils.c
pcap.c
profiler.c
ringbuffer.c
signal.c
smartcard_operations.c
smartcard_pack.c
smartcard_call.c
stopwatch.c)
freerdp_module_add(${${MODULE_PREFIX}_SRCS})

View File

@ -0,0 +1,416 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* SCard utility functions
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <winpr/wlog.h>
#include <winpr/print.h>
#include <winpr/smartcard.h>
#include <freerdp/utils/rdpdr_utils.h>
#include <freerdp/channels/scard.h>
#include <freerdp/channels/rdpdr.h>
#include <freerdp/log.h>
#define TAG FREERDP_TAG("utils.scard")
LONG scard_log_status_error(const char* tag, const char* what, LONG status)
{
if (status != SCARD_S_SUCCESS)
{
DWORD level = WLOG_ERROR;
switch (status)
{
case SCARD_E_TIMEOUT:
level = WLOG_DEBUG;
break;
case SCARD_E_NO_READERS_AVAILABLE:
level = WLOG_INFO;
break;
default:
break;
}
WLog_Print(WLog_Get(tag), level, "%s failed with error %s [%" PRId32 "]", what,
SCardGetErrorString(status), status);
}
return status;
}
const char* scard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName)
{
switch (ioControlCode)
{
case SCARD_IOCTL_ESTABLISHCONTEXT:
return funcName ? "SCardEstablishContext" : "SCARD_IOCTL_ESTABLISHCONTEXT";
case SCARD_IOCTL_RELEASECONTEXT:
return funcName ? "SCardReleaseContext" : "SCARD_IOCTL_RELEASECONTEXT";
case SCARD_IOCTL_ISVALIDCONTEXT:
return funcName ? "SCardIsValidContext" : "SCARD_IOCTL_ISVALIDCONTEXT";
case SCARD_IOCTL_LISTREADERGROUPSA:
return funcName ? "SCardListReaderGroupsA" : "SCARD_IOCTL_LISTREADERGROUPSA";
case SCARD_IOCTL_LISTREADERGROUPSW:
return funcName ? "SCardListReaderGroupsW" : "SCARD_IOCTL_LISTREADERGROUPSW";
case SCARD_IOCTL_LISTREADERSA:
return funcName ? "SCardListReadersA" : "SCARD_IOCTL_LISTREADERSA";
case SCARD_IOCTL_LISTREADERSW:
return funcName ? "SCardListReadersW" : "SCARD_IOCTL_LISTREADERSW";
case SCARD_IOCTL_INTRODUCEREADERGROUPA:
return funcName ? "SCardIntroduceReaderGroupA" : "SCARD_IOCTL_INTRODUCEREADERGROUPA";
case SCARD_IOCTL_INTRODUCEREADERGROUPW:
return funcName ? "SCardIntroduceReaderGroupW" : "SCARD_IOCTL_INTRODUCEREADERGROUPW";
case SCARD_IOCTL_FORGETREADERGROUPA:
return funcName ? "SCardForgetReaderGroupA" : "SCARD_IOCTL_FORGETREADERGROUPA";
case SCARD_IOCTL_FORGETREADERGROUPW:
return funcName ? "SCardForgetReaderGroupW" : "SCARD_IOCTL_FORGETREADERGROUPW";
case SCARD_IOCTL_INTRODUCEREADERA:
return funcName ? "SCardIntroduceReaderA" : "SCARD_IOCTL_INTRODUCEREADERA";
case SCARD_IOCTL_INTRODUCEREADERW:
return funcName ? "SCardIntroduceReaderW" : "SCARD_IOCTL_INTRODUCEREADERW";
case SCARD_IOCTL_FORGETREADERA:
return funcName ? "SCardForgetReaderA" : "SCARD_IOCTL_FORGETREADERA";
case SCARD_IOCTL_FORGETREADERW:
return funcName ? "SCardForgetReaderW" : "SCARD_IOCTL_FORGETREADERW";
case SCARD_IOCTL_ADDREADERTOGROUPA:
return funcName ? "SCardAddReaderToGroupA" : "SCARD_IOCTL_ADDREADERTOGROUPA";
case SCARD_IOCTL_ADDREADERTOGROUPW:
return funcName ? "SCardAddReaderToGroupW" : "SCARD_IOCTL_ADDREADERTOGROUPW";
case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
return funcName ? "SCardRemoveReaderFromGroupA" : "SCARD_IOCTL_REMOVEREADERFROMGROUPA";
case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
return funcName ? "SCardRemoveReaderFromGroupW" : "SCARD_IOCTL_REMOVEREADERFROMGROUPW";
case SCARD_IOCTL_LOCATECARDSA:
return funcName ? "SCardLocateCardsA" : "SCARD_IOCTL_LOCATECARDSA";
case SCARD_IOCTL_LOCATECARDSW:
return funcName ? "SCardLocateCardsW" : "SCARD_IOCTL_LOCATECARDSW";
case SCARD_IOCTL_GETSTATUSCHANGEA:
return funcName ? "SCardGetStatusChangeA" : "SCARD_IOCTL_GETSTATUSCHANGEA";
case SCARD_IOCTL_GETSTATUSCHANGEW:
return funcName ? "SCardGetStatusChangeW" : "SCARD_IOCTL_GETSTATUSCHANGEW";
case SCARD_IOCTL_CANCEL:
return funcName ? "SCardCancel" : "SCARD_IOCTL_CANCEL";
case SCARD_IOCTL_CONNECTA:
return funcName ? "SCardConnectA" : "SCARD_IOCTL_CONNECTA";
case SCARD_IOCTL_CONNECTW:
return funcName ? "SCardConnectW" : "SCARD_IOCTL_CONNECTW";
case SCARD_IOCTL_RECONNECT:
return funcName ? "SCardReconnect" : "SCARD_IOCTL_RECONNECT";
case SCARD_IOCTL_DISCONNECT:
return funcName ? "SCardDisconnect" : "SCARD_IOCTL_DISCONNECT";
case SCARD_IOCTL_BEGINTRANSACTION:
return funcName ? "SCardBeginTransaction" : "SCARD_IOCTL_BEGINTRANSACTION";
case SCARD_IOCTL_ENDTRANSACTION:
return funcName ? "SCardEndTransaction" : "SCARD_IOCTL_ENDTRANSACTION";
case SCARD_IOCTL_STATE:
return funcName ? "SCardState" : "SCARD_IOCTL_STATE";
case SCARD_IOCTL_STATUSA:
return funcName ? "SCardStatusA" : "SCARD_IOCTL_STATUSA";
case SCARD_IOCTL_STATUSW:
return funcName ? "SCardStatusW" : "SCARD_IOCTL_STATUSW";
case SCARD_IOCTL_TRANSMIT:
return funcName ? "SCardTransmit" : "SCARD_IOCTL_TRANSMIT";
case SCARD_IOCTL_CONTROL:
return funcName ? "SCardControl" : "SCARD_IOCTL_CONTROL";
case SCARD_IOCTL_GETATTRIB:
return funcName ? "SCardGetAttrib" : "SCARD_IOCTL_GETATTRIB";
case SCARD_IOCTL_SETATTRIB:
return funcName ? "SCardSetAttrib" : "SCARD_IOCTL_SETATTRIB";
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
return funcName ? "SCardAccessStartedEvent" : "SCARD_IOCTL_ACCESSSTARTEDEVENT";
case SCARD_IOCTL_LOCATECARDSBYATRA:
return funcName ? "SCardLocateCardsByATRA" : "SCARD_IOCTL_LOCATECARDSBYATRA";
case SCARD_IOCTL_LOCATECARDSBYATRW:
return funcName ? "SCardLocateCardsByATRB" : "SCARD_IOCTL_LOCATECARDSBYATRW";
case SCARD_IOCTL_READCACHEA:
return funcName ? "SCardReadCacheA" : "SCARD_IOCTL_READCACHEA";
case SCARD_IOCTL_READCACHEW:
return funcName ? "SCardReadCacheW" : "SCARD_IOCTL_READCACHEW";
case SCARD_IOCTL_WRITECACHEA:
return funcName ? "SCardWriteCacheA" : "SCARD_IOCTL_WRITECACHEA";
case SCARD_IOCTL_WRITECACHEW:
return funcName ? "SCardWriteCacheW" : "SCARD_IOCTL_WRITECACHEW";
case SCARD_IOCTL_GETTRANSMITCOUNT:
return funcName ? "SCardGetTransmitCount" : "SCARD_IOCTL_GETTRANSMITCOUNT";
case SCARD_IOCTL_RELEASETARTEDEVENT:
return funcName ? "SCardReleaseStartedEvent" : "SCARD_IOCTL_RELEASETARTEDEVENT";
case SCARD_IOCTL_GETREADERICON:
return funcName ? "SCardGetReaderIcon" : "SCARD_IOCTL_GETREADERICON";
case SCARD_IOCTL_GETDEVICETYPEID:
return funcName ? "SCardGetDeviceTypeId" : "SCARD_IOCTL_GETDEVICETYPEID";
default:
return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN";
}
}
const char* rdpdr_component_string(UINT16 component)
{
switch (component)
{
case RDPDR_CTYP_PRN:
return "RDPDR_CTYP_PRN";
case RDPDR_CTYP_CORE:
return "RDPDR_CTYP_CORE";
default:
return "UNKNOWN";
}
}
const char* rdpdr_packetid_string(UINT16 packetid)
{
switch (packetid)
{
case PAKID_CORE_SERVER_ANNOUNCE:
return "PAKID_CORE_SERVER_ANNOUNCE";
case PAKID_CORE_CLIENTID_CONFIRM:
return "PAKID_CORE_CLIENTID_CONFIRM";
case PAKID_CORE_CLIENT_NAME:
return "PAKID_CORE_CLIENT_NAME";
case PAKID_CORE_DEVICELIST_ANNOUNCE:
return "PAKID_CORE_DEVICELIST_ANNOUNCE";
case PAKID_CORE_DEVICE_REPLY:
return "PAKID_CORE_DEVICE_REPLY";
case PAKID_CORE_DEVICE_IOREQUEST:
return "PAKID_CORE_DEVICE_IOREQUEST";
case PAKID_CORE_DEVICE_IOCOMPLETION:
return "PAKID_CORE_DEVICE_IOCOMPLETION";
case PAKID_CORE_SERVER_CAPABILITY:
return "PAKID_CORE_SERVER_CAPABILITY";
case PAKID_CORE_CLIENT_CAPABILITY:
return "PAKID_CORE_CLIENT_CAPABILITY";
case PAKID_CORE_DEVICELIST_REMOVE:
return "PAKID_CORE_DEVICELIST_REMOVE";
case PAKID_CORE_USER_LOGGEDON:
return "PAKID_CORE_USER_LOGGEDON";
case PAKID_PRN_CACHE_DATA:
return "PAKID_PRN_CACHE_DATA";
case PAKID_PRN_USING_XPS:
return "PAKID_PRN_USING_XPS";
default:
return "UNKNOWN";
}
}
BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 CompletionId,
UINT32 ioStatus)
{
WINPR_ASSERT(out);
Stream_SetPosition(out, 0);
if (!Stream_EnsureRemainingCapacity(out, 16))
return FALSE;
Stream_Write_UINT16(out, RDPDR_CTYP_CORE); /* Component (2 bytes) */
Stream_Write_UINT16(out, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */
Stream_Write_UINT32(out, DeviceId); /* DeviceId (4 bytes) */
Stream_Write_UINT32(out, CompletionId); /* CompletionId (4 bytes) */
Stream_Write_UINT32(out, ioStatus); /* IoStatus (4 bytes) */
return TRUE;
}
void rdpdr_dump_received_packet(wStream* s, const char* custom)
{
const size_t pos = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
if (Stream_Length(s) >= 4)
{
BOOL done = FALSE;
UINT16 component, packetid;
UINT32 deviceID = 0;
UINT32 FileId = 0;
UINT32 CompletionId = 0;
UINT32 MajorFunction = 0;
UINT32 MinorFunction = 0;
const size_t pos = Stream_GetPosition(s);
Stream_Read_UINT16(s, component);
Stream_Read_UINT16(s, packetid);
if (Stream_GetRemainingLength(s) >= 4)
Stream_Read_UINT32(s, deviceID);
if (component == RDPDR_CTYP_CORE)
{
if (packetid == PAKID_CORE_DEVICE_IOREQUEST)
{
if (Stream_GetRemainingLength(s) >= 16)
{
Stream_Read_UINT32(s, FileId); /* FileId (4 bytes) */
Stream_Read_UINT32(s, CompletionId); /* CompletionId (4 bytes) */
Stream_Read_UINT32(s, MajorFunction); /* MajorFunction (4 bytes) */
Stream_Read_UINT32(s, MinorFunction); /* MinorFunction (4 bytes) */
WLog_DBG(TAG,
"[%s] receive [%s | %s] [0x%08" PRIx32 "] FileID=0x%08" PRIx32
", CompletionID=0x%08" PRIx32 ", MajorFunction=%s [0x%08" PRIx32
"] -> %" PRIuz,
custom, rdpdr_component_string(component),
rdpdr_packetid_string(packetid), deviceID, FileId, CompletionId,
rdpdr_irp_string(MajorFunction), MinorFunction, deviceID,
Stream_Length(s));
done = TRUE;
}
}
}
Stream_SetPosition(s, pos);
if (!done)
{
WLog_DBG(TAG, "[%s] receive [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID,
Stream_Length(s));
}
winpr_HexDump(TAG, WLOG_TRACE, Stream_Buffer(s), Stream_Length(s));
}
Stream_SetPosition(s, pos);
}
void rdpdr_dump_send_packet(wStream* s, const char* custom)
{
WINPR_ASSERT(s);
if (Stream_Length(s) >= 8)
{
UINT16 component, packetid;
UINT32 deviceID;
const size_t pos = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
Stream_Read_UINT16(s, component);
Stream_Read_UINT16(s, packetid);
Stream_Read_UINT32(s, deviceID);
switch (packetid)
{
case PAKID_CORE_DEVICE_IOCOMPLETION:
{
UINT32 completionID, ioStatus;
Stream_Read_UINT32(s, completionID);
Stream_Read_UINT32(s, ioStatus);
WLog_DBG(TAG,
"[%s] sending [%s | %s] [0x%08" PRIx32 "] completionID=0x%08" PRIx32
", ioStatus=0x%08" PRIx32 " -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, completionID, ioStatus, pos);
}
break;
default:
WLog_DBG(TAG, "[%s] sending [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, pos);
break;
}
winpr_HexDump(TAG, WLOG_TRACE, Stream_Buffer(s), pos);
Stream_SetPosition(s, pos);
}
}
const char* rdpdr_irp_string(UINT32 major)
{
switch (major)
{
case IRP_MJ_CREATE:
return "IRP_MJ_CREATE";
case IRP_MJ_CLOSE:
return "IRP_MJ_CLOSE";
case IRP_MJ_READ:
return "IRP_MJ_READ";
case IRP_MJ_WRITE:
return "IRP_MJ_WRITE";
case IRP_MJ_DEVICE_CONTROL:
return "IRP_MJ_DEVICE_CONTROL";
case IRP_MJ_QUERY_VOLUME_INFORMATION:
return "IRP_MJ_QUERY_VOLUME_INFORMATION";
case IRP_MJ_SET_VOLUME_INFORMATION:
return "IRP_MJ_SET_VOLUME_INFORMATION";
case IRP_MJ_QUERY_INFORMATION:
return "IRP_MJ_QUERY_INFORMATION";
case IRP_MJ_SET_INFORMATION:
return "IRP_MJ_SET_INFORMATION";
case IRP_MJ_DIRECTORY_CONTROL:
return "IRP_MJ_DIRECTORY_CONTROL";
case IRP_MJ_LOCK_CONTROL:
return "IRP_MJ_LOCK_CONTROL";
default:
return "IRP_UNKNOWN";
}
}
const char* rdpdr_cap_type_string(UINT16 capability)
{
switch (capability)
{
case CAP_GENERAL_TYPE:
return "CAP_GENERAL_TYPE";
case CAP_PRINTER_TYPE:
return "CAP_PRINTER_TYPE";
case CAP_PORT_TYPE:
return "CAP_PORT_TYPE";
case CAP_DRIVE_TYPE:
return "CAP_DRIVE_TYPE";
case CAP_SMARTCARD_TYPE:
return "CAP_SMARTCARD_TYPE";
default:
return "CAP_UNKNOWN";
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff