Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2014-04-14 14:17:37 -04:00
commit 94f2a52196
59 changed files with 10074 additions and 3104 deletions

View File

@ -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")

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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]"

View File

@ -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})

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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)

15
cmake/FindPCSCWinPR.cmake Normal file
View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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)

View File

@ -55,9 +55,6 @@ void http_context_free(HttpContext* http_context);
struct _http_request
{
int count;
char** lines;
char* Method;
char* URI;
char* AuthScheme;

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -1087,6 +1087,7 @@ void mcs_free(rdpMcs* mcs)
{
if (mcs)
{
free(mcs->channels);
free(mcs);
}
}

View File

@ -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;
}
/**

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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
{

View File

@ -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()

View File

@ -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}")

View File

@ -0,0 +1,3 @@
LIBRARY "libwinpr-smartcard"
EXPORTS

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -0,0 +1,2 @@
TestSmartCard
TestSmartCard.c

View File

@ -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")

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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;
}
/**

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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++)
{