mirror of https://github.com/FreeRDP/FreeRDP
Merge branch 'master' of github.com:FreeRDP/FreeRDP
This commit is contained in:
commit
94f2a52196
|
@ -341,6 +341,8 @@ else()
|
|||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
endif()
|
||||
|
||||
find_package(PCSCWinPR)
|
||||
|
||||
set(X11_FEATURE_PURPOSE "X11")
|
||||
set(X11_FEATURE_DESCRIPTION "X11 client and server")
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "devman.h"
|
||||
|
||||
static void devman_device_free(DEVICE* device)
|
||||
void devman_device_free(DEVICE* device)
|
||||
{
|
||||
IFCALL(device->Free, device);
|
||||
}
|
||||
|
@ -71,7 +71,8 @@ void devman_unregister_device(DEVMAN* devman, void* key)
|
|||
{
|
||||
DEVICE* device;
|
||||
|
||||
device = (DEVICE *)ListDictionary_Remove(devman->devices, key);
|
||||
device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
|
||||
|
||||
if (device)
|
||||
devman_device_free(device);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
static void irp_free(IRP* irp)
|
||||
{
|
||||
if (!irp)
|
||||
return;
|
||||
|
||||
Stream_Free(irp->input, TRUE);
|
||||
Stream_Free(irp->output, TRUE);
|
||||
|
||||
|
@ -46,8 +49,8 @@ static void irp_complete(IRP* irp)
|
|||
int pos;
|
||||
|
||||
pos = (int) Stream_GetPosition(irp->output);
|
||||
Stream_SetPosition(irp->output, 12);
|
||||
Stream_Write_UINT32(irp->output, irp->IoStatus);
|
||||
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4);
|
||||
Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */
|
||||
Stream_SetPosition(irp->output, pos);
|
||||
|
||||
rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output);
|
||||
|
@ -59,37 +62,39 @@ static void irp_complete(IRP* irp)
|
|||
IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
{
|
||||
IRP* irp;
|
||||
UINT32 DeviceId;
|
||||
DEVICE* device;
|
||||
UINT32 DeviceId;
|
||||
|
||||
Stream_Read_UINT32(s, DeviceId);
|
||||
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
|
||||
device = devman_get_device_by_id(devman, DeviceId);
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
ZeroMemory(irp, sizeof(IRP));
|
||||
|
||||
irp->input = s;
|
||||
irp->device = device;
|
||||
irp->devman = devman;
|
||||
Stream_Read_UINT32(s, irp->FileId);
|
||||
Stream_Read_UINT32(s, irp->CompletionId);
|
||||
Stream_Read_UINT32(s, irp->MajorFunction);
|
||||
Stream_Read_UINT32(s, irp->MinorFunction);
|
||||
irp->input = s;
|
||||
|
||||
Stream_Read_UINT32(s, irp->FileId); /* FileId (4 bytes) */
|
||||
Stream_Read_UINT32(s, irp->CompletionId); /* CompletionId (4 bytes) */
|
||||
Stream_Read_UINT32(s, irp->MajorFunction); /* MajorFunction (4 bytes) */
|
||||
Stream_Read_UINT32(s, irp->MinorFunction); /* MinorFunction (4 bytes) */
|
||||
|
||||
irp->output = Stream_New(NULL, 256);
|
||||
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION);
|
||||
Stream_Write_UINT32(irp->output, DeviceId);
|
||||
Stream_Write_UINT32(irp->output, irp->CompletionId);
|
||||
Stream_Seek_UINT32(irp->output); /* IoStatus */
|
||||
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) */
|
||||
|
||||
irp->Complete = irp_complete;
|
||||
irp->Discard = irp_free;
|
||||
|
||||
irp->thread = NULL;
|
||||
irp->cancelled = FALSE;
|
||||
|
||||
return irp;
|
||||
}
|
||||
|
|
|
@ -680,6 +680,26 @@ static BOOL rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void rdpdr_process_init(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
int index;
|
||||
int keyCount;
|
||||
DEVICE* device;
|
||||
ULONG_PTR* pKeys;
|
||||
|
||||
pKeys = NULL;
|
||||
keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys);
|
||||
|
||||
for (index = 0; index < keyCount; index++)
|
||||
{
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]);
|
||||
|
||||
IFCALL(device->Init, device);
|
||||
}
|
||||
|
||||
free(pKeys);
|
||||
}
|
||||
|
||||
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 component;
|
||||
|
@ -698,6 +718,7 @@ static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||
rdpdr_process_server_announce_request(rdpdr, s);
|
||||
rdpdr_send_client_announce_reply(rdpdr);
|
||||
rdpdr_send_client_name_request(rdpdr);
|
||||
rdpdr_process_init(rdpdr);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
|
||||
set(OPTION_DEFAULT OFF)
|
||||
set(OPTION_CLIENT_DEFAULT OFF)
|
||||
set(OPTION_CLIENT_DEFAULT ON)
|
||||
set(OPTION_SERVER_DEFAULT OFF)
|
||||
|
||||
if(WITH_PCSC)
|
||||
set(OPTION_CLIENT_DEFAULT ON)
|
||||
set(OPTION_SERVER_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
define_channel_options(NAME "smartcard" TYPE "device"
|
||||
DESCRIPTION "Smart Card Virtual Channel Extension"
|
||||
SPECIFICATIONS "[MS-RDPESC]"
|
||||
|
|
|
@ -20,11 +20,11 @@ define_channel_client("smartcard")
|
|||
set(${MODULE_PREFIX}_SRCS
|
||||
smartcard_main.c
|
||||
smartcard_main.h
|
||||
smartcard_pack.c
|
||||
smartcard_pack.h
|
||||
smartcard_operations.c)
|
||||
|
||||
include_directories(${PCSC_INCLUDE_DIR})
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DeviceServiceEntry")
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DeviceServiceEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -36,13 +36,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
|||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-synch winpr-thread winpr-interlocked)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PCSC_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND ${MODULE_PREFIX}_LIBS winscard)
|
||||
endif()
|
||||
MODULES winpr-crt winpr-smartcard winpr-synch winpr-thread winpr-interlocked winpr-utils)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
|
|
@ -28,300 +28,199 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
#include "smartcard_main.h"
|
||||
|
||||
static void smartcard_free(DEVICE* dev)
|
||||
{
|
||||
IRP* irp;
|
||||
COMPLETIONIDINFO* CompletionIdInfo;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) dev;
|
||||
#define SMARTCARD_ASYNC_IRP 1
|
||||
|
||||
SetEvent(smartcard->stopEvent);
|
||||
static void smartcard_free(DEVICE* device)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
|
||||
MessageQueue_PostQuit(smartcard->IrpQueue, 0);
|
||||
WaitForSingleObject(smartcard->thread, INFINITE);
|
||||
|
||||
while ((irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList)) != NULL)
|
||||
irp->Discard(irp);
|
||||
|
||||
_aligned_free(smartcard->pIrpList);
|
||||
|
||||
/* Begin TS Client defect workaround. */
|
||||
|
||||
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(smartcard->CompletionIds)) != NULL)
|
||||
free(CompletionIdInfo);
|
||||
|
||||
CloseHandle(smartcard->thread);
|
||||
CloseHandle(smartcard->irpEvent);
|
||||
CloseHandle(smartcard->stopEvent);
|
||||
CloseHandle(smartcard->CompletionIdsMutex);
|
||||
|
||||
Stream_Free(smartcard->device.data, TRUE);
|
||||
list_free(smartcard->CompletionIds);
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
MessageQueue_Free(smartcard->IrpQueue);
|
||||
ListDictionary_Free(smartcard->OutstandingIrps);
|
||||
|
||||
free(dev);
|
||||
free(device);
|
||||
}
|
||||
|
||||
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
{
|
||||
switch (irp->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
smartcard_device_control(smartcard, irp);
|
||||
break;
|
||||
/**
|
||||
* Initialization occurs when the protocol server sends a device announce message.
|
||||
* At that time, we need to cancel all outstanding IRPs.
|
||||
*/
|
||||
|
||||
default:
|
||||
fprintf(stderr, "MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
|
||||
DEBUG_WARN("Smartcard MajorFunction 0x%X not supported.", irp->MajorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
irp->Complete(irp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void smartcard_process_irp_list(SMARTCARD_DEVICE* smartcard)
|
||||
static void smartcard_init(DEVICE* device)
|
||||
{
|
||||
IRP* irp;
|
||||
int index;
|
||||
int keyCount;
|
||||
ULONG_PTR* pKeys;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
|
||||
while (1)
|
||||
if (ListDictionary_Count(smartcard->OutstandingIrps) > 0)
|
||||
{
|
||||
if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
pKeys = NULL;
|
||||
keyCount = ListDictionary_GetKeys(smartcard->OutstandingIrps, &pKeys);
|
||||
|
||||
irp = (IRP*) InterlockedPopEntrySList(smartcard->pIrpList);
|
||||
for (index = 0; index < keyCount; index++)
|
||||
{
|
||||
irp = (IRP*) ListDictionary_GetItemValue(smartcard->OutstandingIrps, (void*) pKeys[index]);
|
||||
|
||||
if (irp == NULL)
|
||||
break;
|
||||
if (irp)
|
||||
irp->cancelled = TRUE;
|
||||
}
|
||||
|
||||
smartcard_process_irp(smartcard, irp);
|
||||
free(pKeys);
|
||||
}
|
||||
}
|
||||
|
||||
struct _SMARTCARD_IRP_WORKER
|
||||
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
{
|
||||
void* key;
|
||||
|
||||
key = (void*) (size_t) irp->CompletionId;
|
||||
ListDictionary_Remove(smartcard->OutstandingIrps, key);
|
||||
|
||||
if (!irp->cancelled)
|
||||
irp->Complete(irp);
|
||||
else
|
||||
irp->Discard(irp);
|
||||
}
|
||||
|
||||
void* smartcard_process_irp_worker_proc(IRP* irp)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
IRP* irp;
|
||||
HANDLE thread;
|
||||
};
|
||||
typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER;
|
||||
|
||||
static void *smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker)
|
||||
{
|
||||
smartcard_process_irp(irpWorker->smartcard, irpWorker->irp);
|
||||
|
||||
CloseHandle(irpWorker->thread);
|
||||
smartcard = (SMARTCARD_DEVICE*) irp->device;
|
||||
|
||||
free(irpWorker);
|
||||
smartcard_irp_device_control(smartcard, irp);
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiple threads and SCardGetStatusChange:
|
||||
* http://musclecard.996296.n3.nabble.com/Multiple-threads-and-SCardGetStatusChange-td4430.html
|
||||
*/
|
||||
|
||||
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
{
|
||||
void* key;
|
||||
BOOL asyncIrp = FALSE;
|
||||
UINT32 ioControlCode = 0;
|
||||
|
||||
key = (void*) (size_t) irp->CompletionId;
|
||||
ListDictionary_Add(smartcard->OutstandingIrps, key, irp);
|
||||
|
||||
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||
{
|
||||
smartcard_irp_device_control_peek_io_control_code(smartcard, irp, &ioControlCode);
|
||||
|
||||
if (!ioControlCode)
|
||||
return;
|
||||
|
||||
#ifdef SMARTCARD_ASYNC_IRP
|
||||
asyncIrp = TRUE;
|
||||
|
||||
switch (ioControlCode)
|
||||
{
|
||||
case SCARD_IOCTL_ESTABLISHCONTEXT:
|
||||
case SCARD_IOCTL_RELEASECONTEXT:
|
||||
case SCARD_IOCTL_ISVALIDCONTEXT:
|
||||
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
|
||||
case SCARD_IOCTL_RELEASESTARTEDEVENT:
|
||||
asyncIrp = FALSE;
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_TRANSMIT:
|
||||
case SCARD_IOCTL_STATUSA:
|
||||
case SCARD_IOCTL_STATUSW:
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEA:
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEW:
|
||||
asyncIrp = TRUE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!asyncIrp)
|
||||
{
|
||||
smartcard_irp_device_control(smartcard, irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
irp->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) smartcard_process_irp_worker_proc,
|
||||
irp, 0, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
|
||||
irp->MajorFunction, irp->MinorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
smartcard_complete_irp(smartcard, irp);
|
||||
}
|
||||
}
|
||||
|
||||
static void* smartcard_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
wMessage message;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
|
||||
HANDLE ev[] = {smartcard->irpEvent, smartcard->stopEvent};
|
||||
|
||||
while (1)
|
||||
{
|
||||
DWORD status = WaitForMultipleObjects(2, ev, FALSE, INFINITE);
|
||||
|
||||
if (status == WAIT_OBJECT_0 + 1)
|
||||
if (!MessageQueue_Wait(smartcard->IrpQueue))
|
||||
break;
|
||||
else if(status != WAIT_OBJECT_0)
|
||||
continue;
|
||||
|
||||
ResetEvent(smartcard->irpEvent);
|
||||
smartcard_process_irp_list(smartcard);
|
||||
if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE))
|
||||
break;
|
||||
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
irp = (IRP*) message.wParam;
|
||||
|
||||
if (irp)
|
||||
smartcard_process_irp(smartcard, irp);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Begin TS Client defect workaround. */
|
||||
static COMPLETIONIDINFO* smartcard_mark_duplicate_id(SMARTCARD_DEVICE* smartcard, UINT32 CompletionId)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
COMPLETIONIDINFO* CompletionIdInfo;
|
||||
|
||||
/*
|
||||
* Search from the beginning of the LIST for one outstanding "CompletionID"
|
||||
* that matches the one passed in. If there is one, mark it as a duplicate
|
||||
* if it is not already marked.
|
||||
*/
|
||||
|
||||
for (item = smartcard->CompletionIds->head; item; item = item->next)
|
||||
{
|
||||
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
|
||||
|
||||
if (CompletionIdInfo->ID == CompletionId)
|
||||
{
|
||||
if (!CompletionIdInfo->duplicate)
|
||||
{
|
||||
CompletionIdInfo->duplicate = TRUE;
|
||||
DEBUG_WARN("CompletionID number %u is now marked as a duplicate.", CompletionId);
|
||||
}
|
||||
|
||||
return CompletionIdInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* Either no items in the list or no match. */
|
||||
}
|
||||
|
||||
static BOOL smartcard_check_for_duplicate_id(SMARTCARD_DEVICE* smartcard, UINT32 CompletionId)
|
||||
{
|
||||
BOOL duplicate;
|
||||
LIST_ITEM* item;
|
||||
COMPLETIONIDINFO* CompletionIdInfo;
|
||||
|
||||
/*
|
||||
* Search from the end of the LIST for one outstanding "CompletionID"
|
||||
* that matches the one passed in. Remove it from the list and free the
|
||||
* memory associated with it. Return whether or not it was marked
|
||||
* as a duplicate.
|
||||
*/
|
||||
|
||||
for (item = smartcard->CompletionIds->tail; item; item = item->prev)
|
||||
{
|
||||
CompletionIdInfo = (COMPLETIONIDINFO*) item->data;
|
||||
|
||||
if (CompletionIdInfo->ID == CompletionId)
|
||||
{
|
||||
duplicate = CompletionIdInfo->duplicate;
|
||||
|
||||
if (duplicate)
|
||||
{
|
||||
DEBUG_WARN("CompletionID number %u was previously marked as a duplicate.", CompletionId);
|
||||
}
|
||||
|
||||
list_remove(smartcard->CompletionIds, CompletionIdInfo);
|
||||
free(CompletionIdInfo);
|
||||
|
||||
return duplicate;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function should only be called when there is
|
||||
* at least one outstanding CompletionID item in the list.
|
||||
*/
|
||||
DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void smartcard_irp_complete(IRP* irp)
|
||||
{
|
||||
int pos;
|
||||
BOOL duplicate;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) irp->device;
|
||||
|
||||
/* This function is (mostly) a copy of the statically-declared "irp_complete()"
|
||||
* function except that this function adds extra operations for the
|
||||
* smart card's handling of duplicate "CompletionID"s. This function needs
|
||||
* to be in this file so that "smartcard_irp_request()" can reference it.
|
||||
*/
|
||||
|
||||
DEBUG_SCARD("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
||||
|
||||
pos = Stream_GetPosition(irp->output);
|
||||
Stream_SetPosition(irp->output, 12);
|
||||
Stream_Write_UINT32(irp->output, irp->IoStatus);
|
||||
Stream_SetPosition(irp->output, pos);
|
||||
|
||||
/* Begin TS Client defect workaround. */
|
||||
WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE);
|
||||
/* Remove from the list the item identified by the CompletionID.
|
||||
* The function returns whether or not it was a duplicate CompletionID.
|
||||
*/
|
||||
duplicate = smartcard_check_for_duplicate_id(smartcard, irp->CompletionId);
|
||||
ReleaseMutex(smartcard->CompletionIdsMutex);
|
||||
|
||||
if (!duplicate)
|
||||
{
|
||||
irp->Complete(irp);
|
||||
}
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
|
||||
/* irp_free(irp); The "irp_free()" function is statically-declared
|
||||
* and so is not available to be called
|
||||
* here. Instead, call it indirectly by calling
|
||||
* the IRP's "Discard()" function,
|
||||
* which has already been assigned
|
||||
* to point to "irp_free()" in "irp_new()".
|
||||
*/
|
||||
irp->Discard(irp);
|
||||
}
|
||||
/* End TS Client defect workaround. */
|
||||
|
||||
static void smartcard_irp_request(DEVICE* device, IRP* irp)
|
||||
{
|
||||
COMPLETIONIDINFO* CompletionIdInfo;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
|
||||
/* Begin TS Client defect workaround. */
|
||||
|
||||
CompletionIdInfo = (COMPLETIONIDINFO*) malloc(sizeof(COMPLETIONIDINFO));
|
||||
ZeroMemory(CompletionIdInfo, sizeof(COMPLETIONIDINFO));
|
||||
|
||||
CompletionIdInfo->ID = irp->CompletionId;
|
||||
|
||||
WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE);
|
||||
smartcard_mark_duplicate_id(smartcard, irp->CompletionId);
|
||||
list_enqueue(smartcard->CompletionIds, CompletionIdInfo);
|
||||
ReleaseMutex(smartcard->CompletionIdsMutex);
|
||||
|
||||
/* Overwrite the previous assignment made in irp_new() */
|
||||
irp->Complete = smartcard_irp_complete;
|
||||
|
||||
/* End TS Client defect workaround. */
|
||||
|
||||
if ((irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) && smartcard_async_op(irp))
|
||||
{
|
||||
/* certain potentially long running operations get their own thread */
|
||||
SMARTCARD_IRP_WORKER* irpWorker = malloc(sizeof(SMARTCARD_IRP_WORKER));
|
||||
|
||||
irpWorker->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) smartcard_process_irp_thread_func,
|
||||
irpWorker, CREATE_SUSPENDED, NULL);
|
||||
|
||||
irpWorker->smartcard = smartcard;
|
||||
irpWorker->irp = irp;
|
||||
|
||||
ResumeThread(irpWorker->thread);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
InterlockedPushEntrySList(smartcard->pIrpList, &(irp->ItemEntry));
|
||||
|
||||
SetEvent(smartcard->irpEvent);
|
||||
MessageQueue_Post(smartcard->IrpQueue, NULL, 0, (void*) irp, NULL);
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
/* smartcard is always built-in */
|
||||
#define DeviceServiceEntry smartcard_DeviceServiceEntry
|
||||
#endif
|
||||
|
||||
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
char* name;
|
||||
char* path;
|
||||
int i, length, ck;
|
||||
int length, ck;
|
||||
RDPDR_SMARTCARD* device;
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
|
||||
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
|
||||
|
||||
name = device->Name;
|
||||
path = device->Path;
|
||||
|
||||
/* TODO: check if server supports sc redirect (version 5.1) */
|
||||
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
||||
|
||||
if (!smartcard)
|
||||
|
@ -330,6 +229,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
|
||||
smartcard->device.name = "SCARD";
|
||||
smartcard->device.IRPRequest = smartcard_irp_request;
|
||||
smartcard->device.Init = smartcard_init;
|
||||
smartcard->device.Free = smartcard_free;
|
||||
|
||||
length = strlen(smartcard->device.name);
|
||||
|
@ -353,17 +253,16 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||
smartcard->name = name;
|
||||
}
|
||||
|
||||
smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
InitializeSListHead(smartcard->pIrpList);
|
||||
smartcard->log = WLog_Get("com.freerdp.channel.smartcard.client");
|
||||
|
||||
WLog_SetLogLevel(smartcard->log, WLOG_DEBUG);
|
||||
|
||||
smartcard->IrpQueue = MessageQueue_New(NULL);
|
||||
smartcard->OutstandingIrps = ListDictionary_New(TRUE);
|
||||
|
||||
smartcard->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
smartcard->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func,
|
||||
smartcard, CREATE_SUSPENDED, NULL);
|
||||
|
||||
smartcard->CompletionIds = list_new();
|
||||
smartcard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard);
|
||||
|
||||
ResumeThread(smartcard->thread);
|
||||
|
|
|
@ -21,101 +21,87 @@
|
|||
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/smartcard.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
/*
|
||||
* When using Windows Server 2008 R2 as the Terminal Services (TS)
|
||||
* server, and with a smart card reader connected to the TS client machine
|
||||
* and used to authenticate to an existing login session, the TS server
|
||||
* will initiate the protocol initialization of MS-RDPEFS, Section 1.3.1,
|
||||
* twice as it re-establishes a connection. The TS server starts both
|
||||
* initializations with a "Server Announce Request" message.
|
||||
* When the TS client receives this message, as per Section 3.2.5.1.2,
|
||||
*
|
||||
* The client SHOULD treat this packet as the beginning
|
||||
* of a new sequence. The client SHOULD also cancel all
|
||||
* outstanding requests and release previous references to
|
||||
* all devices.
|
||||
*
|
||||
* As of this writing, the code does not cancel all outstanding requests.
|
||||
* This leads to a problem where, after the first MS-RDPEFS initialization,
|
||||
* the TS server sends an SCARD_IOCTL_GETSTATUSCHANGEx control in a message
|
||||
* that uses an available "CompletionID". The
|
||||
* TS client doesn't respond immediately because it is blocking while
|
||||
* waiting for a change in the smart card's status in the reader.
|
||||
* Then the TS server initiates a second MS-RDPEFS initialization sequence.
|
||||
* As noted above, this should cancel the outstanding
|
||||
* SCARD_IOCTL_GETSTATUSCHANGEx request, but it does not.
|
||||
* At this point, the TS server is free to reuse the previously used
|
||||
* "CompletionID", and it does reuse it for other SCARD_IOCTLs.
|
||||
* Therefore, when the user removes (for example) the card from the reader,
|
||||
* the TS client sends an "IOCompetion" message in response to the
|
||||
* GETSTATUSCHANGEx using the original "CompletionID". The TS server does not
|
||||
* expect this "CompletionID" and so, as per Section 3.1.5.2 of MS-RDPEFS,
|
||||
* it treats that "IOCompletion" message as an error and terminates the
|
||||
* virtual channel.
|
||||
*
|
||||
* The following structure is part of a work-around for this missing
|
||||
* capability of canceling outstanding requests. This work-around
|
||||
* allows the TS client to send an "IOCompletion" back to the
|
||||
* TS server for the second (and subsequent) SCARD_IOCTLs that use
|
||||
* the same "CompletionID" as the still outstanding
|
||||
* SCARD_IOCTL_GETSTATUSCHANGEx. The work-around in the TS client
|
||||
* prevents the client from sending the "IOCompletion" back (when
|
||||
* the user removes the card) for the SCARD_IOCTL_GETSTATUSCHANGEx.
|
||||
*
|
||||
* This TS client expects the responses from the PCSC daemon for the second
|
||||
* and subsequent SCARD_IOCTLs that use the same "CompletionID"
|
||||
* to arrive at the TS client before the daemon's response to the
|
||||
* SCARD_IOCTL_GETSTATUSCHANGEx. This is a race condition.
|
||||
*
|
||||
* The "CompletionIDs" are a global pool of IDs across all "DeviceIDs".
|
||||
* However, this problem of duplicate "CompletionIDs" only affects smart cards.
|
||||
*
|
||||
* This structure tracks outstanding Terminal Services server "CompletionIDs"
|
||||
* used by the redirected smart card device.
|
||||
*/
|
||||
#define RDP_SCARD_CTL_CODE(code) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, (code), METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
struct _COMPLETIONIDINFO
|
||||
{
|
||||
UINT32 ID; /* CompletionID */
|
||||
BOOL duplicate; /* Indicates whether or not this
|
||||
* CompletionID is a duplicate of an
|
||||
* earlier, outstanding, CompletionID.
|
||||
*/
|
||||
};
|
||||
typedef struct _COMPLETIONIDINFO COMPLETIONIDINFO;
|
||||
#define SCARD_IOCTL_ESTABLISHCONTEXT RDP_SCARD_CTL_CODE(5) /* SCardEstablishContext */
|
||||
#define SCARD_IOCTL_RELEASECONTEXT RDP_SCARD_CTL_CODE(6) /* SCardReleaseContext */
|
||||
#define SCARD_IOCTL_ISVALIDCONTEXT RDP_SCARD_CTL_CODE(7) /* SCardIsValidContext */
|
||||
#define SCARD_IOCTL_LISTREADERGROUPSA RDP_SCARD_CTL_CODE(8) /* SCardListReaderGroupsA */
|
||||
#define SCARD_IOCTL_LISTREADERGROUPSW RDP_SCARD_CTL_CODE(9) /* SCardListReaderGroupsW */
|
||||
#define SCARD_IOCTL_LISTREADERSA RDP_SCARD_CTL_CODE(10) /* SCardListReadersA */
|
||||
#define SCARD_IOCTL_LISTREADERSW RDP_SCARD_CTL_CODE(11) /* SCardListReadersW */
|
||||
#define SCARD_IOCTL_INTRODUCEREADERGROUPA RDP_SCARD_CTL_CODE(20) /* SCardIntroduceReaderGroupA */
|
||||
#define SCARD_IOCTL_INTRODUCEREADERGROUPW RDP_SCARD_CTL_CODE(21) /* SCardIntroduceReaderGroupW */
|
||||
#define SCARD_IOCTL_FORGETREADERGROUPA RDP_SCARD_CTL_CODE(22) /* SCardForgetReaderGroupA */
|
||||
#define SCARD_IOCTL_FORGETREADERGROUPW RDP_SCARD_CTL_CODE(23) /* SCardForgetReaderGroupW */
|
||||
#define SCARD_IOCTL_INTRODUCEREADERA RDP_SCARD_CTL_CODE(24) /* SCardIntroduceReaderA */
|
||||
#define SCARD_IOCTL_INTRODUCEREADERW RDP_SCARD_CTL_CODE(25) /* SCardIntroduceReaderW */
|
||||
#define SCARD_IOCTL_FORGETREADERA RDP_SCARD_CTL_CODE(26) /* SCardForgetReaderA */
|
||||
#define SCARD_IOCTL_FORGETREADERW RDP_SCARD_CTL_CODE(27) /* SCardForgetReaderW */
|
||||
#define SCARD_IOCTL_ADDREADERTOGROUPA RDP_SCARD_CTL_CODE(28) /* SCardAddReaderToGroupA */
|
||||
#define SCARD_IOCTL_ADDREADERTOGROUPW RDP_SCARD_CTL_CODE(29) /* SCardAddReaderToGroupW */
|
||||
#define SCARD_IOCTL_REMOVEREADERFROMGROUPA RDP_SCARD_CTL_CODE(30) /* SCardRemoveReaderFromGroupA */
|
||||
#define SCARD_IOCTL_REMOVEREADERFROMGROUPW RDP_SCARD_CTL_CODE(31) /* SCardRemoveReaderFromGroupW */
|
||||
#define SCARD_IOCTL_LOCATECARDSA RDP_SCARD_CTL_CODE(38) /* SCardLocateCardsA */
|
||||
#define SCARD_IOCTL_LOCATECARDSW RDP_SCARD_CTL_CODE(39) /* SCardLocateCardsW */
|
||||
#define SCARD_IOCTL_GETSTATUSCHANGEA RDP_SCARD_CTL_CODE(40) /* SCardGetStatusChangeA */
|
||||
#define SCARD_IOCTL_GETSTATUSCHANGEW RDP_SCARD_CTL_CODE(41) /* SCardGetStatusChangeW */
|
||||
#define SCARD_IOCTL_CANCEL RDP_SCARD_CTL_CODE(42) /* SCardCancel */
|
||||
#define SCARD_IOCTL_CONNECTA RDP_SCARD_CTL_CODE(43) /* SCardConnectA */
|
||||
#define SCARD_IOCTL_CONNECTW RDP_SCARD_CTL_CODE(44) /* SCardConnectW */
|
||||
#define SCARD_IOCTL_RECONNECT RDP_SCARD_CTL_CODE(45) /* SCardReconnect */
|
||||
#define SCARD_IOCTL_DISCONNECT RDP_SCARD_CTL_CODE(46) /* SCardDisconnect */
|
||||
#define SCARD_IOCTL_BEGINTRANSACTION RDP_SCARD_CTL_CODE(47) /* SCardBeginTransaction */
|
||||
#define SCARD_IOCTL_ENDTRANSACTION RDP_SCARD_CTL_CODE(48) /* SCardEndTransaction */
|
||||
#define SCARD_IOCTL_STATE RDP_SCARD_CTL_CODE(49) /* SCardState */
|
||||
#define SCARD_IOCTL_STATUSA RDP_SCARD_CTL_CODE(50) /* SCardStatusA */
|
||||
#define SCARD_IOCTL_STATUSW RDP_SCARD_CTL_CODE(51) /* SCardStatusW */
|
||||
#define SCARD_IOCTL_TRANSMIT RDP_SCARD_CTL_CODE(52) /* SCardTransmit */
|
||||
#define SCARD_IOCTL_CONTROL RDP_SCARD_CTL_CODE(53) /* SCardControl */
|
||||
#define SCARD_IOCTL_GETATTRIB RDP_SCARD_CTL_CODE(54) /* SCardGetAttrib */
|
||||
#define SCARD_IOCTL_SETATTRIB RDP_SCARD_CTL_CODE(55) /* SCardSetAttrib */
|
||||
#define SCARD_IOCTL_ACCESSSTARTEDEVENT RDP_SCARD_CTL_CODE(56) /* SCardAccessStartedEvent */
|
||||
#define SCARD_IOCTL_LOCATECARDSBYATRA RDP_SCARD_CTL_CODE(58) /* SCardLocateCardsByATRA */
|
||||
#define SCARD_IOCTL_LOCATECARDSBYATRW RDP_SCARD_CTL_CODE(59) /* SCardLocateCardsByATRW */
|
||||
#define SCARD_IOCTL_READCACHEA RDP_SCARD_CTL_CODE(60) /* SCardReadCacheA */
|
||||
#define SCARD_IOCTL_READCACHEW RDP_SCARD_CTL_CODE(61) /* SCardReadCacheW */
|
||||
#define SCARD_IOCTL_WRITECACHEA RDP_SCARD_CTL_CODE(62) /* SCardWriteCacheA */
|
||||
#define SCARD_IOCTL_WRITECACHEW RDP_SCARD_CTL_CODE(63) /* SCardWriteCacheW */
|
||||
#define SCARD_IOCTL_GETTRANSMITCOUNT RDP_SCARD_CTL_CODE(64) /* SCardGetTransmitCount */
|
||||
#define SCARD_IOCTL_RELEASESTARTEDEVENT RDP_SCARD_CTL_CODE(66) /* SCardReleaseStartedEvent */
|
||||
#define SCARD_IOCTL_GETREADERICON RDP_SCARD_CTL_CODE(67) /* SCardGetReaderIconA */
|
||||
#define SCARD_IOCTL_GETDEVICETYPEID RDP_SCARD_CTL_CODE(68) /* SCardGetDeviceTypeIdA */
|
||||
|
||||
struct _SMARTCARD_DEVICE
|
||||
{
|
||||
DEVICE device;
|
||||
|
||||
wLog* log;
|
||||
|
||||
char* name;
|
||||
char* path;
|
||||
|
||||
PSLIST_HEADER pIrpList;
|
||||
|
||||
HANDLE thread;
|
||||
HANDLE irpEvent;
|
||||
HANDLE stopEvent;
|
||||
|
||||
LIST* CompletionIds;
|
||||
HANDLE CompletionIdsMutex;
|
||||
wMessageQueue* IrpQueue;
|
||||
wListDictionary* OutstandingIrps;
|
||||
};
|
||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||
|
||||
#ifdef WITH_DEBUG_SCARD
|
||||
#define DEBUG_SCARD(fmt, ...) DEBUG_CLASS(SCARD, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_SCARD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
|
||||
BOOL smartcard_async_op(IRP*);
|
||||
void smartcard_device_control(SMARTCARD_DEVICE*, IRP*);
|
||||
void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
void smartcard_irp_device_control_peek_io_control_code(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* ioControlCode);
|
||||
|
||||
#include "smartcard_pack.h"
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,528 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Smart Card Structure Packing
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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_CLIENT_PACK_H
|
||||
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include "smartcard_main.h"
|
||||
|
||||
/* interface type_scard_pack */
|
||||
/* [unique][version][uuid] */
|
||||
|
||||
typedef struct _REDIR_SCARDCONTEXT
|
||||
{
|
||||
/* [range] */ DWORD cbContext;
|
||||
/* [size_is][unique] */ BYTE pbContext[8];
|
||||
} REDIR_SCARDCONTEXT;
|
||||
|
||||
typedef struct _REDIR_SCARDHANDLE
|
||||
{
|
||||
/* [range] */ DWORD cbHandle;
|
||||
/* [size_is] */ BYTE pbHandle[8];
|
||||
} REDIR_SCARDHANDLE;
|
||||
|
||||
typedef struct _Long_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
} Long_Return;
|
||||
|
||||
typedef struct _longAndMultiString_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cBytes;
|
||||
/* [size_is][unique] */ BYTE *msz;
|
||||
} ListReaderGroups_Return;
|
||||
|
||||
typedef struct _longAndMultiString_Return ListReaders_Return;
|
||||
|
||||
typedef struct _Context_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
} Context_Call;
|
||||
|
||||
typedef struct _ContextAndStringA_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [string] */ unsigned char *sz;
|
||||
} ContextAndStringA_Call;
|
||||
|
||||
typedef struct _ContextAndStringW_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [string] */ WCHAR *sz;
|
||||
} ContextAndStringW_Call;
|
||||
|
||||
typedef struct _ContextAndTwoStringA_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [string] */ unsigned char *sz1;
|
||||
/* [string] */ unsigned char *sz2;
|
||||
} ContextAndTwoStringA_Call;
|
||||
|
||||
typedef struct _ContextAndTwoStringW_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [string] */ WCHAR *sz1;
|
||||
/* [string] */ WCHAR *sz2;
|
||||
} ContextAndTwoStringW_Call;
|
||||
|
||||
typedef struct _EstablishContext_Call
|
||||
{
|
||||
DWORD dwScope;
|
||||
} EstablishContext_Call;
|
||||
|
||||
typedef struct _EstablishContext_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
} EstablishContext_Return;
|
||||
|
||||
typedef struct _ListReaderGroups_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
LONG fmszGroupsIsNULL;
|
||||
DWORD cchGroups;
|
||||
} ListReaderGroups_Call;
|
||||
|
||||
typedef struct _ListReaders_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [range] */ DWORD cBytes;
|
||||
/* [size_is][unique] */ BYTE *mszGroups;
|
||||
LONG fmszReadersIsNULL;
|
||||
DWORD cchReaders;
|
||||
} ListReaders_Call;
|
||||
|
||||
typedef struct _ReaderState_Common_Call
|
||||
{
|
||||
DWORD dwCurrentState;
|
||||
DWORD dwEventState;
|
||||
/* [range] */ DWORD cbAtr;
|
||||
BYTE rgbAtr[36];
|
||||
} ReaderState_Common_Call;
|
||||
|
||||
typedef struct _ReaderStateA
|
||||
{
|
||||
/* [string] */ unsigned char *szReader;
|
||||
ReaderState_Common_Call Common;
|
||||
} ReaderStateA;
|
||||
|
||||
typedef struct _ReaderStateW
|
||||
{
|
||||
/* [string] */ WCHAR *szReader;
|
||||
ReaderState_Common_Call Common;
|
||||
} ReaderStateW;
|
||||
|
||||
typedef struct _ReaderState_Return
|
||||
{
|
||||
DWORD dwCurrentState;
|
||||
DWORD dwEventState;
|
||||
/* [range] */ DWORD cbAtr;
|
||||
BYTE rgbAtr[36];
|
||||
} ReaderState_Return;
|
||||
|
||||
typedef struct _GetStatusChangeA_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
DWORD dwTimeOut;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ LPSCARD_READERSTATEA rgReaderStates;
|
||||
} GetStatusChangeA_Call;
|
||||
|
||||
typedef struct _LocateCardsA_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [range] */ DWORD cBytes;
|
||||
/* [size_is] */ BYTE *mszCards;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ ReaderStateA *rgReaderStates;
|
||||
} LocateCardsA_Call;
|
||||
|
||||
typedef struct _LocateCardsW_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [range] */ DWORD cBytes;
|
||||
/* [size_is] */ BYTE *mszCards;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ ReaderStateW *rgReaderStates;
|
||||
} LocateCardsW_Call;
|
||||
|
||||
typedef struct _LocateCards_ATRMask
|
||||
{
|
||||
/* [range] */ DWORD cbAtr;
|
||||
BYTE rgbAtr[ 36 ];
|
||||
BYTE rgbMask[ 36 ];
|
||||
} LocateCards_ATRMask;
|
||||
|
||||
typedef struct _LocateCardsByATRA_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [range] */ DWORD cAtrs;
|
||||
/* [size_is] */ LocateCards_ATRMask *rgAtrMasks;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ ReaderStateA *rgReaderStates;
|
||||
} LocateCardsByATRA_Call;
|
||||
|
||||
typedef struct _LocateCardsByATRW_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
/* [range] */ DWORD cAtrs;
|
||||
/* [size_is] */ LocateCards_ATRMask *rgAtrMasks;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ ReaderStateW *rgReaderStates;
|
||||
} LocateCardsByATRW_Call;
|
||||
|
||||
typedef struct _GetStatusChange_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ ReaderState_Return *rgReaderStates;
|
||||
} LocateCards_Return;
|
||||
|
||||
typedef struct _GetStatusChange_Return GetStatusChange_Return;
|
||||
|
||||
typedef struct _GetStatusChangeW_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
DWORD dwTimeOut;
|
||||
/* [range] */ DWORD cReaders;
|
||||
/* [size_is] */ LPSCARD_READERSTATEW rgReaderStates;
|
||||
} GetStatusChangeW_Call;
|
||||
|
||||
typedef struct _Connect_Common
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
DWORD dwShareMode;
|
||||
DWORD dwPreferredProtocols;
|
||||
} Connect_Common;
|
||||
|
||||
typedef struct _ConnectA_Call
|
||||
{
|
||||
/* [string] */ unsigned char *szReader;
|
||||
Connect_Common Common;
|
||||
} ConnectA_Call;
|
||||
|
||||
typedef struct _ConnectW_Call
|
||||
{
|
||||
/* [string] */ WCHAR *szReader;
|
||||
Connect_Common Common;
|
||||
} ConnectW_Call;
|
||||
|
||||
typedef struct _Connect_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwActiveProtocol;
|
||||
} Connect_Return;
|
||||
|
||||
typedef struct _Reconnect_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwShareMode;
|
||||
DWORD dwPreferredProtocols;
|
||||
DWORD dwInitialization;
|
||||
} Reconnect_Call;
|
||||
|
||||
typedef struct Reconnect_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
DWORD dwActiveProtocol;
|
||||
} Reconnect_Return;
|
||||
|
||||
typedef struct _HCardAndDisposition_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwDisposition;
|
||||
} HCardAndDisposition_Call;
|
||||
|
||||
typedef struct _State_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
LONG fpbAtrIsNULL;
|
||||
DWORD cbAtrLen;
|
||||
} State_Call;
|
||||
|
||||
typedef struct _State_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
DWORD dwState;
|
||||
DWORD dwProtocol;
|
||||
/* [range] */ DWORD cbAtrLen;
|
||||
/* [size_is][unique] */ BYTE rgAtr[36];
|
||||
} State_Return;
|
||||
|
||||
typedef struct _Status_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
LONG fmszReaderNamesIsNULL;
|
||||
DWORD cchReaderLen;
|
||||
DWORD cbAtrLen;
|
||||
} Status_Call;
|
||||
|
||||
typedef struct _Status_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cBytes;
|
||||
/* [size_is][unique] */ BYTE *mszReaderNames;
|
||||
DWORD dwState;
|
||||
DWORD dwProtocol;
|
||||
BYTE pbAtr[32];
|
||||
/* [range] */ DWORD cbAtrLen;
|
||||
} Status_Return;
|
||||
|
||||
typedef struct _SCardIO_Request
|
||||
{
|
||||
DWORD dwProtocol;
|
||||
/* [range] */ DWORD cbExtraBytes;
|
||||
/* [size_is][unique] */ BYTE *pbExtraBytes;
|
||||
} SCardIO_Request;
|
||||
|
||||
typedef struct _Transmit_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
LPSCARD_IO_REQUEST pioSendPci;
|
||||
/* [range] */ DWORD cbSendLength;
|
||||
/* [size_is] */ BYTE *pbSendBuffer;
|
||||
/* [unique] */ LPSCARD_IO_REQUEST pioRecvPci;
|
||||
LONG fpbRecvBufferIsNULL;
|
||||
DWORD cbRecvLength;
|
||||
} Transmit_Call;
|
||||
|
||||
typedef struct _Transmit_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [unique] */ LPSCARD_IO_REQUEST pioRecvPci;
|
||||
/* [range] */ DWORD cbRecvLength;
|
||||
/* [size_is][unique] */ BYTE *pbRecvBuffer;
|
||||
} Transmit_Return;
|
||||
|
||||
typedef struct _GetTransmitCount_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
} GetTransmitCount_Call;
|
||||
|
||||
typedef struct _GetTransmitCount_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
DWORD cTransmitCount;
|
||||
} GetTransmitCount_Return;
|
||||
|
||||
typedef struct _Control_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwControlCode;
|
||||
/* [range] */ DWORD cbInBufferSize;
|
||||
/* [size_is][unique] */ BYTE *pvInBuffer;
|
||||
LONG fpvOutBufferIsNULL;
|
||||
DWORD cbOutBufferSize;
|
||||
} Control_Call;
|
||||
|
||||
typedef struct _Control_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cbOutBufferSize;
|
||||
/* [size_is][unique] */ BYTE *pvOutBuffer;
|
||||
} Control_Return;
|
||||
|
||||
typedef struct _GetAttrib_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwAttrId;
|
||||
LONG fpbAttrIsNULL;
|
||||
DWORD cbAttrLen;
|
||||
} GetAttrib_Call;
|
||||
|
||||
typedef struct _GetAttrib_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cbAttrLen;
|
||||
/* [size_is][unique] */ BYTE *pbAttr;
|
||||
} GetAttrib_Return;
|
||||
|
||||
typedef struct _SetAttrib_Call
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
REDIR_SCARDHANDLE hCard;
|
||||
DWORD dwAttrId;
|
||||
/* [range] */ DWORD cbAttrLen;
|
||||
/* [size_is] */ BYTE *pbAttr;
|
||||
} SetAttrib_Call;
|
||||
|
||||
typedef struct _ReadCache_Common
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
UUID *CardIdentifier;
|
||||
DWORD FreshnessCounter;
|
||||
LONG fPbDataIsNULL;
|
||||
DWORD cbDataLen;
|
||||
} ReadCache_Common;
|
||||
|
||||
typedef struct _ReadCacheA_Call
|
||||
{
|
||||
/* [string] */ unsigned char *szLookupName;
|
||||
ReadCache_Common Common;
|
||||
} ReadCacheA_Call;
|
||||
|
||||
typedef struct _ReadCacheW_Call
|
||||
{
|
||||
/* [string] */ WCHAR *szLookupName;
|
||||
ReadCache_Common Common;
|
||||
} ReadCacheW_Call;
|
||||
|
||||
typedef struct _ReadCache_Return
|
||||
{
|
||||
LONG ReturnCode;
|
||||
/* [range] */ DWORD cbDataLen;
|
||||
/* [size_is][unique] */ BYTE *pbData;
|
||||
} ReadCache_Return;
|
||||
|
||||
typedef struct _WriteCache_Common
|
||||
{
|
||||
REDIR_SCARDCONTEXT hContext;
|
||||
UUID *CardIdentifier;
|
||||
DWORD FreshnessCounter;
|
||||
/* [range] */ DWORD cbDataLen;
|
||||
/* [size_is][unique] */ BYTE *pbData;
|
||||
} WriteCache_Common;
|
||||
|
||||
typedef struct _WriteCacheA_Call
|
||||
{
|
||||
/* [string] */ unsigned char *szLookupName;
|
||||
WriteCache_Common Common;
|
||||
} WriteCacheA_Call;
|
||||
|
||||
typedef struct _WriteCacheW_Call
|
||||
{
|
||||
/* [string] */ WCHAR *szLookupName;
|
||||
WriteCache_Common Common;
|
||||
} WriteCacheW_Call;
|
||||
|
||||
#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8
|
||||
#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8
|
||||
|
||||
UINT32 smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment);
|
||||
UINT32 smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 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);
|
||||
|
||||
UINT32 smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
UINT32 smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
|
||||
UINT32 smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
UINT32 smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength);
|
||||
|
||||
UINT32 smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
|
||||
UINT32 smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
|
||||
|
||||
UINT32 smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
|
||||
UINT32 smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
|
||||
|
||||
UINT32 smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
|
||||
UINT32 smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
|
||||
|
||||
UINT32 smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
|
||||
UINT32 smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
|
||||
|
||||
UINT32 smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Call* call);
|
||||
void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, EstablishContext_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Return* ret);
|
||||
void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, EstablishContext_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call);
|
||||
void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, Context_Call* call, const char* name);
|
||||
|
||||
UINT32 smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call);
|
||||
void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, BOOL unicode);
|
||||
|
||||
UINT32 smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret);
|
||||
void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, BOOL unicode);
|
||||
|
||||
UINT32 smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call);
|
||||
void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, ConnectA_Call* call);
|
||||
|
||||
UINT32 smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call);
|
||||
void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, ConnectW_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Return* ret);
|
||||
void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, Connect_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call);
|
||||
void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, Reconnect_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Return* ret);
|
||||
void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, Reconnect_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, HCardAndDisposition_Call* call);
|
||||
void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, HCardAndDisposition_Call* call, const char* name);
|
||||
|
||||
UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call);
|
||||
void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeA_Call* call);
|
||||
|
||||
UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call);
|
||||
void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeW_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChange_Return* ret);
|
||||
void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, GetStatusChange_Return* ret, BOOL unicode);
|
||||
|
||||
UINT32 smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call);
|
||||
UINT32 smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call);
|
||||
void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, Status_Call* call, BOOL unicode);
|
||||
|
||||
UINT32 smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret);
|
||||
void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, Status_Return* ret, BOOL unicode);
|
||||
|
||||
UINT32 smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call);
|
||||
void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, GetAttrib_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret);
|
||||
void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, DWORD dwAttrId);
|
||||
|
||||
UINT32 smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call);
|
||||
void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, Control_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret);
|
||||
void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, Control_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call);
|
||||
void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, Transmit_Call* call);
|
||||
|
||||
UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret);
|
||||
void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, Transmit_Return* ret);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */
|
|
@ -407,7 +407,7 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
|
|||
if (count > 1)
|
||||
parallel->Name = _strdup(params[1]);
|
||||
|
||||
if (count > 1)
|
||||
if (count > 2)
|
||||
parallel->Path = _strdup(params[2]);
|
||||
|
||||
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel);
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
# PCSC_LIBRARIES - libraries needed for linking
|
||||
|
||||
include(FindPkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PC_PCSC QUIET libpcsclite)
|
||||
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PC_PCSC QUIET libpcsclite)
|
||||
endif()
|
||||
|
||||
find_path(PCSC_INCLUDE_DIR pcsclite.h WinSCard.h
|
||||
HINTS ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES PCSC)
|
||||
HINTS ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES PCSC)
|
||||
|
||||
find_library(PCSC_LIBRARY NAMES PCSC WinSCard pcsclite
|
||||
HINTS ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS})
|
||||
HINTS ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCSC DEFAULT_MSG PCSC_LIBRARY PCSC_INCLUDE_DIR)
|
||||
|
@ -24,3 +25,4 @@ set(PCSC_INCLUDE_DIRS ${PCSC_INCLUDE_DIR})
|
|||
|
||||
mark_as_advanced(PCSC_INCLUDE_DIR PCSC_LIBRARY)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
find_library(PCSC_WINPR_LIBRARY
|
||||
NAMES libpcsc-winpr.a
|
||||
PATHS
|
||||
/opt/lib
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(NOT ${PCSC_WINPR_LIBRARY} MATCHES ".*-NOTFOUND")
|
||||
set(PCSC_WINPR_FOUND 1)
|
||||
message(STATUS "Found PCSC-WinPR: ${PCSC_WINPR_LIBRARY}")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(PCSC_WINPR_LIBRARY)
|
|
@ -34,6 +34,12 @@
|
|||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
#define RDPDR_DEVICE_IO_REQUEST_LENGTH 24
|
||||
#define RDPDR_DEVICE_IO_RESPONSE_LENGTH 16
|
||||
|
||||
#define RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH 32
|
||||
#define RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH 4
|
||||
|
||||
/* RDPDR_HEADER.Component */
|
||||
enum RDPDR_CTYP
|
||||
{
|
||||
|
@ -206,34 +212,36 @@ enum RDPDR_PRINTER_ANNOUNCE_FLAG
|
|||
#endif
|
||||
|
||||
/* [MS-FSCC] FSCTL Structures */
|
||||
enum FSCTL_STRUCTURE
|
||||
{
|
||||
FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900c0,
|
||||
FSCTL_GET_REPARSE_POINT = 0x900a8,
|
||||
FSCTL_GET_RETRIEVAL_POINTERS = 0x90073,
|
||||
FSCTL_IS_PATHNAME_VALID = 0x9002c,
|
||||
FSCTL_LMR_SET_LINK_TRACKING_INFORMATION = 0x1400ec,
|
||||
FSCTL_PIPE_PEEK = 0x11400c,
|
||||
FSCTL_PIPE_TRANSCEIVE = 0x11c017,
|
||||
FSCTL_PIPE_WAIT = 0x110018,
|
||||
FSCTL_QUERY_FAT_BPB = 0x90058,
|
||||
FSCTL_QUERY_ALLOCATED_RANGES = 0x940cf,
|
||||
FSCTL_QUERY_ON_DISK_VOLUME_INFO = 0x9013c,
|
||||
FSCTL_QUERY_SPARING_INFO = 0x90138,
|
||||
FSCTL_READ_FILE_USN_DATA = 0x900eb,
|
||||
FSCTL_RECALL_FILE = 0x90117,
|
||||
FSCTL_SET_COMPRESSION = 0x9c040,
|
||||
FSCTL_SET_DEFECT_MANAGEMENT = 0x98134,
|
||||
FSCTL_SET_ENCRYPTION = 0x900D7,
|
||||
FSCTL_SET_OBJECT_ID = 0x90098,
|
||||
FSCTL_SET_OBJECT_ID_EXTENDED = 0x900bc,
|
||||
FSCTL_SET_REPARSE_POINT = 0x900a4,
|
||||
FSCTL_SET_SPARSE = 0x900c4,
|
||||
FSCTL_SET_ZERO_DATA = 0x980c8,
|
||||
FSCTL_SET_ZERO_ON_DEALLOCATION = 0x90194,
|
||||
FSCTL_SIS_COPYFILE = 0x90100,
|
||||
FSCTL_WRITE_USN_CLOSE_RECORD = 0x900ef
|
||||
};
|
||||
|
||||
#define FSCTL_LMR_SET_LINK_TRACKING_INFORMATION 0x1400ec
|
||||
#define FSCTL_PIPE_PEEK 0x11400c
|
||||
#define FSCTL_PIPE_TRANSCEIVE 0x11c017
|
||||
#define FSCTL_PIPE_WAIT 0x110018
|
||||
#define FSCTL_QUERY_ON_DISK_VOLUME_INFO 0x9013c
|
||||
#define FSCTL_QUERY_SPARING_INFO 0x90138
|
||||
|
||||
#ifndef _WIN32
|
||||
#define FSCTL_CREATE_OR_GET_OBJECT_ID 0x900c0
|
||||
#define FSCTL_GET_REPARSE_POINT 0x900a8
|
||||
#define FSCTL_GET_RETRIEVAL_POINTERS 0x90073
|
||||
#define FSCTL_IS_PATHNAME_VALID 0x9002c
|
||||
#define FSCTL_READ_FILE_USN_DATA 0x900eb
|
||||
#define FSCTL_RECALL_FILE 0x90117
|
||||
#define FSCTL_QUERY_FAT_BPB 0x90058
|
||||
#define FSCTL_QUERY_ALLOCATED_RANGES 0x940cf
|
||||
#define FSCTL_SET_COMPRESSION 0x9c040
|
||||
#define FSCTL_SET_ENCRYPTION 0x900D7
|
||||
#define FSCTL_SET_OBJECT_ID 0x90098
|
||||
#define FSCTL_SET_OBJECT_ID_EXTENDED 0x900bc
|
||||
#define FSCTL_SET_REPARSE_POINT 0x900a4
|
||||
#define FSCTL_SET_SPARSE 0x900c4
|
||||
#define FSCTL_SET_ZERO_DATA 0x980c8
|
||||
#define FSCTL_SIS_COPYFILE 0x90100
|
||||
#define FSCTL_WRITE_USN_CLOSE_RECORD 0x900ef
|
||||
#endif
|
||||
|
||||
#define FSCTL_SET_DEFECT_MANAGEMENT 0x98134
|
||||
#define FSCTL_SET_ZERO_ON_DEALLOCATION 0x90194
|
||||
|
||||
/* [MS-FSCC] FileFsAttributeInformation.FileSystemAttributes */
|
||||
|
||||
|
@ -304,6 +312,7 @@ typedef struct _IRP IRP;
|
|||
typedef struct _DEVMAN DEVMAN;
|
||||
|
||||
typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp);
|
||||
typedef void (*pcInitDevice)(DEVICE* device);
|
||||
typedef void (*pcFreeDevice)(DEVICE* device);
|
||||
|
||||
struct _DEVICE
|
||||
|
@ -315,6 +324,7 @@ struct _DEVICE
|
|||
wStream* data;
|
||||
|
||||
pcIRPRequest IRPRequest;
|
||||
pcInitDevice Init;
|
||||
pcFreeDevice Free;
|
||||
};
|
||||
|
||||
|
@ -337,6 +347,9 @@ struct _IRP
|
|||
|
||||
pcIRPResponse Complete;
|
||||
pcIRPResponse Discard;
|
||||
|
||||
HANDLE thread;
|
||||
BOOL cancelled;
|
||||
};
|
||||
|
||||
struct _DEVMAN
|
||||
|
|
|
@ -2275,8 +2275,44 @@ BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdp
|
|||
|
||||
Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */
|
||||
|
||||
if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
|
||||
settings->MultifragMaxRequestSize = multifragMaxRequestSize;
|
||||
if (settings->ServerMode)
|
||||
{
|
||||
if (settings->RemoteFxCodec)
|
||||
{
|
||||
/**
|
||||
* If we are using RemoteFX the client MUST use a value greater
|
||||
* than or equal to the value we've previously sent in the server to
|
||||
* client multi-fragment update capability set (MS-RDPRFX 1.5)
|
||||
*/
|
||||
if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
|
||||
{
|
||||
/**
|
||||
* If it happens to be smaller we honor the client's value but
|
||||
* have to disable RemoteFX
|
||||
*/
|
||||
settings->RemoteFxCodec = FALSE;
|
||||
settings->MultifragMaxRequestSize = multifragMaxRequestSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no need to increase server's max request size setting here */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->MultifragMaxRequestSize = multifragMaxRequestSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* In client mode we keep up with the server's capabilites.
|
||||
* In RemoteFX mode we MUST do this but it might also be useful to
|
||||
* receive larger related bitmap updates.
|
||||
*/
|
||||
if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
|
||||
settings->MultifragMaxRequestSize = multifragMaxRequestSize;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -2294,6 +2330,29 @@ void rdp_write_multifragment_update_capability_set(wStream* s, rdpSettings* sett
|
|||
|
||||
Stream_EnsureRemainingCapacity(s, 32);
|
||||
|
||||
if (settings->ServerMode)
|
||||
{
|
||||
/**
|
||||
* In server mode we prefer to use the highest useful request size that
|
||||
* will allow us to pack a complete screen update into a single fast
|
||||
* path PDU using any of the supported codecs.
|
||||
* However, the client is completely free to accept our proposed
|
||||
* max request size or send a different value in the client-to-server
|
||||
* multi-fragment update capability set and we have to accept that,
|
||||
* unless we are using RemoteFX where the client MUST announce a value
|
||||
* greater than or equal to the value we're sending here.
|
||||
* See [MS-RDPRFX 1.5 capability #2]
|
||||
*/
|
||||
|
||||
UINT32 tileNumX = (settings->DesktopWidth+63)/64;
|
||||
UINT32 tileNumY = (settings->DesktopHeight+63)/64;
|
||||
|
||||
settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
|
||||
|
||||
/* and add room for headers, regions, frame markers, etc. */
|
||||
settings->MultifragMaxRequestSize += 16384;
|
||||
}
|
||||
|
||||
header = rdp_capability_set_start(s);
|
||||
|
||||
Stream_Write_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */
|
||||
|
@ -2531,6 +2590,8 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting
|
|||
BYTE bitmapCodecCount;
|
||||
UINT16 codecPropertiesLength;
|
||||
UINT16 remainingLength;
|
||||
BOOL receivedRemoteFxCodec = FALSE;
|
||||
BOOL receivedNSCodec = FALSE;
|
||||
|
||||
if (length < 5)
|
||||
return FALSE;
|
||||
|
@ -2538,13 +2599,6 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting
|
|||
Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
|
||||
remainingLength = length - 5;
|
||||
|
||||
if (settings->ServerMode)
|
||||
{
|
||||
settings->RemoteFxCodec = FALSE;
|
||||
settings->NSCodec = FALSE;
|
||||
settings->JpegCodec = FALSE;
|
||||
}
|
||||
|
||||
while (bitmapCodecCount > 0)
|
||||
{
|
||||
if (remainingLength < 19)
|
||||
|
@ -2557,12 +2611,12 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting
|
|||
if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status))
|
||||
{
|
||||
Stream_Read_UINT8(s, settings->RemoteFxCodecId);
|
||||
settings->RemoteFxCodec = TRUE;
|
||||
receivedRemoteFxCodec = TRUE;
|
||||
}
|
||||
else if (UuidEqual(&codecGuid, &CODEC_GUID_NSCODEC, &rpc_status))
|
||||
{
|
||||
Stream_Read_UINT8(s, settings->NSCodecId);
|
||||
settings->NSCodec = TRUE;
|
||||
receivedNSCodec = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2601,6 +2655,14 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting
|
|||
bitmapCodecCount--;
|
||||
}
|
||||
|
||||
if (settings->ServerMode)
|
||||
{
|
||||
/* only enable a codec if we've announced/enabled it before */
|
||||
settings->RemoteFxCodec = settings->RemoteFxCodec && receivedRemoteFxCodec;
|
||||
settings->NSCodec = settings->NSCodec && receivedNSCodec;
|
||||
settings->JpegCodec = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -584,20 +584,14 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
|||
* @param length certificate length
|
||||
*/
|
||||
|
||||
int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
|
||||
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
|
||||
{
|
||||
wStream* s;
|
||||
UINT32 dwVersion;
|
||||
int status = 1;
|
||||
|
||||
if (length < 1)
|
||||
{
|
||||
DEBUG_CERTIFICATE("null server certificate\n");
|
||||
return 0;
|
||||
}
|
||||
BOOL ret;
|
||||
|
||||
if (length < 4)
|
||||
return -1;
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(server_cert, length);
|
||||
|
||||
|
@ -606,22 +600,22 @@ int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serve
|
|||
switch (dwVersion & CERT_CHAIN_VERSION_MASK)
|
||||
{
|
||||
case CERT_CHAIN_VERSION_1:
|
||||
status = certificate_read_server_proprietary_certificate(certificate, s);
|
||||
ret = certificate_read_server_proprietary_certificate(certificate, s);
|
||||
break;
|
||||
|
||||
case CERT_CHAIN_VERSION_2:
|
||||
status = certificate_read_server_x509_certificate_chain(certificate, s);
|
||||
ret = certificate_read_server_x509_certificate_chain(certificate, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
|
||||
status = -1;
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdpRsaKey* key_new(const char* keyfile)
|
||||
|
|
|
@ -50,7 +50,7 @@ void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain);
|
|||
|
||||
BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, wStream* s);
|
||||
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s);
|
||||
int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
|
||||
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
|
||||
|
||||
rdpCertificate* certificate_new(void);
|
||||
void certificate_free(rdpCertificate* certificate);
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
|
||||
BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
{
|
||||
BOOL ret;
|
||||
rdpSettings* settings = rdp->settings;
|
||||
|
||||
if (rdp->settingsCopy)
|
||||
|
@ -208,6 +209,8 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||
|
||||
cookie_length = domain_length + 1 + user_length;
|
||||
cookie = (char*) malloc(cookie_length + 1);
|
||||
if (!cookie)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(cookie, domain, domain_length);
|
||||
CharUpperBuffA(cookie, domain_length);
|
||||
|
@ -218,14 +221,17 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||
|
||||
cookie[cookie_length] = '\0';
|
||||
|
||||
nego_set_cookie(rdp->nego, cookie);
|
||||
ret = nego_set_cookie(rdp->nego, cookie);
|
||||
free(cookie);
|
||||
}
|
||||
else
|
||||
{
|
||||
nego_set_cookie(rdp->nego, settings->Username);
|
||||
ret = nego_set_cookie(rdp->nego, settings->Username);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
|
||||
nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
|
||||
nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);
|
||||
|
@ -247,7 +253,10 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||
nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);
|
||||
|
||||
if (settings->LoadBalanceInfo)
|
||||
nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength);
|
||||
{
|
||||
if (!nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nego_connect(rdp->nego))
|
||||
{
|
||||
|
@ -421,7 +430,11 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
|||
key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
|
||||
mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
|
||||
exp = rdp->settings->RdpServerCertificate->cert_info.exponent;
|
||||
crypt_client_random = calloc(1,key_len);
|
||||
/*
|
||||
* client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1
|
||||
* for details
|
||||
*/
|
||||
crypt_client_random = calloc(1,key_len+8);
|
||||
if (!crypt_client_random)
|
||||
return FALSE;
|
||||
crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random);
|
||||
|
@ -521,7 +534,10 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
|||
}
|
||||
|
||||
if (!rdp_read_security_header(s, &sec_flags))
|
||||
{
|
||||
fprintf(stderr, "%s: invalid security header\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
|
||||
{
|
||||
|
|
|
@ -30,14 +30,7 @@
|
|||
|
||||
HttpContext* http_context_new()
|
||||
{
|
||||
HttpContext* http_context = (HttpContext*) malloc(sizeof(HttpContext));
|
||||
|
||||
if (http_context != NULL)
|
||||
{
|
||||
ZeroMemory(http_context, sizeof(HttpContext));
|
||||
}
|
||||
|
||||
return http_context;
|
||||
return (HttpContext *)calloc(1, sizeof(HttpContext));
|
||||
}
|
||||
|
||||
void http_context_set_method(HttpContext* http_context, char* method)
|
||||
|
@ -46,6 +39,7 @@ void http_context_set_method(HttpContext* http_context, char* method)
|
|||
free(http_context->Method);
|
||||
|
||||
http_context->Method = _strdup(method);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_uri(HttpContext* http_context, char* uri)
|
||||
|
@ -54,6 +48,7 @@ void http_context_set_uri(HttpContext* http_context, char* uri)
|
|||
free(http_context->URI);
|
||||
|
||||
http_context->URI = _strdup(uri);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_user_agent(HttpContext* http_context, char* user_agent)
|
||||
|
@ -62,6 +57,7 @@ void http_context_set_user_agent(HttpContext* http_context, char* user_agent)
|
|||
free(http_context->UserAgent);
|
||||
|
||||
http_context->UserAgent = _strdup(user_agent);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_host(HttpContext* http_context, char* host)
|
||||
|
@ -70,6 +66,7 @@ void http_context_set_host(HttpContext* http_context, char* host)
|
|||
free(http_context->Host);
|
||||
|
||||
http_context->Host = _strdup(host);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_accept(HttpContext* http_context, char* accept)
|
||||
|
@ -78,6 +75,7 @@ void http_context_set_accept(HttpContext* http_context, char* accept)
|
|||
free(http_context->Accept);
|
||||
|
||||
http_context->Accept = _strdup(accept);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_cache_control(HttpContext* http_context, char* cache_control)
|
||||
|
@ -86,6 +84,7 @@ void http_context_set_cache_control(HttpContext* http_context, char* cache_contr
|
|||
free(http_context->CacheControl);
|
||||
|
||||
http_context->CacheControl = _strdup(cache_control);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_connection(HttpContext* http_context, char* connection)
|
||||
|
@ -94,6 +93,7 @@ void http_context_set_connection(HttpContext* http_context, char* connection)
|
|||
free(http_context->Connection);
|
||||
|
||||
http_context->Connection = _strdup(connection);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_set_pragma(HttpContext* http_context, char* pragma)
|
||||
|
@ -102,6 +102,7 @@ void http_context_set_pragma(HttpContext* http_context, char* pragma)
|
|||
free(http_context->Pragma);
|
||||
|
||||
http_context->Pragma = _strdup(pragma);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_context_free(HttpContext* http_context)
|
||||
|
@ -126,6 +127,7 @@ void http_request_set_method(HttpRequest* http_request, char* method)
|
|||
free(http_request->Method);
|
||||
|
||||
http_request->Method = _strdup(method);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_request_set_uri(HttpRequest* http_request, char* uri)
|
||||
|
@ -134,6 +136,7 @@ void http_request_set_uri(HttpRequest* http_request, char* uri)
|
|||
free(http_request->URI);
|
||||
|
||||
http_request->URI = _strdup(uri);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme)
|
||||
|
@ -142,6 +145,7 @@ void http_request_set_auth_scheme(HttpRequest* http_request, char* auth_scheme)
|
|||
free(http_request->AuthScheme);
|
||||
|
||||
http_request->AuthScheme = _strdup(auth_scheme);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
void http_request_set_auth_param(HttpRequest* http_request, char* auth_param)
|
||||
|
@ -150,6 +154,7 @@ void http_request_set_auth_param(HttpRequest* http_request, char* auth_param)
|
|||
free(http_request->AuthParam);
|
||||
|
||||
http_request->AuthParam = _strdup(auth_param);
|
||||
// TODO: check result
|
||||
}
|
||||
|
||||
char* http_encode_body_line(char* param, char* value)
|
||||
|
@ -159,6 +164,8 @@ char* http_encode_body_line(char* param, char* value)
|
|||
|
||||
length = strlen(param) + strlen(value) + 2;
|
||||
line = (char*) malloc(length + 1);
|
||||
if (!line)
|
||||
return NULL;
|
||||
sprintf_s(line, length + 1, "%s: %s", param, value);
|
||||
|
||||
return line;
|
||||
|
@ -172,7 +179,9 @@ char* http_encode_content_length_line(int ContentLength)
|
|||
|
||||
_itoa_s(ContentLength, str, sizeof(str), 10);
|
||||
length = strlen("Content-Length") + strlen(str) + 2;
|
||||
line = (char*) malloc(length + 1);
|
||||
line = (char *)malloc(length + 1);
|
||||
if (!line)
|
||||
return NULL;
|
||||
sprintf_s(line, length + 1, "Content-Length: %s", str);
|
||||
|
||||
return line;
|
||||
|
@ -184,7 +193,9 @@ char* http_encode_header_line(char* Method, char* URI)
|
|||
int length;
|
||||
|
||||
length = strlen("HTTP/1.1") + strlen(Method) + strlen(URI) + 2;
|
||||
line = (char*) malloc(length + 1);
|
||||
line = (char *)malloc(length + 1);
|
||||
if (!line)
|
||||
return NULL;
|
||||
sprintf_s(line, length + 1, "%s %s HTTP/1.1", Method, URI);
|
||||
|
||||
return line;
|
||||
|
@ -197,6 +208,8 @@ char* http_encode_authorization_line(char* AuthScheme, char* AuthParam)
|
|||
|
||||
length = strlen("Authorization") + strlen(AuthScheme) + strlen(AuthParam) + 3;
|
||||
line = (char*) malloc(length + 1);
|
||||
if (!line)
|
||||
return NULL;
|
||||
sprintf_s(line, length + 1, "Authorization: %s %s", AuthScheme, AuthParam);
|
||||
|
||||
return line;
|
||||
|
@ -204,81 +217,101 @@ char* http_encode_authorization_line(char* AuthScheme, char* AuthParam)
|
|||
|
||||
wStream* http_request_write(HttpContext* http_context, HttpRequest* http_request)
|
||||
{
|
||||
int i;
|
||||
int i, count;
|
||||
char **lines;
|
||||
wStream* s;
|
||||
int length = 0;
|
||||
|
||||
http_request->count = 9;
|
||||
http_request->lines = (char**) malloc(sizeof(char*) * http_request->count);
|
||||
count = 9;
|
||||
lines = (char **)calloc(count, sizeof(char *));
|
||||
if (!lines)
|
||||
return NULL;
|
||||
|
||||
http_request->lines[0] = http_encode_header_line(http_request->Method, http_request->URI);
|
||||
http_request->lines[1] = http_encode_body_line("Cache-Control", http_context->CacheControl);
|
||||
http_request->lines[2] = http_encode_body_line("Connection", http_context->Connection);
|
||||
http_request->lines[3] = http_encode_body_line("Pragma", http_context->Pragma);
|
||||
http_request->lines[4] = http_encode_body_line("Accept", http_context->Accept);
|
||||
http_request->lines[5] = http_encode_body_line("User-Agent", http_context->UserAgent);
|
||||
http_request->lines[6] = http_encode_content_length_line(http_request->ContentLength);
|
||||
http_request->lines[7] = http_encode_body_line("Host", http_context->Host);
|
||||
lines[0] = http_encode_header_line(http_request->Method, http_request->URI);
|
||||
lines[1] = http_encode_body_line("Cache-Control", http_context->CacheControl);
|
||||
lines[2] = http_encode_body_line("Connection", http_context->Connection);
|
||||
lines[3] = http_encode_body_line("Pragma", http_context->Pragma);
|
||||
lines[4] = http_encode_body_line("Accept", http_context->Accept);
|
||||
lines[5] = http_encode_body_line("User-Agent", http_context->UserAgent);
|
||||
lines[6] = http_encode_content_length_line(http_request->ContentLength);
|
||||
lines[7] = http_encode_body_line("Host", http_context->Host);
|
||||
|
||||
/* check that everything went well */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (!lines[i])
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (http_request->Authorization != NULL)
|
||||
{
|
||||
http_request->lines[8] = http_encode_body_line("Authorization", http_request->Authorization);
|
||||
lines[8] = http_encode_body_line("Authorization", http_request->Authorization);
|
||||
if (!lines[8])
|
||||
goto out_free;
|
||||
}
|
||||
else if ((http_request->AuthScheme != NULL) && (http_request->AuthParam != NULL))
|
||||
{
|
||||
http_request->lines[8] = http_encode_authorization_line(http_request->AuthScheme, http_request->AuthParam);
|
||||
lines[8] = http_encode_authorization_line(http_request->AuthScheme, http_request->AuthParam);
|
||||
if (!lines[8])
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < http_request->count; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
length += (strlen(http_request->lines[i]) + 2); /* add +2 for each '\r\n' character */
|
||||
length += (strlen(lines[i]) + 2); /* add +2 for each '\r\n' character */
|
||||
}
|
||||
length += 2; /* empty line "\r\n" at end of header */
|
||||
length += 1; /* null terminator */
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
if (!s)
|
||||
goto out_free;
|
||||
|
||||
for (i = 0; i < http_request->count; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
Stream_Write(s, http_request->lines[i], strlen(http_request->lines[i]));
|
||||
Stream_Write(s, lines[i], strlen(lines[i]));
|
||||
Stream_Write(s, "\r\n", 2);
|
||||
free(http_request->lines[i]);
|
||||
free(lines[i]);
|
||||
}
|
||||
Stream_Write(s, "\r\n", 2);
|
||||
|
||||
free(http_request->lines);
|
||||
free(lines);
|
||||
|
||||
Stream_Write(s, "\0", 1); /* append null terminator */
|
||||
Stream_Rewind(s, 1); /* don't include null terminator in length */
|
||||
Stream_Length(s) = Stream_GetPosition(s);
|
||||
|
||||
return s;
|
||||
|
||||
out_free:
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
if (lines[i])
|
||||
free(lines[i]);
|
||||
}
|
||||
free(lines);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HttpRequest* http_request_new()
|
||||
{
|
||||
HttpRequest* http_request = (HttpRequest*) malloc(sizeof(HttpRequest));
|
||||
|
||||
if (http_request != NULL)
|
||||
{
|
||||
ZeroMemory(http_request, sizeof(HttpRequest));
|
||||
}
|
||||
|
||||
return http_request;
|
||||
return (HttpRequest*) calloc(1, sizeof(HttpRequest));
|
||||
}
|
||||
|
||||
void http_request_free(HttpRequest* http_request)
|
||||
{
|
||||
if (http_request != NULL)
|
||||
{
|
||||
if (!http_request)
|
||||
return;
|
||||
|
||||
if (http_request->AuthParam)
|
||||
free(http_request->AuthParam);
|
||||
if (http_request->AuthScheme)
|
||||
free(http_request->AuthScheme);
|
||||
if (http_request->Authorization)
|
||||
free(http_request->Authorization);
|
||||
free(http_request->Content);
|
||||
free(http_request->Method);
|
||||
free(http_request->URI);
|
||||
free(http_request);
|
||||
}
|
||||
free(http_request->Content);
|
||||
free(http_request->Method);
|
||||
free(http_request->URI);
|
||||
free(http_request);
|
||||
}
|
||||
|
||||
BOOL http_response_parse_header_status_line(HttpResponse* http_response, char* status_line)
|
||||
|
@ -300,11 +333,13 @@ BOOL http_response_parse_header_status_line(HttpResponse* http_response, char* s
|
|||
*separator = '\0';
|
||||
http_response->StatusCode = atoi(status_code);
|
||||
http_response->ReasonPhrase = _strdup(reason_phrase);
|
||||
if (!http_response->ReasonPhrase)
|
||||
return FALSE;
|
||||
*separator = ' ';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void http_response_parse_header_field(HttpResponse* http_response, char* name, char* value)
|
||||
BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, char* value)
|
||||
{
|
||||
if (_stricmp(name, "Content-Length") == 0)
|
||||
{
|
||||
|
@ -315,6 +350,8 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c
|
|||
char* separator;
|
||||
|
||||
http_response->Authorization = _strdup(value);
|
||||
if (!http_response->Authorization)
|
||||
return FALSE;
|
||||
|
||||
separator = strchr(value, ' ');
|
||||
|
||||
|
@ -323,6 +360,8 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c
|
|||
*separator = '\0';
|
||||
http_response->AuthScheme = _strdup(value);
|
||||
http_response->AuthParam = _strdup(separator + 1);
|
||||
if (!http_response->AuthScheme || !http_response->AuthParam)
|
||||
return FALSE;
|
||||
*separator = ' ';
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +374,7 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c
|
|||
if (separator != NULL)
|
||||
{
|
||||
/* WWW-Authenticate: parameter with spaces="value" */
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
separator = strchr(value, ' ');
|
||||
|
@ -349,9 +388,10 @@ void http_response_parse_header_field(HttpResponse* http_response, char* name, c
|
|||
http_response->AuthParam = _strdup(separator + 1);
|
||||
*separator = ' ';
|
||||
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL http_response_parse_header(HttpResponse* http_response)
|
||||
|
@ -412,7 +452,8 @@ BOOL http_response_parse_header(HttpResponse* http_response)
|
|||
break;
|
||||
}
|
||||
|
||||
http_response_parse_header_field(http_response, name, value);
|
||||
if (!http_response_parse_header_field(http_response, name, value))
|
||||
return FALSE;
|
||||
|
||||
*end_of_header = end_of_header_char;
|
||||
}
|
||||
|
@ -445,7 +486,12 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
length = 10000;
|
||||
content = NULL;
|
||||
buffer = malloc(length);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
http_response = http_response_new();
|
||||
if (!http_response)
|
||||
goto out_free;
|
||||
|
||||
p = buffer;
|
||||
http_response->ContentLength = 0;
|
||||
|
@ -456,20 +502,14 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
{
|
||||
status = tls_read(tls, p, length - nbytes);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
nbytes += status;
|
||||
p = (BYTE*) &buffer[nbytes];
|
||||
}
|
||||
else if (status == 0)
|
||||
{
|
||||
if (status < 0)
|
||||
goto out_error;
|
||||
|
||||
if (!status)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
http_response_free(http_response);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nbytes += status;
|
||||
p = (BYTE*) &buffer[nbytes];
|
||||
}
|
||||
|
||||
header_end = strstr((char*) buffer, "\r\n\r\n");
|
||||
|
@ -478,8 +518,7 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
{
|
||||
fprintf(stderr, "http_response_recv: invalid response:\n");
|
||||
winpr_HexDump(buffer, status);
|
||||
http_response_free(http_response);
|
||||
return NULL;
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
header_end += 2;
|
||||
|
@ -505,8 +544,9 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
http_response->count = count;
|
||||
if (count)
|
||||
{
|
||||
http_response->lines = (char**) malloc(sizeof(char*) * http_response->count);
|
||||
ZeroMemory(http_response->lines, sizeof(char*) * http_response->count);
|
||||
http_response->lines = (char **)calloc(http_response->count, sizeof(char *));
|
||||
if (!http_response->lines)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
@ -515,19 +555,21 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
while (line != NULL)
|
||||
{
|
||||
http_response->lines[count] = _strdup(line);
|
||||
if (!http_response->lines[count])
|
||||
goto out_error;
|
||||
|
||||
line = strtok(NULL, "\r\n");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!http_response_parse_header(http_response))
|
||||
{
|
||||
http_response_free(http_response);
|
||||
return NULL;
|
||||
}
|
||||
goto out_error;
|
||||
|
||||
if (http_response->ContentLength > 0)
|
||||
{
|
||||
http_response->Content = _strdup(content);
|
||||
if (!http_response->Content)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -544,20 +586,17 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||
free(buffer);
|
||||
|
||||
return http_response;
|
||||
|
||||
out_error:
|
||||
http_response_free(http_response);
|
||||
out_free:
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HttpResponse* http_response_new()
|
||||
{
|
||||
HttpResponse* http_response;
|
||||
|
||||
http_response = (HttpResponse*) malloc(sizeof(HttpResponse));
|
||||
|
||||
if (http_response != NULL)
|
||||
{
|
||||
ZeroMemory(http_response, sizeof(HttpResponse));
|
||||
}
|
||||
|
||||
return http_response;
|
||||
return (HttpResponse *)calloc(1, sizeof(HttpResponse));
|
||||
}
|
||||
|
||||
void http_response_free(HttpResponse* http_response)
|
||||
|
|
|
@ -55,9 +55,6 @@ void http_context_free(HttpContext* http_context);
|
|||
|
||||
struct _http_request
|
||||
{
|
||||
int count;
|
||||
char** lines;
|
||||
|
||||
char* Method;
|
||||
char* URI;
|
||||
char* AuthScheme;
|
||||
|
|
|
@ -307,25 +307,34 @@ rdpNtlmHttp* ntlm_http_new()
|
|||
{
|
||||
rdpNtlmHttp* ntlm_http;
|
||||
|
||||
ntlm_http = (rdpNtlmHttp*) malloc(sizeof(rdpNtlmHttp));
|
||||
ntlm_http = (rdpNtlmHttp *)calloc(1, sizeof(rdpNtlmHttp));
|
||||
|
||||
if (ntlm_http != NULL)
|
||||
{
|
||||
ZeroMemory(ntlm_http, sizeof(rdpNtlmHttp));
|
||||
ntlm_http->ntlm = ntlm_new();
|
||||
ntlm_http->context = http_context_new();
|
||||
}
|
||||
if (!ntlm_http)
|
||||
return NULL;
|
||||
|
||||
ntlm_http->ntlm = ntlm_new();
|
||||
if (!ntlm_http->ntlm)
|
||||
goto out_free;
|
||||
|
||||
ntlm_http->context = http_context_new();
|
||||
if (!ntlm_http->context)
|
||||
goto out_free_ntlm;
|
||||
|
||||
return ntlm_http;
|
||||
|
||||
out_free_ntlm:
|
||||
ntlm_free(ntlm_http->ntlm);
|
||||
out_free:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ntlm_http_free(rdpNtlmHttp* ntlm_http)
|
||||
{
|
||||
if (ntlm_http != NULL)
|
||||
{
|
||||
ntlm_free(ntlm_http->ntlm);
|
||||
http_context_free(ntlm_http->context);
|
||||
if (!ntlm_http)
|
||||
return;
|
||||
|
||||
free(ntlm_http);
|
||||
}
|
||||
ntlm_free(ntlm_http->ntlm);
|
||||
http_context_free(ntlm_http->context);
|
||||
|
||||
free(ntlm_http);
|
||||
}
|
||||
|
|
|
@ -137,6 +137,8 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
|
|||
if (!ServiceClass)
|
||||
{
|
||||
ntlm->ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
|
||||
if (!ntlm->ServicePrincipalName)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -147,6 +149,8 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
|
|||
return FALSE;
|
||||
|
||||
ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
|
||||
if (!ntlm->ServicePrincipalName)
|
||||
return FALSE;
|
||||
|
||||
status = DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName);
|
||||
|
||||
|
@ -210,6 +214,8 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
|
|||
ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
|
||||
ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
|
||||
ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
|
||||
if (!ntlm->outputBuffer[0].pvBuffer)
|
||||
return FALSE;
|
||||
|
||||
if (ntlm->haveInputBuffer)
|
||||
{
|
||||
|
@ -286,14 +292,7 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
|
|||
|
||||
rdpNtlm* ntlm_new()
|
||||
{
|
||||
rdpNtlm* ntlm = (rdpNtlm*) malloc(sizeof(rdpNtlm));
|
||||
|
||||
if (ntlm != NULL)
|
||||
{
|
||||
ZeroMemory(ntlm, sizeof(rdpNtlm));
|
||||
}
|
||||
|
||||
return ntlm;
|
||||
return (rdpNtlm *)calloc(1, sizeof(rdpNtlm));
|
||||
}
|
||||
|
||||
void ntlm_free(rdpNtlm* ntlm)
|
||||
|
|
|
@ -497,20 +497,27 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne
|
|||
|
||||
RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
|
||||
{
|
||||
RpcVirtualConnection* connection = (RpcVirtualConnection*) malloc(sizeof(RpcVirtualConnection));
|
||||
RpcVirtualConnection* connection = (RpcVirtualConnection*) calloc(1, sizeof(RpcVirtualConnection));
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
ZeroMemory(connection, sizeof(RpcVirtualConnection));
|
||||
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
|
||||
connection->DefaultInChannel = (RpcInChannel*) malloc(sizeof(RpcInChannel));
|
||||
connection->DefaultOutChannel = (RpcOutChannel*) malloc(sizeof(RpcOutChannel));
|
||||
ZeroMemory(connection->DefaultInChannel, sizeof(RpcInChannel));
|
||||
ZeroMemory(connection->DefaultOutChannel, sizeof(RpcOutChannel));
|
||||
rpc_client_virtual_connection_init(rpc, connection);
|
||||
}
|
||||
if (!connection)
|
||||
return NULL;
|
||||
|
||||
connection->State = VIRTUAL_CONNECTION_STATE_INITIAL;
|
||||
connection->DefaultInChannel = (RpcInChannel *)calloc(1, sizeof(RpcInChannel));
|
||||
if (!connection->DefaultInChannel)
|
||||
goto out_free;
|
||||
connection->DefaultOutChannel = (RpcOutChannel*)calloc(1, sizeof(RpcOutChannel));
|
||||
if (!connection->DefaultOutChannel)
|
||||
goto out_default_in;
|
||||
rpc_client_virtual_connection_init(rpc, connection);
|
||||
|
||||
return connection;
|
||||
|
||||
out_default_in:
|
||||
free(connection->DefaultInChannel);
|
||||
out_free:
|
||||
free(connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection)
|
||||
|
@ -525,64 +532,84 @@ void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection
|
|||
|
||||
rdpRpc* rpc_new(rdpTransport* transport)
|
||||
{
|
||||
rdpRpc* rpc = (rdpRpc*) malloc(sizeof(rdpRpc));
|
||||
rdpRpc* rpc = (rdpRpc*) calloc(1, sizeof(rdpRpc));
|
||||
if (!rpc)
|
||||
return NULL;
|
||||
|
||||
if (rpc != NULL)
|
||||
{
|
||||
ZeroMemory(rpc, sizeof(rdpRpc));
|
||||
rpc->State = RPC_CLIENT_STATE_INITIAL;
|
||||
|
||||
rpc->State = RPC_CLIENT_STATE_INITIAL;
|
||||
rpc->transport = transport;
|
||||
rpc->settings = transport->settings;
|
||||
|
||||
rpc->transport = transport;
|
||||
rpc->settings = transport->settings;
|
||||
rpc->SendSeqNum = 0;
|
||||
rpc->ntlm = ntlm_new();
|
||||
if (!rpc->ntlm)
|
||||
goto out_free;
|
||||
|
||||
rpc->SendSeqNum = 0;
|
||||
rpc->ntlm = ntlm_new();
|
||||
rpc->NtlmHttpIn = ntlm_http_new();
|
||||
if (!rpc->NtlmHttpIn)
|
||||
goto out_free_ntlm;
|
||||
rpc->NtlmHttpOut = ntlm_http_new();
|
||||
if (!rpc->NtlmHttpOut)
|
||||
goto out_free_ntlm_http_in;
|
||||
|
||||
rpc->NtlmHttpIn = ntlm_http_new();
|
||||
rpc->NtlmHttpOut = ntlm_http_new();
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
|
||||
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
|
||||
rpc->PipeCallId = 0;
|
||||
|
||||
rpc->PipeCallId = 0;
|
||||
rpc->StubCallId = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
|
||||
rpc->StubCallId = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
rpc->rpc_vers = 5;
|
||||
rpc->rpc_vers_minor = 0;
|
||||
|
||||
rpc->rpc_vers = 5;
|
||||
rpc->rpc_vers_minor = 0;
|
||||
/* little-endian data representation */
|
||||
rpc->packed_drep[0] = 0x10;
|
||||
rpc->packed_drep[1] = 0x00;
|
||||
rpc->packed_drep[2] = 0x00;
|
||||
rpc->packed_drep[3] = 0x00;
|
||||
|
||||
/* little-endian data representation */
|
||||
rpc->packed_drep[0] = 0x10;
|
||||
rpc->packed_drep[1] = 0x00;
|
||||
rpc->packed_drep[2] = 0x00;
|
||||
rpc->packed_drep[3] = 0x00;
|
||||
rpc->max_xmit_frag = 0x0FF8;
|
||||
rpc->max_recv_frag = 0x0FF8;
|
||||
|
||||
rpc->max_xmit_frag = 0x0FF8;
|
||||
rpc->max_recv_frag = 0x0FF8;
|
||||
rpc->ReceiveWindow = 0x00010000;
|
||||
|
||||
rpc->ReceiveWindow = 0x00010000;
|
||||
rpc->ChannelLifetime = 0x40000000;
|
||||
rpc->ChannelLifetimeSet = 0;
|
||||
|
||||
rpc->ChannelLifetime = 0x40000000;
|
||||
rpc->ChannelLifetimeSet = 0;
|
||||
rpc->KeepAliveInterval = 300000;
|
||||
rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
|
||||
rpc->CurrentKeepAliveTime = 0;
|
||||
|
||||
rpc->KeepAliveInterval = 300000;
|
||||
rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval;
|
||||
rpc->CurrentKeepAliveTime = 0;
|
||||
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
|
||||
if (!rpc->VirtualConnection)
|
||||
goto out_free_ntlm_http_out;
|
||||
|
||||
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
|
||||
rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE);
|
||||
rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE);
|
||||
if (!rpc->VirtualConnectionCookieTable)
|
||||
goto out_free_virtual_connection;
|
||||
|
||||
rpc->CallId = 2;
|
||||
rpc->CallId = 2;
|
||||
|
||||
rpc_client_new(rpc);
|
||||
rpc_client_new(rpc);
|
||||
|
||||
rpc->client->SynchronousSend = TRUE;
|
||||
rpc->client->SynchronousReceive = TRUE;
|
||||
}
|
||||
rpc->client->SynchronousSend = TRUE;
|
||||
rpc->client->SynchronousReceive = TRUE;
|
||||
|
||||
return rpc;
|
||||
|
||||
out_free_virtual_connection:
|
||||
rpc_client_virtual_connection_free(rpc->VirtualConnection);
|
||||
out_free_ntlm_http_out:
|
||||
ntlm_http_free(rpc->NtlmHttpOut);
|
||||
out_free_ntlm_http_in:
|
||||
ntlm_http_free(rpc->NtlmHttpIn);
|
||||
out_free_ntlm:
|
||||
ntlm_free(rpc->ntlm);
|
||||
out_free:
|
||||
free(rpc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpc_free(rdpRpc* rpc)
|
||||
|
|
|
@ -775,7 +775,7 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
|
|||
|
||||
/* Parse Server Certificate */
|
||||
if (!certificate_read_server_certificate(license->certificate,
|
||||
license->ServerCertificate->data, license->ServerCertificate->length) < 0)
|
||||
license->ServerCertificate->data, license->ServerCertificate->length))
|
||||
return FALSE;
|
||||
|
||||
license_generate_keys(license);
|
||||
|
|
|
@ -1087,6 +1087,7 @@ void mcs_free(rdpMcs* mcs)
|
|||
{
|
||||
if (mcs)
|
||||
{
|
||||
free(mcs->channels);
|
||||
free(mcs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ BOOL nego_connect(rdpNego* nego)
|
|||
{
|
||||
DEBUG_NEGO("No security protocol is enabled");
|
||||
nego->state = NEGO_STATE_FAIL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nego->NegotiateSecurityLayer)
|
||||
|
@ -1118,12 +1119,15 @@ void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
|
|||
* @param RoutingTokenLength
|
||||
*/
|
||||
|
||||
void nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength)
|
||||
BOOL nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength)
|
||||
{
|
||||
free(nego->RoutingToken);
|
||||
nego->RoutingTokenLength = RoutingTokenLength;
|
||||
nego->RoutingToken = (BYTE*) malloc(nego->RoutingTokenLength);
|
||||
if (!nego->RoutingToken)
|
||||
return FALSE;
|
||||
CopyMemory(nego->RoutingToken, RoutingToken, nego->RoutingTokenLength);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1132,12 +1136,15 @@ void nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingToke
|
|||
* @param cookie
|
||||
*/
|
||||
|
||||
void nego_set_cookie(rdpNego* nego, char* cookie)
|
||||
BOOL nego_set_cookie(rdpNego* nego, char* cookie)
|
||||
{
|
||||
if (nego->cookie)
|
||||
free(nego->cookie);
|
||||
|
||||
nego->cookie = _strdup(cookie);
|
||||
if (!nego->cookie)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -150,8 +150,8 @@ void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
|||
void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
|
||||
void nego_enable_nla(rdpNego* nego, BOOL enable_nla);
|
||||
void nego_enable_ext(rdpNego* nego, BOOL enable_ext);
|
||||
void nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength);
|
||||
void nego_set_cookie(rdpNego* nego, char* cookie);
|
||||
BOOL nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength);
|
||||
BOOL nego_set_cookie(rdpNego* nego, char* cookie);
|
||||
void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length);
|
||||
void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu);
|
||||
void nego_set_preconnection_id(rdpNego* nego, UINT32 id);
|
||||
|
|
|
@ -1356,6 +1356,8 @@ LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
|
|||
}
|
||||
|
||||
ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
|
||||
if (!ServicePrincipalName)
|
||||
return NULL;
|
||||
|
||||
status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName);
|
||||
|
||||
|
|
|
@ -1199,47 +1199,118 @@ rdpRdp* rdp_new(rdpContext* context)
|
|||
{
|
||||
rdpRdp* rdp;
|
||||
DWORD flags;
|
||||
BOOL newSettings = FALSE;
|
||||
|
||||
rdp = (rdpRdp*) malloc(sizeof(rdpRdp));
|
||||
rdp = (rdpRdp*) calloc(1, sizeof(rdpRdp));
|
||||
if (!rdp)
|
||||
return NULL;
|
||||
|
||||
if (rdp)
|
||||
rdp->context = context;
|
||||
rdp->instance = context->instance;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (context->ServerMode)
|
||||
flags |= FREERDP_SETTINGS_SERVER_MODE;
|
||||
|
||||
if (!context->settings)
|
||||
{
|
||||
ZeroMemory(rdp, sizeof(rdpRdp));
|
||||
|
||||
rdp->context = context;
|
||||
rdp->instance = context->instance;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (context->ServerMode)
|
||||
flags |= FREERDP_SETTINGS_SERVER_MODE;
|
||||
|
||||
context->settings = freerdp_settings_new(flags);
|
||||
if (!context->settings)
|
||||
context->settings = freerdp_settings_new(flags);
|
||||
|
||||
rdp->settings = context->settings;
|
||||
rdp->settings->instance = context->instance;
|
||||
|
||||
if (context->instance)
|
||||
context->instance->settings = rdp->settings;
|
||||
|
||||
rdp->extension = extension_new(context->instance);
|
||||
rdp->transport = transport_new(rdp->settings);
|
||||
rdp->transport->rdp = rdp;
|
||||
rdp->license = license_new(rdp);
|
||||
rdp->input = input_new(rdp);
|
||||
rdp->update = update_new(rdp);
|
||||
rdp->fastpath = fastpath_new(rdp);
|
||||
rdp->nego = nego_new(rdp->transport);
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
rdp->redirection = redirection_new();
|
||||
rdp->autodetect = autodetect_new();
|
||||
rdp->heartbeat = heartbeat_new();
|
||||
rdp->multitransport = multitransport_new();
|
||||
rdp->bulk = bulk_new(context);
|
||||
goto out_free;
|
||||
newSettings = TRUE;
|
||||
}
|
||||
|
||||
rdp->settings = context->settings;
|
||||
rdp->settings->instance = context->instance;
|
||||
if (context->instance)
|
||||
context->instance->settings = rdp->settings;
|
||||
|
||||
rdp->extension = extension_new(context->instance);
|
||||
if (!rdp->extension)
|
||||
goto out_free_settings;
|
||||
|
||||
rdp->transport = transport_new(rdp->settings);
|
||||
if (!rdp->transport)
|
||||
goto out_free_extension;
|
||||
rdp->transport->rdp = rdp;
|
||||
|
||||
rdp->license = license_new(rdp);
|
||||
if (!rdp->license)
|
||||
goto out_free_transport;
|
||||
|
||||
rdp->input = input_new(rdp);
|
||||
if (!rdp->input)
|
||||
goto out_free_license;
|
||||
|
||||
rdp->update = update_new(rdp);
|
||||
if (!rdp->update)
|
||||
goto out_free_input;
|
||||
|
||||
rdp->fastpath = fastpath_new(rdp);
|
||||
if (!rdp->fastpath)
|
||||
goto out_free_update;
|
||||
|
||||
rdp->nego = nego_new(rdp->transport);
|
||||
if (!rdp->nego)
|
||||
goto out_free_fastpath;
|
||||
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
if (!rdp->mcs)
|
||||
goto out_free_nego;
|
||||
|
||||
rdp->redirection = redirection_new();
|
||||
if (!rdp->redirection)
|
||||
goto out_free_mcs;
|
||||
|
||||
rdp->autodetect = autodetect_new();
|
||||
if (!rdp->autodetect)
|
||||
goto out_free_redirection;
|
||||
|
||||
rdp->heartbeat = heartbeat_new();
|
||||
if (!rdp->heartbeat)
|
||||
goto out_free_autodetect;
|
||||
|
||||
rdp->multitransport = multitransport_new();
|
||||
if (!rdp->multitransport)
|
||||
goto out_free_heartbeat;
|
||||
|
||||
rdp->bulk = bulk_new(context);
|
||||
if (!rdp->bulk)
|
||||
goto out_free_multitransport;
|
||||
|
||||
return rdp;
|
||||
|
||||
out_free_multitransport:
|
||||
multitransport_free(rdp->multitransport);
|
||||
out_free_heartbeat:
|
||||
heartbeat_free(rdp->heartbeat);
|
||||
out_free_autodetect:
|
||||
autodetect_free(rdp->autodetect);
|
||||
out_free_redirection:
|
||||
redirection_free(rdp->redirection);
|
||||
out_free_mcs:
|
||||
mcs_free(rdp->mcs);
|
||||
out_free_nego:
|
||||
nego_free(rdp->nego);
|
||||
out_free_fastpath:
|
||||
fastpath_free(rdp->fastpath);
|
||||
out_free_update:
|
||||
update_free(rdp->update);
|
||||
out_free_input:
|
||||
input_free(rdp->input);
|
||||
out_free_license:
|
||||
license_free(rdp->license);
|
||||
out_free_transport:
|
||||
transport_free(rdp->transport);
|
||||
out_free_extension:
|
||||
extension_free(rdp->extension);
|
||||
out_free_settings:
|
||||
if (newSettings)
|
||||
freerdp_settings_free(rdp->settings);
|
||||
out_free:
|
||||
free(rdp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rdp_reset(rdpRdp* rdp)
|
||||
|
|
|
@ -264,15 +264,14 @@ rdpCertificateStore* certificate_store_new(rdpSettings* settings)
|
|||
{
|
||||
rdpCertificateStore* certificate_store;
|
||||
|
||||
certificate_store = (rdpCertificateStore*) malloc(sizeof(rdpCertificateStore));
|
||||
certificate_store = (rdpCertificateStore *)calloc(1, sizeof(rdpCertificateStore));
|
||||
|
||||
if (certificate_store != NULL)
|
||||
{
|
||||
ZeroMemory(certificate_store, sizeof(rdpCertificateStore));
|
||||
if (!certificate_store)
|
||||
return NULL;
|
||||
|
||||
certificate_store->settings = settings;
|
||||
certificate_store_init(certificate_store);
|
||||
}
|
||||
certificate_store->settings = settings;
|
||||
certificate_store_init(certificate_store);
|
||||
/* TODO: certificate_store_init should not fail silently */
|
||||
|
||||
return certificate_store;
|
||||
}
|
||||
|
|
|
@ -154,10 +154,10 @@ WINPR_API void ArrayList_Clear(wArrayList* arrayList);
|
|||
WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj);
|
||||
|
||||
WINPR_API int ArrayList_Add(wArrayList* arrayList, void* obj);
|
||||
WINPR_API void ArrayList_Insert(wArrayList* arrayList, int index, void* obj);
|
||||
WINPR_API BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj);
|
||||
|
||||
WINPR_API void ArrayList_Remove(wArrayList* arrayList, void* obj);
|
||||
WINPR_API void ArrayList_RemoveAt(wArrayList* arrayList, int index);
|
||||
WINPR_API BOOL ArrayList_Remove(wArrayList* arrayList, void* obj);
|
||||
WINPR_API BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index);
|
||||
|
||||
WINPR_API int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count);
|
||||
WINPR_API int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int count);
|
||||
|
@ -200,6 +200,9 @@ typedef struct _wListDictionary wListDictionary;
|
|||
|
||||
WINPR_API int ListDictionary_Count(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API void ListDictionary_Lock(wListDictionary* listDictionary);
|
||||
WINPR_API void ListDictionary_Unlock(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value);
|
||||
WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, void* key);
|
||||
WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary);
|
||||
|
@ -387,7 +390,7 @@ WINPR_API int BufferPool_GetPoolSize(wBufferPool* pool);
|
|||
WINPR_API int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer);
|
||||
|
||||
WINPR_API void* BufferPool_Take(wBufferPool* pool, int bufferSize);
|
||||
WINPR_API void BufferPool_Return(wBufferPool* pool, void* buffer);
|
||||
WINPR_API BOOL BufferPool_Return(wBufferPool* pool, void* buffer);
|
||||
WINPR_API void BufferPool_Clear(wBufferPool* pool);
|
||||
|
||||
WINPR_API wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment);
|
||||
|
|
|
@ -23,7 +23,11 @@
|
|||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <winioctl.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <winpr/nt.h>
|
||||
|
||||
|
@ -82,10 +86,6 @@ WINPR_API BOOL CancelSynchronousIo(HANDLE hThread);
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WinPR I/O Manager Custom API
|
||||
*/
|
||||
|
||||
#define DEVICE_TYPE ULONG
|
||||
|
||||
#define FILE_DEVICE_BEEP 0x00000001
|
||||
|
@ -156,6 +156,27 @@ WINPR_API BOOL CancelSynchronousIo(HANDLE hThread);
|
|||
#define FILE_DEVICE_BIOMETRIC 0x00000044
|
||||
#define FILE_DEVICE_PMI 0x00000045
|
||||
|
||||
#define CTL_CODE(DeviceType, Function, Method, Access) \
|
||||
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
|
||||
|
||||
#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((DWORD)(ctrlCode & 0xFFFF0000)) >> 16)
|
||||
|
||||
#define METHOD_FROM_CTL_CODE(ctrlCode) ((DWORD)(ctrlCode & 3))
|
||||
|
||||
#define METHOD_BUFFERED 0
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#define METHOD_NEITHER 3
|
||||
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
|
||||
#define FILE_READ_ACCESS (0x0001)
|
||||
#define FILE_WRITE_ACCESS (0x0002)
|
||||
|
||||
/*
|
||||
* WinPR I/O Manager Custom API
|
||||
*/
|
||||
|
||||
typedef HANDLE PDRIVER_OBJECT_EX;
|
||||
typedef HANDLE PDEVICE_OBJECT_EX;
|
||||
|
||||
|
@ -166,5 +187,12 @@ WINPR_API VOID _IoDeleteDeviceEx(PDEVICE_OBJECT_EX DeviceObject);
|
|||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Extended API
|
||||
*/
|
||||
|
||||
#define ACCESS_FROM_CTL_CODE(ctrlCode) ((DWORD)((ctrlCode >> 14) & 0x3))
|
||||
#define FUNCTION_FROM_CTL_CODE(ctrlCode) ((DWORD)((ctrlCode >> 2) & 0xFFF))
|
||||
|
||||
#endif /* WINPR_IO_H */
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ extern "C" {
|
|||
WINPR_API void winpr_HexDump(BYTE* data, int length);
|
||||
WINPR_API void winpr_CArrayDump(BYTE* data, int length, int width);
|
||||
|
||||
WINPR_API char* winpr_BinToHexString(BYTE* data, int length, BOOL space);
|
||||
|
||||
WINPR_API int wprintfx(const char *fmt, ...);
|
||||
WINPR_API int wvprintfx(const char *fmt, va_list args);
|
||||
WINPR_API int wvsnprintfx(char *buffer, size_t bufferSize, const char* fmt, va_list args);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -246,6 +246,9 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...);
|
|||
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
|
||||
}
|
||||
|
||||
#define WLog_IsLevelActive(_log, _log_level) \
|
||||
(_log_level >= WLog_GetLogLevel(_log))
|
||||
|
||||
WINPR_API DWORD WLog_GetLogLevel(wLog* log);
|
||||
WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel);
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ typedef HANDLE HINSTANCE;
|
|||
typedef HANDLE HMODULE;
|
||||
typedef HANDLE HWND;
|
||||
typedef HANDLE HBITMAP;
|
||||
typedef HANDLE HICON;
|
||||
typedef HANDLE HCURSOR;
|
||||
|
||||
typedef DWORD HCALL;
|
||||
typedef int INT, *LPINT;
|
||||
|
@ -144,7 +146,6 @@ typedef unsigned short USHORT;
|
|||
#define VOID void
|
||||
typedef void *PVOID, *LPVOID;
|
||||
typedef void *PVOID64, *LPVOID64;
|
||||
typedef const void *LPCVOID;
|
||||
typedef unsigned short WORD, *PWORD, *LPWORD;
|
||||
|
||||
#if __x86_64__
|
||||
|
@ -161,7 +162,7 @@ typedef struct _GUID
|
|||
UINT16 Data2;
|
||||
UINT16 Data3;
|
||||
BYTE Data4[8];
|
||||
} GUID, UUID, *PGUID;
|
||||
} GUID, UUID, *PGUID, *LPGUID, *LPCGUID;
|
||||
|
||||
typedef struct _LUID
|
||||
{
|
||||
|
@ -314,6 +315,16 @@ typedef LONG NTSTATUS;
|
|||
typedef NTSTATUS *PNTSTATUS;
|
||||
#endif
|
||||
|
||||
#ifndef _LPCBYTE_DEFINED
|
||||
#define _LPCBYTE_DEFINED
|
||||
typedef const BYTE *LPCBYTE;
|
||||
#endif
|
||||
|
||||
#ifndef _LPCVOID_DEFINED
|
||||
#define _LPCVOID_DEFINED
|
||||
typedef const VOID *LPCVOID;
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
typedef struct tagDEC
|
||||
|
|
|
@ -235,11 +235,7 @@ BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
|
|||
|
||||
if (lpValue)
|
||||
{
|
||||
length = strlen(lpName) + strlen(lpValue) + 1;
|
||||
envstr = (char*) malloc(length + 1);
|
||||
sprintf_s(envstr, length + 1, "%s=%s", lpName, lpValue);
|
||||
envstr[length] = '\0';
|
||||
putenv(envstr);
|
||||
setenv(lpName,lpValue,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-smartcard cmake build script
|
||||
#
|
||||
# Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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.
|
||||
|
||||
set(MODULE_NAME "winpr-smartcard")
|
||||
set(MODULE_PREFIX "WINPR_SMARTCARD")
|
||||
|
||||
if(PCSC_WINPR_FOUND)
|
||||
add_definitions(-DWITH_WINPR_PCSC)
|
||||
endif()
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
smartcard.c
|
||||
smartcard.h
|
||||
smartcard_link.c
|
||||
smartcard_pcsc.c
|
||||
smartcard_pcsc.h
|
||||
smartcard_winscard.c
|
||||
smartcard_winscard.h)
|
||||
|
||||
if(MSVC AND (NOT MONOLITHIC_BUILD))
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)
|
||||
endif()
|
||||
|
||||
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
SOURCES ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib")
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-library winpr-utils)
|
||||
|
||||
if(PCSC_WINPR_FOUND)
|
||||
list(APPEND ${MODULE_PREFIX}_LIBS ${PCSC_WINPR_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
else()
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT WinPRTargets)
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
set(MINWIN_LAYER "0")
|
||||
set(MINWIN_GROUP "none")
|
||||
set(MINWIN_MAJOR_VERSION "0")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "smartcard")
|
||||
set(MINWIN_LONG_NAME "Smart Card API")
|
||||
set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}")
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
LIBRARY "libwinpr-smartcard"
|
||||
EXPORTS
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Smart Card API
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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 WINPR_SMARTCARD_PRIVATE_H
|
||||
#define WINPR_SMARTCARD_PRIVATE_H
|
||||
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#define SCARDAPI_STUB_CALL_LONG(_name, ...) \
|
||||
if (!g_Initialized) \
|
||||
InitializeSCardApiStubs(); \
|
||||
if (!g_SCardApi || !g_SCardApi->pfn ## _name) \
|
||||
return 0; \
|
||||
return g_SCardApi->pfn ## _name ( __VA_ARGS__ )
|
||||
|
||||
#define SCARDAPI_STUB_CALL_HANDLE(_name, ...) \
|
||||
if (!g_Initialized) \
|
||||
InitializeSCardApiStubs(); \
|
||||
if (!g_SCardApi || !g_SCardApi->pfn ## _name) \
|
||||
return NULL; \
|
||||
return g_SCardApi->pfn ## _name ( __VA_ARGS__ )
|
||||
|
||||
#define SCARDAPI_STUB_CALL_VOID(_name, ...) \
|
||||
if (!g_Initialized) \
|
||||
InitializeSCardApiStubs(); \
|
||||
if (!g_SCardApi || !g_SCardApi->pfn ## _name) \
|
||||
return; \
|
||||
g_SCardApi->pfn ## _name ( __VA_ARGS__ )
|
||||
|
||||
void InitializeSCardApiStubs(void);
|
||||
|
||||
#include "smartcard_pcsc.h"
|
||||
#include "smartcard_winscard.h"
|
||||
|
||||
#endif /* WINPR_SMARTCARD_PRIVATE_H */
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Smart Card API
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* PCSC-WinPR (only required for Mac OS X):
|
||||
*
|
||||
* PCSC-WinPR is a static build of libpcsclite with
|
||||
* minor modifications meant to avoid an ABI conflict.
|
||||
*
|
||||
* Add the WinPR_PCSC_* definitions that follow "#define WinPR_PCSC"
|
||||
* in this file to pcsc-lite/src/PCSC/winscard.h
|
||||
*
|
||||
* Configure pcsc-lite with the following options (Mac OS X):
|
||||
*
|
||||
* ./configure --enable-static --prefix=/usr --program-suffix=winpr
|
||||
* --enable-usbdropdir=/usr/libexec/SmartCardServices/drivers
|
||||
* --enable-confdir=/etc --enable-ipcdir=/var/run
|
||||
*
|
||||
* Build pcsc-lite, and then copy libpcsclite.a to libpcsc-winpr.a:
|
||||
*
|
||||
* make
|
||||
* cp ./src/.libs/libpcsclite.a libpcsc-winpr.a
|
||||
*
|
||||
* Validate that libpcsc-winpr.a has a modified ABI:
|
||||
*
|
||||
* nm libpcsc-winpr.a | grep " T " | grep WinPR
|
||||
*
|
||||
* If the ABI has been successfully modified, you should
|
||||
* see pcsc-lite functions prefixed with "WinPR_PCSC_".
|
||||
*
|
||||
* You can keep this custom pcsc-lite build for later.
|
||||
* To install the library, copy it to /usr/lib or /usr/local/lib.
|
||||
*
|
||||
* The FreeRDP build system will then automatically pick it up
|
||||
* as long as it is present on the system. To ensure PCSC-WinPR
|
||||
* is properly detected at cmake generation time, look for the
|
||||
* following debug output:
|
||||
*
|
||||
* -- Found PCSC-WinPR: /usr/lib/libpcsc-winpr.a
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define WinPR_PCSC
|
||||
#define SCardEstablishContext WinPR_PCSC_SCardEstablishContext
|
||||
#define SCardReleaseContext WinPR_PCSC_SCardReleaseContext
|
||||
#define SCardIsValidContext WinPR_PCSC_SCardIsValidContext
|
||||
#define SCardConnect WinPR_PCSC_SCardConnect
|
||||
#define SCardReconnect WinPR_PCSC_SCardReconnect
|
||||
#define SCardDisconnect WinPR_PCSC_SCardDisconnect
|
||||
#define SCardBeginTransaction WinPR_PCSC_SCardBeginTransaction
|
||||
#define SCardEndTransaction WinPR_PCSC_SCardEndTransaction
|
||||
#define SCardStatus WinPR_PCSC_SCardStatus
|
||||
#define SCardGetStatusChange WinPR_PCSC_SCardGetStatusChange
|
||||
#define SCardControl WinPR_PCSC_SCardControl
|
||||
#define SCardTransmit WinPR_PCSC_SCardTransmit
|
||||
#define SCardListReaderGroups WinPR_PCSC_SCardListReaderGroups
|
||||
#define SCardListReaders WinPR_PCSC_SCardListReaders
|
||||
#define SCardFreeMemory WinPR_PCSC_SCardFreeMemory
|
||||
#define SCardCancel WinPR_PCSC_SCardCancel
|
||||
#define SCardGetAttrib WinPR_PCSC_SCardGetAttrib
|
||||
#define SCardSetAttrib WinPR_PCSC_SCardSetAttrib
|
||||
#define list_size WinPR_PCSC_list_size /* put this line in src/simclist.h */
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WINPR_PCSC
|
||||
extern void* WinPR_PCSC_SCardEstablishContext();
|
||||
extern void* WinPR_PCSC_SCardReleaseContext();
|
||||
extern void* WinPR_PCSC_SCardIsValidContext();
|
||||
extern void* WinPR_PCSC_SCardConnect();
|
||||
extern void* WinPR_PCSC_SCardReconnect();
|
||||
extern void* WinPR_PCSC_SCardDisconnect();
|
||||
extern void* WinPR_PCSC_SCardBeginTransaction();
|
||||
extern void* WinPR_PCSC_SCardEndTransaction();
|
||||
extern void* WinPR_PCSC_SCardStatus();
|
||||
extern void* WinPR_PCSC_SCardGetStatusChange();
|
||||
extern void* WinPR_PCSC_SCardControl();
|
||||
extern void* WinPR_PCSC_SCardTransmit();
|
||||
extern void* WinPR_PCSC_SCardListReaderGroups();
|
||||
extern void* WinPR_PCSC_SCardListReaders();
|
||||
extern void* WinPR_PCSC_SCardFreeMemory();
|
||||
extern void* WinPR_PCSC_SCardCancel();
|
||||
extern void* WinPR_PCSC_SCardGetAttrib();
|
||||
extern void* WinPR_PCSC_SCardSetAttrib();
|
||||
#endif
|
||||
|
||||
struct _PCSCFunctionTable
|
||||
{
|
||||
void* pfnSCardEstablishContext;
|
||||
void* pfnSCardReleaseContext;
|
||||
void* pfnSCardIsValidContext;
|
||||
void* pfnSCardConnect;
|
||||
void* pfnSCardReconnect;
|
||||
void* pfnSCardDisconnect;
|
||||
void* pfnSCardBeginTransaction;
|
||||
void* pfnSCardEndTransaction;
|
||||
void* pfnSCardStatus;
|
||||
void* pfnSCardGetStatusChange;
|
||||
void* pfnSCardControl;
|
||||
void* pfnSCardTransmit;
|
||||
void* pfnSCardListReaderGroups;
|
||||
void* pfnSCardListReaders;
|
||||
void* pfnSCardFreeMemory;
|
||||
void* pfnSCardCancel;
|
||||
void* pfnSCardGetAttrib;
|
||||
void* pfnSCardSetAttrib;
|
||||
};
|
||||
typedef struct _PCSCFunctionTable PCSCFunctionTable;
|
||||
|
||||
PCSCFunctionTable g_PCSC_Link = { 0 };
|
||||
|
||||
int PCSC_InitializeSCardApi_Link(void)
|
||||
{
|
||||
int status = -1;
|
||||
|
||||
#ifdef WITH_WINPR_PCSC
|
||||
g_PCSC_Link.pfnSCardEstablishContext = (void*) WinPR_PCSC_SCardEstablishContext;
|
||||
g_PCSC_Link.pfnSCardReleaseContext = (void*) WinPR_PCSC_SCardReleaseContext;
|
||||
g_PCSC_Link.pfnSCardIsValidContext = (void*) WinPR_PCSC_SCardIsValidContext;
|
||||
g_PCSC_Link.pfnSCardConnect = (void*) WinPR_PCSC_SCardConnect;
|
||||
g_PCSC_Link.pfnSCardReconnect = (void*) WinPR_PCSC_SCardReconnect;
|
||||
g_PCSC_Link.pfnSCardDisconnect = (void*) WinPR_PCSC_SCardDisconnect;
|
||||
g_PCSC_Link.pfnSCardBeginTransaction = (void*) WinPR_PCSC_SCardBeginTransaction;
|
||||
g_PCSC_Link.pfnSCardEndTransaction = (void*) WinPR_PCSC_SCardEndTransaction;
|
||||
g_PCSC_Link.pfnSCardStatus = (void*) WinPR_PCSC_SCardStatus;
|
||||
g_PCSC_Link.pfnSCardGetStatusChange = (void*) WinPR_PCSC_SCardGetStatusChange;
|
||||
g_PCSC_Link.pfnSCardControl = (void*) WinPR_PCSC_SCardControl;
|
||||
g_PCSC_Link.pfnSCardTransmit = (void*) WinPR_PCSC_SCardTransmit;
|
||||
g_PCSC_Link.pfnSCardListReaderGroups = (void*) WinPR_PCSC_SCardListReaderGroups;
|
||||
g_PCSC_Link.pfnSCardListReaders = (void*) WinPR_PCSC_SCardListReaders;
|
||||
//g_PCSC_Link.pfnSCardFreeMemory = (void*) WinPR_PCSC_SCardFreeMemory;
|
||||
g_PCSC_Link.pfnSCardFreeMemory = (void*) NULL;
|
||||
g_PCSC_Link.pfnSCardCancel = (void*) WinPR_PCSC_SCardCancel;
|
||||
g_PCSC_Link.pfnSCardGetAttrib = (void*) WinPR_PCSC_SCardGetAttrib;
|
||||
g_PCSC_Link.pfnSCardSetAttrib = (void*) WinPR_PCSC_SCardSetAttrib;
|
||||
|
||||
status = 1;
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Smart Card API
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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 WINPR_SMARTCARD_PCSC_PRIVATE_H
|
||||
#define WINPR_SMARTCARD_PCSC_PRIVATE_H
|
||||
|
||||
#include <winpr/platform.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#define PCSC_SCARD_UNKNOWN 0x0001
|
||||
#define PCSC_SCARD_ABSENT 0x0002
|
||||
#define PCSC_SCARD_PRESENT 0x0004
|
||||
#define PCSC_SCARD_SWALLOWED 0x0008
|
||||
#define PCSC_SCARD_POWERED 0x0010
|
||||
#define PCSC_SCARD_NEGOTIABLE 0x0020
|
||||
#define PCSC_SCARD_SPECIFIC 0x0040
|
||||
|
||||
#define PCSC_SCARD_PROTOCOL_RAW 0x00000004
|
||||
#define PCSC_SCARD_PROTOCOL_T15 0x00000008
|
||||
|
||||
struct _PCSCFunctionTable
|
||||
{
|
||||
LONG (* pfnSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
|
||||
LONG (* pfnSCardReleaseContext)(SCARDCONTEXT hContext);
|
||||
LONG (* pfnSCardIsValidContext)(SCARDCONTEXT hContext);
|
||||
LONG (* pfnSCardConnect)(SCARDCONTEXT hContext,
|
||||
LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
|
||||
LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
|
||||
LONG (* pfnSCardReconnect)(SCARDHANDLE hCard,
|
||||
DWORD dwShareMode, DWORD dwPreferredProtocols,
|
||||
DWORD dwInitialization, LPDWORD pdwActiveProtocol);
|
||||
LONG (* pfnSCardDisconnect)(SCARDHANDLE hCard, DWORD dwDisposition);
|
||||
LONG (* pfnSCardBeginTransaction)(SCARDHANDLE hCard);
|
||||
LONG (* pfnSCardEndTransaction)(SCARDHANDLE hCard, DWORD dwDisposition);
|
||||
LONG (* pfnSCardStatus)(SCARDHANDLE hCard,
|
||||
LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState,
|
||||
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen);
|
||||
LONG (* pfnSCardGetStatusChange)(SCARDCONTEXT hContext,
|
||||
DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders);
|
||||
LONG (* pfnSCardControl)(SCARDHANDLE hCard,
|
||||
DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength,
|
||||
LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned);
|
||||
LONG (* pfnSCardTransmit)(SCARDHANDLE hCard,
|
||||
const SCARD_IO_REQUEST* pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength,
|
||||
SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
|
||||
LONG (* pfnSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups);
|
||||
LONG (* pfnSCardListReaders)(SCARDCONTEXT hContext,
|
||||
LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders);
|
||||
LONG (* pfnSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
|
||||
LONG (* pfnSCardCancel)(SCARDCONTEXT hContext);
|
||||
LONG (* pfnSCardGetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen);
|
||||
LONG (* pfnSCardSetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen);
|
||||
};
|
||||
typedef struct _PCSCFunctionTable PCSCFunctionTable;
|
||||
|
||||
int PCSC_InitializeSCardApi(void);
|
||||
PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void);
|
||||
|
||||
#endif /* WINPR_SMARTCARD_PCSC_PRIVATE_H */
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Smart Card API
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/library.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include "smartcard_winscard.h"
|
||||
|
||||
static HMODULE g_WinSCardModule = NULL;
|
||||
|
||||
SCardApiFunctionTable WinSCard_SCardApiFunctionTable =
|
||||
{
|
||||
0, /* dwVersion */
|
||||
0, /* dwFlags */
|
||||
|
||||
NULL, /* SCardEstablishContext */
|
||||
NULL, /* SCardReleaseContext */
|
||||
NULL, /* SCardIsValidContext */
|
||||
NULL, /* SCardListReaderGroupsA */
|
||||
NULL, /* SCardListReaderGroupsW */
|
||||
NULL, /* SCardListReadersA */
|
||||
NULL, /* SCardListReadersW */
|
||||
NULL, /* SCardListCardsA */
|
||||
NULL, /* SCardListCardsW */
|
||||
NULL, /* SCardListInterfacesA */
|
||||
NULL, /* SCardListInterfacesW */
|
||||
NULL, /* SCardGetProviderIdA */
|
||||
NULL, /* SCardGetProviderIdW */
|
||||
NULL, /* SCardGetCardTypeProviderNameA */
|
||||
NULL, /* SCardGetCardTypeProviderNameW */
|
||||
NULL, /* SCardIntroduceReaderGroupA */
|
||||
NULL, /* SCardIntroduceReaderGroupW */
|
||||
NULL, /* SCardForgetReaderGroupA */
|
||||
NULL, /* SCardForgetReaderGroupW */
|
||||
NULL, /* SCardIntroduceReaderA */
|
||||
NULL, /* SCardIntroduceReaderW */
|
||||
NULL, /* SCardForgetReaderA */
|
||||
NULL, /* SCardForgetReaderW */
|
||||
NULL, /* SCardAddReaderToGroupA */
|
||||
NULL, /* SCardAddReaderToGroupW */
|
||||
NULL, /* SCardRemoveReaderFromGroupA */
|
||||
NULL, /* SCardRemoveReaderFromGroupW */
|
||||
NULL, /* SCardIntroduceCardTypeA */
|
||||
NULL, /* SCardIntroduceCardTypeW */
|
||||
NULL, /* SCardSetCardTypeProviderNameA */
|
||||
NULL, /* SCardSetCardTypeProviderNameW */
|
||||
NULL, /* SCardForgetCardTypeA */
|
||||
NULL, /* SCardForgetCardTypeW */
|
||||
NULL, /* SCardFreeMemory */
|
||||
NULL, /* SCardAccessStartedEvent */
|
||||
NULL, /* SCardReleaseStartedEvent */
|
||||
NULL, /* SCardLocateCardsA */
|
||||
NULL, /* SCardLocateCardsW */
|
||||
NULL, /* SCardLocateCardsByATRA */
|
||||
NULL, /* SCardLocateCardsByATRW */
|
||||
NULL, /* SCardGetStatusChangeA */
|
||||
NULL, /* SCardGetStatusChangeW */
|
||||
NULL, /* SCardCancel */
|
||||
NULL, /* SCardConnectA */
|
||||
NULL, /* SCardConnectW */
|
||||
NULL, /* SCardReconnect */
|
||||
NULL, /* SCardDisconnect */
|
||||
NULL, /* SCardBeginTransaction */
|
||||
NULL, /* SCardEndTransaction */
|
||||
NULL, /* SCardCancelTransaction */
|
||||
NULL, /* SCardState */
|
||||
NULL, /* SCardStatusA */
|
||||
NULL, /* SCardStatusW */
|
||||
NULL, /* SCardTransmit */
|
||||
NULL, /* SCardGetTransmitCount */
|
||||
NULL, /* SCardControl */
|
||||
NULL, /* SCardGetAttrib */
|
||||
NULL, /* SCardSetAttrib */
|
||||
NULL, /* SCardUIDlgSelectCardA */
|
||||
NULL, /* SCardUIDlgSelectCardW */
|
||||
NULL, /* GetOpenCardNameA */
|
||||
NULL, /* GetOpenCardNameW */
|
||||
NULL, /* SCardDlgExtendedError */
|
||||
NULL, /* SCardReadCacheA */
|
||||
NULL, /* SCardReadCacheW */
|
||||
NULL, /* SCardWriteCacheA */
|
||||
NULL, /* SCardWriteCacheW */
|
||||
NULL, /* SCardGetReaderIconA */
|
||||
NULL, /* SCardGetReaderIconW */
|
||||
NULL, /* SCardGetDeviceTypeIdA */
|
||||
NULL, /* SCardGetDeviceTypeIdW */
|
||||
NULL, /* SCardGetReaderDeviceInstanceIdA */
|
||||
NULL, /* SCardGetReaderDeviceInstanceIdW */
|
||||
NULL, /* SCardListReadersWithDeviceInstanceIdA */
|
||||
NULL, /* SCardListReadersWithDeviceInstanceIdW */
|
||||
NULL /* SCardAudit */
|
||||
};
|
||||
|
||||
PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void)
|
||||
{
|
||||
return &WinSCard_SCardApiFunctionTable;
|
||||
}
|
||||
|
||||
int WinSCard_InitializeSCardApi(void)
|
||||
{
|
||||
g_WinSCardModule = LoadLibraryA("winscard.dll");
|
||||
|
||||
if (!g_WinSCardModule)
|
||||
return -1;
|
||||
|
||||
WINSCARD_LOAD_PROC(SCardEstablishContext);
|
||||
WINSCARD_LOAD_PROC(SCardReleaseContext);
|
||||
WINSCARD_LOAD_PROC(SCardIsValidContext);
|
||||
WINSCARD_LOAD_PROC(SCardListReaderGroupsA);
|
||||
WINSCARD_LOAD_PROC(SCardListReaderGroupsW);
|
||||
WINSCARD_LOAD_PROC(SCardListReadersA);
|
||||
WINSCARD_LOAD_PROC(SCardListReadersW);
|
||||
WINSCARD_LOAD_PROC(SCardListCardsA);
|
||||
WINSCARD_LOAD_PROC(SCardListCardsW);
|
||||
WINSCARD_LOAD_PROC(SCardListInterfacesA);
|
||||
WINSCARD_LOAD_PROC(SCardListInterfacesW);
|
||||
WINSCARD_LOAD_PROC(SCardGetProviderIdA);
|
||||
WINSCARD_LOAD_PROC(SCardGetProviderIdW);
|
||||
WINSCARD_LOAD_PROC(SCardGetCardTypeProviderNameA);
|
||||
WINSCARD_LOAD_PROC(SCardGetCardTypeProviderNameW);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceReaderGroupA);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceReaderGroupW);
|
||||
WINSCARD_LOAD_PROC(SCardForgetReaderGroupA);
|
||||
WINSCARD_LOAD_PROC(SCardForgetReaderGroupW);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceReaderA);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceReaderW);
|
||||
WINSCARD_LOAD_PROC(SCardForgetReaderA);
|
||||
WINSCARD_LOAD_PROC(SCardForgetReaderW);
|
||||
WINSCARD_LOAD_PROC(SCardAddReaderToGroupA);
|
||||
WINSCARD_LOAD_PROC(SCardAddReaderToGroupW);
|
||||
WINSCARD_LOAD_PROC(SCardRemoveReaderFromGroupA);
|
||||
WINSCARD_LOAD_PROC(SCardRemoveReaderFromGroupW);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceCardTypeA);
|
||||
WINSCARD_LOAD_PROC(SCardIntroduceCardTypeW);
|
||||
WINSCARD_LOAD_PROC(SCardSetCardTypeProviderNameA);
|
||||
WINSCARD_LOAD_PROC(SCardSetCardTypeProviderNameW);
|
||||
WINSCARD_LOAD_PROC(SCardForgetCardTypeA);
|
||||
WINSCARD_LOAD_PROC(SCardForgetCardTypeW);
|
||||
WINSCARD_LOAD_PROC(SCardFreeMemory);
|
||||
WINSCARD_LOAD_PROC(SCardAccessStartedEvent);
|
||||
WINSCARD_LOAD_PROC(SCardReleaseStartedEvent);
|
||||
WINSCARD_LOAD_PROC(SCardLocateCardsA);
|
||||
WINSCARD_LOAD_PROC(SCardLocateCardsW);
|
||||
WINSCARD_LOAD_PROC(SCardLocateCardsByATRA);
|
||||
WINSCARD_LOAD_PROC(SCardLocateCardsByATRW);
|
||||
WINSCARD_LOAD_PROC(SCardGetStatusChangeA);
|
||||
WINSCARD_LOAD_PROC(SCardGetStatusChangeW);
|
||||
WINSCARD_LOAD_PROC(SCardCancel);
|
||||
WINSCARD_LOAD_PROC(SCardConnectA);
|
||||
WINSCARD_LOAD_PROC(SCardConnectW);
|
||||
WINSCARD_LOAD_PROC(SCardReconnect);
|
||||
WINSCARD_LOAD_PROC(SCardDisconnect);
|
||||
WINSCARD_LOAD_PROC(SCardBeginTransaction);
|
||||
WINSCARD_LOAD_PROC(SCardEndTransaction);
|
||||
WINSCARD_LOAD_PROC(SCardCancelTransaction);
|
||||
WINSCARD_LOAD_PROC(SCardState);
|
||||
WINSCARD_LOAD_PROC(SCardStatusA);
|
||||
WINSCARD_LOAD_PROC(SCardStatusW);
|
||||
WINSCARD_LOAD_PROC(SCardTransmit);
|
||||
WINSCARD_LOAD_PROC(SCardGetTransmitCount);
|
||||
WINSCARD_LOAD_PROC(SCardControl);
|
||||
WINSCARD_LOAD_PROC(SCardGetAttrib);
|
||||
WINSCARD_LOAD_PROC(SCardSetAttrib);
|
||||
WINSCARD_LOAD_PROC(SCardUIDlgSelectCardA);
|
||||
WINSCARD_LOAD_PROC(SCardUIDlgSelectCardW);
|
||||
WINSCARD_LOAD_PROC(GetOpenCardNameA);
|
||||
WINSCARD_LOAD_PROC(GetOpenCardNameW);
|
||||
WINSCARD_LOAD_PROC(SCardDlgExtendedError);
|
||||
WINSCARD_LOAD_PROC(SCardReadCacheA);
|
||||
WINSCARD_LOAD_PROC(SCardReadCacheW);
|
||||
WINSCARD_LOAD_PROC(SCardWriteCacheA);
|
||||
WINSCARD_LOAD_PROC(SCardWriteCacheW);
|
||||
WINSCARD_LOAD_PROC(SCardGetReaderIconA);
|
||||
WINSCARD_LOAD_PROC(SCardGetReaderIconW);
|
||||
WINSCARD_LOAD_PROC(SCardGetDeviceTypeIdA);
|
||||
WINSCARD_LOAD_PROC(SCardGetDeviceTypeIdW);
|
||||
WINSCARD_LOAD_PROC(SCardGetReaderDeviceInstanceIdA);
|
||||
WINSCARD_LOAD_PROC(SCardGetReaderDeviceInstanceIdW);
|
||||
WINSCARD_LOAD_PROC(SCardListReadersWithDeviceInstanceIdA);
|
||||
WINSCARD_LOAD_PROC(SCardListReadersWithDeviceInstanceIdW);
|
||||
WINSCARD_LOAD_PROC(SCardAudit);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Smart Card API
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.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 WINPR_SMARTCARD_WINSCARD_PRIVATE_H
|
||||
#define WINPR_SMARTCARD_WINSCARD_PRIVATE_H
|
||||
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#define WINSCARD_LOAD_PROC(_name, ...) \
|
||||
WinSCard_SCardApiFunctionTable.pfn ## _name = (fn ## _name) GetProcAddress(g_WinSCardModule, #_name);
|
||||
|
||||
int WinSCard_InitializeSCardApi(void);
|
||||
PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void);
|
||||
|
||||
#endif /* WINPR_SMARTCARD_WINSCARD_PRIVATE_H */
|
|
@ -0,0 +1,2 @@
|
|||
TestSmartCard
|
||||
TestSmartCard.c
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
set(MODULE_NAME "TestSmartCard")
|
||||
set(MODULE_PREFIX "TEST_SMARTCARD")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestSmartCardListReaders.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-smartcard winpr-crt)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
int TestSmartCardListReaders(int argc, char* argv[])
|
||||
{
|
||||
LONG lStatus;
|
||||
LPTSTR pReader;
|
||||
SCARDCONTEXT hSC;
|
||||
LPTSTR pmszReaders = NULL;
|
||||
DWORD cch = SCARD_AUTOALLOCATE;
|
||||
|
||||
lStatus = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC);
|
||||
|
||||
if (lStatus != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardEstablishContext failure: %s (0x%08X)\n",
|
||||
SCardGetErrorString(lStatus), (int) lStatus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lStatus = SCardListReaders(hSC, NULL, (LPTSTR) &pmszReaders, &cch);
|
||||
|
||||
if (lStatus != SCARD_S_SUCCESS)
|
||||
{
|
||||
if (lStatus == SCARD_E_NO_READERS_AVAILABLE)
|
||||
{
|
||||
printf("SCARD_E_NO_READERS_AVAILABLE\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pReader = pmszReaders;
|
||||
|
||||
while (*pReader)
|
||||
{
|
||||
printf("Reader: %s\n", pReader);
|
||||
pReader = pReader + strlen((CHAR*) pReader) + 1;
|
||||
}
|
||||
|
||||
lStatus = SCardFreeMemory(hSC, pmszReaders);
|
||||
|
||||
if (lStatus != SCARD_S_SUCCESS)
|
||||
printf("Failed SCardFreeMemory\n");
|
||||
}
|
||||
|
||||
SCardReleaseContext(hSC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -100,8 +100,9 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
|
|||
HANDLE handle;
|
||||
WINPR_THREAD* thread;
|
||||
|
||||
thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD));
|
||||
ZeroMemory(thread, sizeof(WINPR_THREAD));
|
||||
thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
thread->started = FALSE;
|
||||
thread->dwStackSize = dwStackSize;
|
||||
|
|
|
@ -133,14 +133,20 @@ void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj)
|
|||
* Shift a section of the list.
|
||||
*/
|
||||
|
||||
void ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
||||
BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
if (arrayList->size + count > arrayList->capacity)
|
||||
{
|
||||
arrayList->capacity *= arrayList->growthFactor;
|
||||
arrayList->array = (void**) realloc(arrayList->array, sizeof(void*) * arrayList->capacity);
|
||||
void **newArray;
|
||||
int newCapacity = arrayList->capacity * arrayList->growthFactor;
|
||||
|
||||
newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity);
|
||||
if (!newArray)
|
||||
return FALSE;
|
||||
arrayList->array = newArray;
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
|
||||
MoveMemory(&arrayList->array[index + count], &arrayList->array[index], (arrayList->size - index) * sizeof(void*));
|
||||
|
@ -153,6 +159,7 @@ void ArrayList_Shift(wArrayList* arrayList, int index, int count)
|
|||
MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void*));
|
||||
arrayList->size += count;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,20 +208,27 @@ BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
|||
|
||||
int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
int index;
|
||||
int index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (arrayList->size + 1 > arrayList->capacity)
|
||||
{
|
||||
arrayList->capacity *= arrayList->growthFactor;
|
||||
arrayList->array = (void**) realloc(arrayList->array, sizeof(void*) * arrayList->capacity);
|
||||
void **newArray;
|
||||
int newCapacity = arrayList->capacity * arrayList->growthFactor;
|
||||
newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity);
|
||||
if (!newArray)
|
||||
goto out;
|
||||
|
||||
arrayList->array = newArray;
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
|
||||
arrayList->array[arrayList->size++] = obj;
|
||||
index = arrayList->size;
|
||||
|
||||
out:
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
|
@ -225,29 +239,38 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
|||
* Inserts an element into the ArrayList at the specified index.
|
||||
*/
|
||||
|
||||
void ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
ArrayList_Shift(arrayList, index, 1);
|
||||
arrayList->array[index] = obj;
|
||||
if (!ArrayList_Shift(arrayList, index, 1))
|
||||
{
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayList->array[index] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of a specific object from the ArrayList.
|
||||
*/
|
||||
|
||||
void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
BOOL ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
int index;
|
||||
BOOL found = FALSE;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
@ -262,28 +285,32 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
|||
}
|
||||
|
||||
if (found)
|
||||
ArrayList_Shift(arrayList, index, -1);
|
||||
ret = ArrayList_Shift(arrayList, index, -1);
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified index of the ArrayList.
|
||||
*/
|
||||
|
||||
void ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
ArrayList_Shift(arrayList, index, -1);
|
||||
ret = ArrayList_Shift(arrayList, index, -1);
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,24 +405,24 @@ wArrayList* ArrayList_New(BOOL synchronized)
|
|||
{
|
||||
wArrayList* arrayList = NULL;
|
||||
|
||||
arrayList = (wArrayList*) malloc(sizeof(wArrayList));
|
||||
arrayList = (wArrayList *)calloc(1, sizeof(wArrayList));
|
||||
if (!arrayList)
|
||||
return NULL;
|
||||
|
||||
if (arrayList)
|
||||
{
|
||||
arrayList->synchronized = synchronized;
|
||||
arrayList->synchronized = synchronized;
|
||||
arrayList->capacity = 32;
|
||||
arrayList->growthFactor = 2;
|
||||
|
||||
arrayList->size = 0;
|
||||
arrayList->capacity = 32;
|
||||
arrayList->growthFactor = 2;
|
||||
|
||||
arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity);
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000);
|
||||
|
||||
ZeroMemory(&arrayList->object, sizeof(wObject));
|
||||
}
|
||||
arrayList->array = (void **)malloc(arrayList->capacity * sizeof(void *));
|
||||
if (!arrayList->array)
|
||||
goto out_free;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000);
|
||||
return arrayList;
|
||||
|
||||
out_free:
|
||||
free(arrayList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ArrayList_Free(wArrayList* arrayList)
|
||||
|
|
|
@ -34,14 +34,20 @@
|
|||
* Methods
|
||||
*/
|
||||
|
||||
void BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
|
||||
BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
if (pool->aSize + count > pool->aCapacity)
|
||||
{
|
||||
pool->aCapacity *= 2;
|
||||
pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity);
|
||||
wBufferPoolItem *newArray;
|
||||
int newCapacity = pool->aCapacity * 2;
|
||||
|
||||
newArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * newCapacity);
|
||||
if (!newArray)
|
||||
return FALSE;
|
||||
pool->aArray = newArray;
|
||||
pool->aCapacity = newCapacity;
|
||||
}
|
||||
|
||||
MoveMemory(&pool->aArray[index + count], &pool->aArray[index], (pool->aSize - index) * sizeof(wBufferPoolItem));
|
||||
|
@ -52,16 +58,21 @@ void BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
|
|||
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wBufferPoolItem));
|
||||
pool->aSize += count;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
|
||||
BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
if (pool->uSize + count > pool->uCapacity)
|
||||
{
|
||||
pool->uCapacity *= 2;
|
||||
pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity);
|
||||
int newUCapacity = pool->uCapacity * 2;
|
||||
wBufferPoolItem *newUArray = (wBufferPoolItem *)realloc(pool->uArray, sizeof(wBufferPoolItem) *newUCapacity);
|
||||
if (!newUArray)
|
||||
return FALSE;
|
||||
pool->uCapacity = newUCapacity;
|
||||
pool->uArray = newUArray;
|
||||
}
|
||||
|
||||
MoveMemory(&pool->uArray[index + count], &pool->uArray[index], (pool->uSize - index) * sizeof(wBufferPoolItem));
|
||||
|
@ -72,6 +83,7 @@ void BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
|
|||
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wBufferPoolItem));
|
||||
pool->uSize += count;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,6 +184,9 @@ void* BufferPool_Take(wBufferPool* pool, int size)
|
|||
else
|
||||
buffer = malloc(pool->fixedSize);
|
||||
}
|
||||
|
||||
if (!buffer)
|
||||
goto out_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -225,17 +240,30 @@ void* BufferPool_Take(wBufferPool* pool, int size)
|
|||
}
|
||||
else
|
||||
{
|
||||
buffer = realloc(buffer, size);
|
||||
void *newBuffer = realloc(buffer, size);
|
||||
if (!newBuffer)
|
||||
goto out_error;
|
||||
|
||||
buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
BufferPool_ShiftAvailable(pool, foundIndex, -1);
|
||||
if (!BufferPool_ShiftAvailable(pool, foundIndex, -1))
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
if (!buffer)
|
||||
goto out_error;
|
||||
|
||||
if (pool->uSize + 1 > pool->uCapacity)
|
||||
{
|
||||
pool->uCapacity *= 2;
|
||||
pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity);
|
||||
int newUCapacity = pool->uCapacity * 2;
|
||||
wBufferPoolItem *newUArray = (wBufferPoolItem *)realloc(pool->uArray, sizeof(wBufferPoolItem) * newUCapacity);
|
||||
if (!newUArray)
|
||||
goto out_error;
|
||||
|
||||
pool->uCapacity = newUCapacity;
|
||||
pool->uArray = newUArray;
|
||||
}
|
||||
|
||||
pool->uArray[pool->uSize].buffer = buffer;
|
||||
|
@ -247,13 +275,18 @@ void* BufferPool_Take(wBufferPool* pool, int size)
|
|||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return buffer;
|
||||
|
||||
out_error:
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a buffer to the pool.
|
||||
*/
|
||||
|
||||
void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
BOOL BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
{
|
||||
int size = 0;
|
||||
int index = 0;
|
||||
|
@ -268,8 +301,13 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
|||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
pool->capacity *= 2;
|
||||
pool->array = (void**) realloc(pool->array, sizeof(void*) * pool->capacity);
|
||||
int newCapacity = pool->capacity * 2;
|
||||
void **newArray = (void **)realloc(pool->array, sizeof(void*) * newCapacity);
|
||||
if (!newArray)
|
||||
goto out_error;
|
||||
|
||||
pool->capacity = newCapacity;
|
||||
pool->array = newArray;
|
||||
}
|
||||
|
||||
pool->array[(pool->size)++] = buffer;
|
||||
|
@ -290,15 +328,21 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
|||
if (found)
|
||||
{
|
||||
size = pool->uArray[index].size;
|
||||
BufferPool_ShiftUsed(pool, index, -1);
|
||||
if (!BufferPool_ShiftUsed(pool, index, -1))
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
if ((pool->aSize + 1) >= pool->aCapacity)
|
||||
{
|
||||
pool->aCapacity *= 2;
|
||||
pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity);
|
||||
int newCapacity = pool->aCapacity * 2;
|
||||
wBufferPoolItem *newArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * newCapacity);
|
||||
if (!newArray)
|
||||
goto out_error;
|
||||
|
||||
pool->aCapacity = newCapacity;
|
||||
pool->aArray = newArray;
|
||||
}
|
||||
|
||||
pool->aArray[pool->aSize].buffer = buffer;
|
||||
|
@ -309,6 +353,12 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
|||
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return TRUE;
|
||||
|
||||
out_error:
|
||||
if (pool->synchronized)
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -92,6 +92,24 @@ BOOL ListDictionary_IsSynchronized(wListDictionary* listDictionary)
|
|||
return listDictionary->synchronized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock access to the ListDictionary
|
||||
*/
|
||||
|
||||
void ListDictionary_Lock(wListDictionary* listDictionary)
|
||||
{
|
||||
EnterCriticalSection(&listDictionary->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock access to the ListDictionary
|
||||
*/
|
||||
|
||||
void ListDictionary_Unlock(wListDictionary* listDictionary)
|
||||
{
|
||||
LeaveCriticalSection(&listDictionary->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods
|
||||
*/
|
||||
|
@ -416,9 +434,10 @@ wListDictionary* ListDictionary_New(BOOL synchronized)
|
|||
listDictionary->head = NULL;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&listDictionary->lock, 4000);
|
||||
|
||||
ZeroMemory(&(listDictionary->object), sizeof(wObject));
|
||||
}
|
||||
|
||||
ZeroMemory(&listDictionary->object, sizeof(wObject));
|
||||
return listDictionary;
|
||||
}
|
||||
|
||||
|
|
|
@ -221,35 +221,37 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
|||
{
|
||||
wQueue* queue = NULL;
|
||||
|
||||
queue = (wQueue*) malloc(sizeof(wQueue));
|
||||
queue = (wQueue *)calloc(1, sizeof(wQueue));
|
||||
if (!queue)
|
||||
return NULL;
|
||||
|
||||
if (queue)
|
||||
{
|
||||
queue->head = 0;
|
||||
queue->tail = 0;
|
||||
queue->size = 0;
|
||||
queue->capacity = 32;
|
||||
queue->growthFactor = 2;
|
||||
|
||||
queue->capacity = 32;
|
||||
queue->growthFactor = 2;
|
||||
queue->synchronized = synchronized;
|
||||
|
||||
queue->synchronized = synchronized;
|
||||
if (capacity > 0)
|
||||
queue->capacity = capacity;
|
||||
|
||||
if (capacity > 0)
|
||||
queue->capacity = capacity;
|
||||
if (growthFactor > 0)
|
||||
queue->growthFactor = growthFactor;
|
||||
|
||||
if (growthFactor > 0)
|
||||
queue->growthFactor = growthFactor;
|
||||
queue->array = (void **)calloc(queue->capacity, sizeof(void *));
|
||||
if (!queue->array)
|
||||
goto out_free;
|
||||
|
||||
queue->array = (void**) malloc(sizeof(void*) * queue->capacity);
|
||||
ZeroMemory(queue->array, sizeof(void*) * queue->capacity);
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&queue->lock, 4000);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
ZeroMemory(&queue->object, sizeof(wObject));
|
||||
}
|
||||
InitializeCriticalSectionAndSpinCount(&queue->lock, 4000);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!queue->event)
|
||||
goto out_free_array;
|
||||
|
||||
return queue;
|
||||
|
||||
out_free_array:
|
||||
free(queue->array);
|
||||
out_free:
|
||||
free(queue);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Queue_Free(wQueue* queue)
|
||||
|
|
|
@ -86,6 +86,35 @@ void winpr_CArrayDump(BYTE* data, int length, int width)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
char* winpr_BinToHexString(BYTE* data, int length, BOOL space)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
char* p;
|
||||
int ln, hn;
|
||||
char bin2hex[] = "0123456789ABCDEF";
|
||||
|
||||
n = space ? 3 : 2;
|
||||
|
||||
p = (char*) malloc((length + 1) * n);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
ln = data[i] & 0xF;
|
||||
hn = (data[i] >> 4) & 0xF;
|
||||
|
||||
p[i * n] = bin2hex[hn];
|
||||
p[(i * n) + 1] = bin2hex[ln];
|
||||
|
||||
if (space)
|
||||
p[(i * n) + 2] = ' ';
|
||||
}
|
||||
|
||||
p[length * n] = '\0';
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int wvprintfx(const char *fmt, va_list args)
|
||||
{
|
||||
return trio_vprintf(fmt, args);
|
||||
|
|
|
@ -456,6 +456,15 @@ void WLog_Uninit()
|
|||
{
|
||||
wLog* root = WLog_GetRoot();
|
||||
|
||||
DWORD index;
|
||||
wLog* child = NULL;
|
||||
|
||||
for (index = 0; index < root->ChildrenCount; index++)
|
||||
{
|
||||
child = root->Children[index];
|
||||
WLog_Free(child);
|
||||
}
|
||||
|
||||
WLog_Free(root);
|
||||
g_RootLog = NULL;
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ int TestWtsApiEnumerateSessions(int argc, char* argv[])
|
|||
if (!bSuccess)
|
||||
{
|
||||
printf("WTSEnumerateSessions failed: %d\n", (int) GetLastError());
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("WTSEnumerateSessions count: %d\n", count);
|
||||
printf("WTSEnumerateSessions count: %d\n", (int) count);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue