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:
parent
803dd8f6ff
commit
3c72cc3306
@ -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;
|
||||
|
@ -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 |
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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 */
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
41
include/freerdp/utils/rdpdr_utils.h
Normal file
41
include/freerdp/utils/rdpdr_utils.h
Normal 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
|
54
include/freerdp/utils/smartcard_call.h
Normal file
54
include/freerdp/utils/smartcard_call.h
Normal 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 */
|
89
include/freerdp/utils/smartcard_operations.h
Normal file
89
include/freerdp/utils/smartcard_operations.h
Normal 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 */
|
168
include/freerdp/utils/smartcard_pack.h
Normal file
168
include/freerdp/utils/smartcard_pack.h
Normal 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 */
|
@ -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})
|
||||
|
416
libfreerdp/utils/rdpdr_utils.c
Normal file
416
libfreerdp/utils/rdpdr_utils.c
Normal 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";
|
||||
}
|
||||
}
|
1950
libfreerdp/utils/smartcard_call.c
Normal file
1950
libfreerdp/utils/smartcard_call.c
Normal file
File diff suppressed because it is too large
Load Diff
1058
libfreerdp/utils/smartcard_operations.c
Normal file
1058
libfreerdp/utils/smartcard_operations.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user