Merge pull request #2148 from awakecoding/master

Virtual Channel System Improvement
This commit is contained in:
Marc-André Moreau 2014-10-14 21:36:36 -04:00
commit 4c455b8a40
32 changed files with 2077 additions and 492 deletions

View File

@ -48,9 +48,17 @@ typedef BOOL (*psPeerLogon)(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* ident
typedef int (*psPeerSendChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size);
typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
typedef HANDLE (*psPeerVirtualChannelOpen)(freerdp_peer* client, const char* name, UINT32 flags);
typedef BOOL (*psPeerVirtualChannelClose)(freerdp_peer* client, HANDLE hChannel);
typedef int (*psPeerVirtualChannelRead)(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length);
typedef int (*psPeerVirtualChannelWrite)(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length);
typedef void* (*psPeerVirtualChannelGetData)(freerdp_peer* client, HANDLE hChannel);
typedef int (*psPeerVirtualChannelSetData)(freerdp_peer* client, HANDLE hChannel, void* data);
struct rdp_freerdp_peer
{
rdpContext* context;
int sockfd;
char hostname[50];
@ -79,6 +87,13 @@ struct rdp_freerdp_peer
psPeerSendChannelData SendChannelData;
psPeerReceiveChannelData ReceiveChannelData;
psPeerVirtualChannelOpen VirtualChannelOpen;
psPeerVirtualChannelClose VirtualChannelClose;
psPeerVirtualChannelRead VirtualChannelRead;
psPeerVirtualChannelWrite VirtualChannelWrite;
psPeerVirtualChannelGetData VirtualChannelGetData;
psPeerVirtualChannelSetData VirtualChannelSetData;
int pId;
UINT32 ack_frame_id;
BOOL local;

View File

@ -2332,15 +2332,15 @@ int freerdp_image24_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
dstFlip = FREERDP_PIXEL_FORMAT_FLIP(DstFormat);
dstType = FREERDP_PIXEL_FORMAT_TYPE(DstFormat);
nSrcPad = (nSrcStep - (nWidth * srcBytesPerPixel));
nDstPad = (nDstStep - (nWidth * dstBytesPerPixel));
if (nSrcStep < 0)
nSrcStep = srcBytesPerPixel * nWidth;
if (nDstStep < 0)
nDstStep = dstBytesPerPixel * nWidth;
nSrcPad = (nSrcStep - (nWidth * srcBytesPerPixel));
nDstPad = (nDstStep - (nWidth * dstBytesPerPixel));
if (srcFlip != dstFlip)
vFlip = TRUE;
@ -2448,7 +2448,83 @@ int freerdp_image24_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
}
else if (dstBytesPerPixel == 3)
{
BYTE* pSrcPixel;
BYTE* pDstPixel;
if (!invert)
{
if (!vFlip)
{
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 3)];
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 3)];
for (y = 0; y < nHeight; y++)
{
CopyMemory(pDstPixel, pSrcPixel, nWidth * 3);
pSrcPixel = &pSrcPixel[nSrcStep];
pDstPixel = &pDstPixel[nDstStep];
}
}
else
{
pSrcPixel = &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 3)];
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 3)];
for (y = 0; y < nHeight; y++)
{
CopyMemory(pDstPixel, pSrcPixel, nWidth * 3);
pSrcPixel = &pSrcPixel[-nSrcStep];
pDstPixel = &pDstPixel[nDstStep];
}
}
}
else
{
if (!vFlip)
{
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 3)];
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 3)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
pDstPixel[0] = pSrcPixel[2];
pDstPixel[1] = pSrcPixel[1];
pDstPixel[2] = pSrcPixel[0];
pSrcPixel += 3;
pDstPixel += 3;
}
pSrcPixel = &pSrcPixel[nSrcPad];
pDstPixel = &pDstPixel[nDstPad];
}
}
else
{
pSrcPixel = &pSrcData[((nYSrc + nHeight - 1) * nSrcStep) + (nXSrc * 3)];
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 3)];
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
{
pDstPixel[0] = pSrcPixel[2];
pDstPixel[1] = pSrcPixel[1];
pDstPixel[2] = pSrcPixel[0];
pSrcPixel += 3;
pDstPixel += 3;
}
pSrcPixel = &pSrcPixel[-((nSrcStep - nSrcPad) + nSrcStep)];
pDstPixel = &pDstPixel[nDstPad];
}
}
}
return 1;
}
else if (dstBytesPerPixel == 2)
{

View File

@ -265,11 +265,13 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa
SrcFormat = PIXEL_FORMAT_RGB24_VF;
#if 0
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
RleDecompress24to24(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
#endif
if (BufferSize > interleaved->TempSize)
{
@ -292,11 +294,13 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa
SrcFormat = (bpp == 16) ? PIXEL_FORMAT_RGB16_VF : PIXEL_FORMAT_RGB15_VF;
#if 0
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
RleDecompress16to16(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
#endif
if (BufferSize > interleaved->TempSize)
{
@ -319,11 +323,13 @@ int interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pSrcDa
SrcFormat = PIXEL_FORMAT_RGB8_VF;
#if 0
if ((SrcFormat == DstFormat) && !nXDst && !nYDst && (scanline == nDstStep))
{
RleDecompress8to8(pSrcData, SrcSize, pDstData, scanline, nWidth, nHeight);
return 1;
}
#endif
if (BufferSize > interleaved->TempSize)
{

View File

@ -143,8 +143,36 @@ BOOL freerdp_channel_peer_process(freerdp_peer* client, wStream* s, UINT16 chann
Stream_Read_UINT32(s, flags);
chunkLength = Stream_GetRemainingLength(s);
IFCALL(client->ReceiveChannelData, client,
channelId, Stream_Pointer(s), chunkLength, flags, length);
if (client->VirtualChannelRead)
{
UINT32 index;
BOOL found = FALSE;
HANDLE hChannel = 0;
rdpContext* context = client->context;
rdpMcs* mcs = context->rdp->mcs;
rdpMcsChannel* mcsChannel = NULL;
for (index = 0; index < mcs->channelCount; index++)
{
mcsChannel = &(mcs->channels[index]);
if (mcsChannel->ChannelId == channelId)
{
hChannel = (HANDLE) mcsChannel->handle;
found = TRUE;
break;
}
}
if (!found)
return FALSE;
client->VirtualChannelRead(client, hChannel, Stream_Pointer(s), Stream_GetRemainingLength(s));
}
else if (client->ReceiveChannelData)
{
client->ReceiveChannelData(client, channelId, Stream_Pointer(s), chunkLength, flags, length);
}
return TRUE;
}

View File

@ -1059,7 +1059,8 @@ rdpMcs* mcs_new(rdpTransport* transport)
{
rdpMcs* mcs;
mcs = (rdpMcs *)calloc(1, sizeof(rdpMcs));
mcs = (rdpMcs*) calloc(1, sizeof(rdpMcs));
if (!mcs)
return NULL;
@ -1073,7 +1074,11 @@ rdpMcs* mcs_new(rdpTransport* transport)
mcs->channelCount = 0;
mcs->channelMaxCount = CHANNEL_MAX_COUNT;
mcs->channels = (rdpMcsChannel *)calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
mcs->baseChannelId = MCS_GLOBAL_CHANNEL_ID + 1;
mcs->channels = (rdpMcsChannel*) calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
if (!mcs->channels)
goto out_free;

View File

@ -139,6 +139,7 @@ struct rdp_mcs
rdpSettings* settings;
UINT16 userId;
UINT16 baseChannelId;
UINT16 messageChannelId;
DomainParameters domainParameters;

View File

@ -37,6 +37,161 @@
extern const char* DATA_PDU_TYPE_STRINGS[80];
#endif
static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client, const char* name, UINT32 flags)
{
int length;
UINT32 index;
BOOL joined = FALSE;
rdpMcsChannel* mcsChannel = NULL;
rdpPeerChannel* peerChannel = NULL;
rdpMcs* mcs = client->context->rdp->mcs;
if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
return NULL; /* not yet supported */
length = strlen(name);
if (length > 8)
return NULL; /* SVC maximum name length is 8 */
for (index = 0; index < mcs->channelCount; index++)
{
mcsChannel = &(mcs->channels[index]);
if (!mcsChannel->joined)
continue;
if (strncmp(name, mcsChannel->Name, length) == 0)
{
joined = TRUE;
break;
}
}
if (!joined)
return NULL; /* channel is not joined */
peerChannel = (rdpPeerChannel*) mcsChannel->handle;
if (peerChannel)
{
/* channel is already open */
return (HANDLE) peerChannel;
}
peerChannel = (rdpPeerChannel*) calloc(1, sizeof(rdpPeerChannel));
if (peerChannel)
{
peerChannel->index = index;
peerChannel->client = client;
peerChannel->channelFlags = flags;
peerChannel->channelId = mcsChannel->ChannelId;
peerChannel->mcsChannel = mcsChannel;
mcsChannel->handle = (void*) peerChannel;
}
return (HANDLE) peerChannel;
}
static BOOL freerdp_peer_virtual_channel_close(freerdp_peer* client, HANDLE hChannel)
{
rdpMcsChannel* mcsChannel = NULL;
rdpPeerChannel* peerChannel = NULL;
if (!hChannel)
return FALSE;
peerChannel = (rdpPeerChannel*) hChannel;
mcsChannel = peerChannel->mcsChannel;
mcsChannel->handle = NULL;
free(peerChannel);
return TRUE;
}
int freerdp_peer_virtual_channel_read(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length)
{
return 0; /* this needs to be implemented by the server application */
}
static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length)
{
wStream* s;
UINT32 flags;
UINT32 chunkSize;
UINT32 maxChunkSize;
UINT32 totalLength;
rdpRdp* rdp = client->context->rdp;
rdpPeerChannel* peerChannel = (rdpPeerChannel*) hChannel;
rdpMcsChannel* mcsChannel = peerChannel->mcsChannel;
if (!hChannel)
return -1;
if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
return -1; /* not yet supported */
maxChunkSize = rdp->settings->VirtualChannelChunkSize;
totalLength = length;
flags = CHANNEL_FLAG_FIRST;
while (length > 0)
{
s = rdp_send_stream_init(rdp);
if (length > maxChunkSize)
{
chunkSize = rdp->settings->VirtualChannelChunkSize;
}
else
{
chunkSize = length;
flags |= CHANNEL_FLAG_LAST;
}
if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
Stream_Write_UINT32(s, totalLength);
Stream_Write_UINT32(s, flags);
Stream_EnsureRemainingCapacity(s, chunkSize);
Stream_Write(s, buffer, chunkSize);
rdp_send(rdp, s, peerChannel->channelId);
buffer += chunkSize;
length -= chunkSize;
flags = 0;
}
return 1;
}
void* freerdp_peer_virtual_channel_get_data(freerdp_peer* client, HANDLE hChannel)
{
rdpPeerChannel* peerChannel = (rdpPeerChannel*) hChannel;
if (!hChannel)
return NULL;
return peerChannel->extra;
}
int freerdp_peer_virtual_channel_set_data(freerdp_peer* client, HANDLE hChannel, void* data)
{
rdpPeerChannel* peerChannel = (rdpPeerChannel*) hChannel;
if (!hChannel)
return -1;
peerChannel->extra = data;
return 1;
}
static BOOL freerdp_peer_initialize(freerdp_peer* client)
{
rdpRdp* rdp = client->context->rdp;
@ -427,8 +582,7 @@ static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
{
rdpTransport *transport = peer->context->rdp->transport;
rdpTransport* transport = peer->context->rdp->transport;
return tranport_drain_output_buffer(transport);
}
@ -500,6 +654,12 @@ freerdp_peer* freerdp_peer_new(int sockfd)
client->SendChannelData = freerdp_peer_send_channel_data;
client->IsWriteBlocked = freerdp_peer_is_write_blocked;
client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
client->VirtualChannelRead = NULL; /* must be defined by server application */
client->VirtualChannelGetData = freerdp_peer_virtual_channel_get_data;
client->VirtualChannelSetData = freerdp_peer_virtual_channel_set_data;
}
return client;

View File

@ -21,6 +21,9 @@
#define __PEER
#include "rdp.h"
#include "mcs.h"
#include "server.h"
#include <freerdp/peer.h>
#endif /* __PEER */

View File

@ -296,30 +296,30 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel)
}
}
static int wts_write_variable_uint(wStream* stream, UINT32 val)
static int wts_write_variable_uint(wStream* s, UINT32 val)
{
int cb;
if (val <= 0xFF)
{
cb = 0;
Stream_Write_UINT8(stream, val);
Stream_Write_UINT8(s, val);
}
else if (val <= 0xFFFF)
{
cb = 1;
Stream_Write_UINT16(stream, val);
Stream_Write_UINT16(s, val);
}
else
{
cb = 2;
Stream_Write_UINT32(stream, val);
Stream_Write_UINT32(s, val);
}
return cb;
}
static void wts_write_drdynvc_header(wStream *s, BYTE Cmd, UINT32 ChannelId)
static void wts_write_drdynvc_header(wStream* s, BYTE Cmd, UINT32 ChannelId)
{
BYTE* bm;
int cbChId;
@ -477,9 +477,10 @@ HANDLE WTSVirtualChannelManagerGetEventHandle(HANDLE hServer)
return MessageQueue_Event(vcm->queue);
}
static rdpMcsChannel* wts_get_joined_channel_by_name(rdpMcs *mcs, const char *channel_name)
static rdpMcsChannel* wts_get_joined_channel_by_name(rdpMcs* mcs, const char* channel_name)
{
UINT32 index;
if (!mcs || !channel_name || !strlen(channel_name))
return NULL;
@ -489,14 +490,16 @@ static rdpMcsChannel* wts_get_joined_channel_by_name(rdpMcs *mcs, const char *ch
{
if (_strnicmp(mcs->channels[index].Name, channel_name, strlen(channel_name)) == 0)
return &mcs->channels[index];
}
}
return NULL;
}
}
return NULL;
}
static rdpMcsChannel* wts_get_joined_channel_by_id(rdpMcs *mcs, const UINT16 channel_id)
static rdpMcsChannel* wts_get_joined_channel_by_id(rdpMcs* mcs, const UINT16 channel_id)
{
UINT32 index;
if (!mcs || !channel_id)
return NULL;
@ -506,12 +509,13 @@ static rdpMcsChannel* wts_get_joined_channel_by_id(rdpMcs *mcs, const UINT16 cha
{
if (mcs->channels[index].ChannelId == channel_id)
return &mcs->channels[index];
}
}
return NULL;
}
}
return NULL;
}
BOOL WTSIsChannelJoinedByName(freerdp_peer *client, const char *channel_name)
BOOL WTSIsChannelJoinedByName(freerdp_peer* client, const char* channel_name)
{
if (!client || !client->context || !client->context->rdp)
return FALSE;
@ -519,7 +523,7 @@ BOOL WTSIsChannelJoinedByName(freerdp_peer *client, const char *channel_name)
return wts_get_joined_channel_by_name(client->context->rdp->mcs, channel_name) == NULL ? FALSE : TRUE;
}
BOOL WTSIsChannelJoinedById(freerdp_peer *client, const UINT16 channel_id)
BOOL WTSIsChannelJoinedById(freerdp_peer* client, const UINT16 channel_id)
{
if (!client || !client->context || !client->context->rdp)
return FALSE;
@ -537,27 +541,30 @@ BOOL WTSVirtualChannelManagerIsChannelJoined(HANDLE hServer, const char* name)
return wts_get_joined_channel_by_name(vcm->rdp->mcs, name) == NULL ? FALSE : TRUE;
}
UINT16 WTSChannelGetId(freerdp_peer *client, const char *channel_name)
UINT16 WTSChannelGetId(freerdp_peer* client, const char* channel_name)
{
rdpMcsChannel *channel;
rdpMcsChannel* channel;
if (!client || !client->context || !client->context->rdp)
return 0;
channel = wts_get_joined_channel_by_name(client->context->rdp->mcs, channel_name);
if (!channel)
return 0;
return channel->ChannelId;
}
BOOL WTSChannelSetHandleByName(freerdp_peer *client, const char *channel_name, void *handle)
BOOL WTSChannelSetHandleByName(freerdp_peer* client, const char* channel_name, void* handle)
{
rdpMcsChannel *channel;
rdpMcsChannel* channel;
if (!client || !client->context || !client->context->rdp)
return FALSE;
channel = wts_get_joined_channel_by_name(client->context->rdp->mcs, channel_name);
if (!channel)
return FALSE;
@ -565,13 +572,15 @@ BOOL WTSChannelSetHandleByName(freerdp_peer *client, const char *channel_name, v
return TRUE;
}
BOOL WTSChannelSetHandleById(freerdp_peer *client, const UINT16 channel_id, void *handle)
BOOL WTSChannelSetHandleById(freerdp_peer* client, const UINT16 channel_id, void* handle)
{
rdpMcsChannel *channel;
rdpMcsChannel* channel;
if (!client || !client->context || !client->context->rdp)
return FALSE;
channel = wts_get_joined_channel_by_id(client->context->rdp->mcs, channel_id);
if (!channel)
return FALSE;
@ -579,26 +588,30 @@ BOOL WTSChannelSetHandleById(freerdp_peer *client, const UINT16 channel_id, void
return TRUE;
}
void *WTSChannelGetHandleByName(freerdp_peer *client, const char *channel_name)
void* WTSChannelGetHandleByName(freerdp_peer* client, const char *channel_name)
{
rdpMcsChannel *channel;
rdpMcsChannel* channel;
if (!client || !client->context || !client->context->rdp)
return NULL;
channel = wts_get_joined_channel_by_name(client->context->rdp->mcs, channel_name);
if (!channel)
return NULL;
return channel->handle;
}
void *WTSChannelGetHandleById(freerdp_peer *client, const UINT16 channel_id)
void* WTSChannelGetHandleById(freerdp_peer* client, const UINT16 channel_id)
{
rdpMcsChannel *channel;
rdpMcsChannel* channel;
if (!client || !client->context || !client->context->rdp)
return NULL;
channel = wts_get_joined_channel_by_id(client->context->rdp->mcs, channel_id);
if (!channel)
return NULL;
@ -1054,15 +1067,18 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut,
buffer = (BYTE*) (messageCtx + 1);
*pBytesRead = messageCtx->length - messageCtx->offset;
if (Buffer == NULL || BufferSize == 0)
{
return TRUE;
}
if (*pBytesRead > BufferSize)
*pBytesRead = BufferSize;
CopyMemory(Buffer, buffer + messageCtx->offset, *pBytesRead);
messageCtx->offset += *pBytesRead;
if (messageCtx->offset >= messageCtx->length)
{
MessageQueue_Peek(channel->queue, &message, TRUE);

View File

@ -28,9 +28,11 @@
#include <winpr/stream.h>
#include <winpr/collections.h>
typedef struct rdp_peer_channel rdpPeerChannel;
typedef struct WTSVirtualChannelManager WTSVirtualChannelManager;
#include "rdp.h"
#include "mcs.h"
#define CREATE_REQUEST_PDU 0x01
#define DATA_FIRST_PDU 0x02
@ -59,22 +61,23 @@ enum
DVC_OPEN_STATE_CLOSED = 3
};
typedef struct rdp_peer_channel rdpPeerChannel;
struct rdp_peer_channel
{
WTSVirtualChannelManager* vcm;
freerdp_peer* client;
void* extra;
UINT16 index;
UINT32 channelId;
UINT16 channelType;
UINT16 index;
UINT32 channelFlags;
wStream* receiveData;
wMessageQueue* queue;
BYTE dvc_open_state;
UINT32 dvc_total_length;
rdpMcsChannel* mcsChannel;
};
struct WTSVirtualChannelManager

View File

@ -42,8 +42,8 @@ extern "C" {
/* Engine */
rdtkEngine* rdtk_engine_new();
void rdtk_engine_free(rdtkEngine* engine);
RDTK_EXPORT rdtkEngine* rdtk_engine_new();
RDTK_EXPORT void rdtk_engine_free(rdtkEngine* engine);
/* Surface */

View File

@ -138,6 +138,7 @@ typedef struct _wArrayList wArrayList;
WINPR_API int ArrayList_Capacity(wArrayList* arrayList);
WINPR_API int ArrayList_Count(wArrayList* arrayList);
WINPR_API int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems);
WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
@ -326,27 +327,33 @@ WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown);
/* Hash Table */
typedef void (*KEY_VALUE_FREE_FN)(void* context, void* key, void* value);
typedef UINT32 (*HASH_TABLE_HASH_FN)(void* key);
typedef BOOL (*HASH_TABLE_KEY_COMPARE_FN)(void* key1, void* key2);
typedef BOOL (*HASH_TABLE_VALUE_COMPARE_FN)(void* value1, void* value2);
typedef void* (*HASH_TABLE_KEY_CLONE_FN)(void* key);
typedef void* (*HASH_TABLE_VALUE_CLONE_FN)(void* value);
typedef void (*HASH_TABLE_KEY_FREE_FN)(void* key);
typedef void (*HASH_TABLE_VALUE_FREE_FN)(void* value);
struct _wHashTable
{
BOOL synchronized;
CRITICAL_SECTION lock;
long numOfBuckets;
long numOfElements;
int numOfBuckets;
int numOfElements;
float idealRatio;
float lowerRehashThreshold;
float upperRehashThreshold;
wKeyValuePair** bucketArray;
int (*keycmp)(void* key1, void* key2);
int (*valuecmp)(void* value1, void* value2);
unsigned long (*hashFunction)(void* key);
void (*keyDeallocator)(void* key);
void (*valueDeallocator)(void* value);
void* context;
KEY_VALUE_FREE_FN pfnKeyValueFree;
HASH_TABLE_HASH_FN hash;
HASH_TABLE_KEY_COMPARE_FN keyCompare;
HASH_TABLE_VALUE_COMPARE_FN valueCompare;
HASH_TABLE_KEY_CLONE_FN keyClone;
HASH_TABLE_VALUE_CLONE_FN valueClone;
HASH_TABLE_KEY_FREE_FN keyFree;
HASH_TABLE_VALUE_FREE_FN valueFree;
};
typedef struct _wHashTable wHashTable;
@ -359,9 +366,16 @@ WINPR_API BOOL HashTable_ContainsKey(wHashTable* table, void* key);
WINPR_API BOOL HashTable_ContainsValue(wHashTable* table, void* value);
WINPR_API void* HashTable_GetItemValue(wHashTable* table, void* key);
WINPR_API BOOL HashTable_SetItemValue(wHashTable* table, void* key, void* value);
WINPR_API void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree);
WINPR_API int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys);
WINPR_API UINT32 HashTable_PointerHash(void* pointer);
WINPR_API BOOL HashTable_PointerCompare(void* pointer1, void* pointer2);
WINPR_API UINT32 HashTable_StringHash(void* key);
WINPR_API BOOL HashTable_StringCompare(void* string1, void* string2);
WINPR_API void* HashTable_StringClone(void* str);
WINPR_API void HashTable_StringFree(void* str);
WINPR_API wHashTable* HashTable_New(BOOL synchronized);
WINPR_API void HashTable_Free(wHashTable* table);

View File

@ -73,16 +73,10 @@ WINPR_API DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSi
WINPR_API BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock);
WINPR_API BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock);
WINPR_API LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge);
WINPR_API DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize);
WINPR_API BOOL SetEnvironmentVariableEBA(LPSTR * envBlock,LPCSTR lpName, LPCSTR lpValue);
#ifdef __cplusplus
}
#endif
#ifdef UNICODE
#define GetCurrentDirectory GetCurrentDirectoryW
#define SetCurrentDirectory SetCurrentDirectoryW
@ -111,5 +105,18 @@ WINPR_API BOOL SetEnvironmentVariableEBA(LPSTR * envBlock,LPCSTR lpName, LPCSTR
#endif
#ifdef __cplusplus
extern "C" {
#endif
WINPR_API LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge);
WINPR_API DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize);
WINPR_API BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue);
#ifdef __cplusplus
}
#endif
#endif /* WINPR_ENVIRONMENT_H */

View File

@ -33,6 +33,9 @@ extern "C" {
#ifndef _WIN32
#define DUPLICATE_CLOSE_SOURCE 0x00000001
#define DUPLICATE_SAME_ACCESS 0x00000002
#define HANDLE_FLAG_INHERIT 0x00000001
#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002

View File

@ -58,14 +58,20 @@ typedef struct _wIniFile wIniFile;
extern "C" {
#endif
WINPR_API int IniFile_Parse(wIniFile* ini, const char* filename);
WINPR_API int IniFile_ParseString(wIniFile* ini, const char* iniString);
WINPR_API int IniFile_ReadBuffer(wIniFile* ini, const char* buffer);
WINPR_API int IniFile_ReadFile(wIniFile* ini, const char* filename);
WINPR_API char* IniFile_WriteBuffer(wIniFile* ini);
WINPR_API int IniFile_WriteFile(wIniFile* ini, const char* filename);
WINPR_API char** IniFile_GetSectionNames(wIniFile* ini, int* count);
WINPR_API char** IniFile_GetSectionKeyNames(wIniFile* ini, const char* section, int* count);
WINPR_API char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const char* key);
WINPR_API UINT32 IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key);
WINPR_API const char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const char* key);
WINPR_API int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key);
WINPR_API int IniFile_SetKeyValueString(wIniFile* ini, const char* section, const char* key, const char* value);
WINPR_API int IniFile_SetKeyValueInt(wIniFile* ini, const char* section, const char* key, int value);
WINPR_API wIniFile* IniFile_New();
WINPR_API void IniFile_Free(wIniFile* ini);

View File

@ -73,24 +73,6 @@
#endif
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
#ifdef __GNUC__
#define DECLSPEC_EXPORT __attribute__((dllexport))
#define DECLSPEC_IMPORT __attribute__((dllimport))
#else
#define DECLSPEC_EXPORT __declspec(dllexport)
#define DECLSPEC_IMPORT __declspec(dllimport)
#endif
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DECLSPEC_EXPORT __attribute__ ((visibility("default")))
#define DECLSPEC_IMPORT
#else
#define DECLSPEC_EXPORT
#define DECLSPEC_IMPORT
#endif
#endif
#ifndef DECLSPEC_NORETURN
#if (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
#define DECLSPEC_NORETURN __declspec(noreturn)
@ -971,5 +953,23 @@ char (*__countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
#ifdef __GNUC__
#define DECLSPEC_EXPORT __attribute__((dllexport))
#define DECLSPEC_IMPORT __attribute__((dllimport))
#else
#define DECLSPEC_EXPORT __declspec(dllexport)
#define DECLSPEC_IMPORT __declspec(dllimport)
#endif
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DECLSPEC_EXPORT __attribute__ ((visibility("default")))
#define DECLSPEC_IMPORT
#else
#define DECLSPEC_EXPORT
#define DECLSPEC_IMPORT
#endif
#endif
#endif /* WINPR_SPEC_H */

View File

@ -71,6 +71,7 @@ PCSTR inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize);
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <winpr/error.h>
@ -79,6 +80,10 @@ PCSTR inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize);
typedef UINT_PTR SOCKET;
typedef struct sockaddr_storage SOCKADDR_STORAGE;
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (SOCKET)(~0)
#endif
#define WSADESCRIPTION_LEN 256
#define WSASYS_STATUS_LEN 128

View File

@ -410,8 +410,6 @@ typedef struct tagWTSSESSION_NOTIFICATION
#define WTS_SESSION_LOCK 0x7
#define WTS_SESSION_UNLOCK 0x8
#define WTS_SESSION_REMOTE_CONTROL 0x9
#define WTS_SESSION_CREATE 0xA
#define WTS_SESSION_TERMINATE 0xB
#ifdef __cplusplus
extern "C" {
@ -453,10 +451,12 @@ WINPR_API HWND WINAPI CreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName,
LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
#ifndef WINPR_NO_CREATE_WINDOW
#define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam) \
CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam) \
CreateWindowExW(0L, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#endif
WINPR_API HWND WINAPI FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName);
WINPR_API HWND WINAPI FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName);
@ -519,7 +519,9 @@ WINPR_API LRESULT WINAPI DefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPAR
#define RegisterClass RegisterClassW
#define RegisterClassEx RegisterClassExW
#define UnregisterClass UnregisterClassW
#ifndef WINPR_NO_CREATE_WINDOW
#define CreateWindow CreateWindowW
#endif
#define CreateWindowEx CreateWindowExW
#define FindWindow FindWindowW
#define FindWindowEx FindWindowExW
@ -540,7 +542,9 @@ WINPR_API LRESULT WINAPI DefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPAR
#define RegisterClass RegisterClassA
#define RegisterClassEx RegisterClassExA
#define UnregisterClass UnregisterClassA
#ifndef WINPR_NO_CREATE_WINDOW
#define CreateWindow CreateWindowA
#endif
#define CreateWindowEx CreateWindowExA
#define FindWindow FindWindowA
#define FindWindowEx FindWindowExA
@ -561,5 +565,13 @@ WINPR_API LRESULT WINAPI DefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPAR
#endif
#ifndef WTS_SESSION_CREATE
#define WTS_SESSION_CREATE 0xA
#endif
#ifndef WTS_SESSION_TERMINATE
#define WTS_SESSION_TERMINATE 0xB
#endif
#endif /* WINPR_WND_H */

View File

@ -167,63 +167,6 @@ DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
return length;
}
DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
{
int vLength = 0;
char* env = NULL;
const char * penvb = envBlock;
char *foundEquals;
int nLength, fLength, lpNameLength;
if (!lpName || NULL == envBlock)
return 0;
lpNameLength = strlen(lpName);
if (0 == lpNameLength)
return 0;
while (*penvb && *(penvb+1))
{
fLength = strlen(penvb);
foundEquals = strstr(penvb,"=");
if (foundEquals == NULL)
{
/* if no = sign is found the envBlock is broken */
return 0;
}
nLength = foundEquals - penvb;
if (nLength != lpNameLength)
{
penvb += (fLength +1);
continue;
}
#ifdef _WIN32
if (strnicmp(penvb,lpName,nLength) == 0)
#else
if (strncmp(penvb,lpName,nLength) == 0)
#endif
{
env = foundEquals + 1;
break;
}
penvb += (fLength +1);
}
if (!env)
return 0;
vLength = strlen(env);
if ((vLength + 1 > nSize) || (!lpBuffer))
return vLength + 1;
CopyMemory(lpBuffer, env, vLength + 1);
return vLength;
}
DWORD GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize)
{
return 0;
@ -248,38 +191,6 @@ BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
return TRUE;
}
BOOL SetEnvironmentVariableEBA(LPSTR * envBlock,LPCSTR lpName, LPCSTR lpValue)
{
int length;
char* envstr;
char* newEB;
if (!lpName)
return FALSE;
if (lpValue)
{
length = strlen(lpName) + strlen(lpValue) + 2; /* +2 because of = and \0 */
envstr = (char*) malloc(length + 1); /* +1 because of closing \0 */
sprintf_s(envstr, length, "%s=%s", lpName, lpValue);
}
else
{
length = strlen(lpName) + 2; /* +2 because of = and \0 */
envstr = (char*) malloc(length + 1); /* +1 because of closing \0 */
sprintf_s(envstr, length, "%s=", lpName);
}
envstr[length] = '\0';
newEB = MergeEnvironmentStrings((LPCSTR)*envBlock,envstr);
free(envstr);
if (*envBlock != NULL)
free(*envBlock);
*envBlock = newEB;
return TRUE;
}
BOOL SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
{
return TRUE;
@ -342,137 +253,6 @@ LPCH GetEnvironmentStrings(VOID)
return lpszEnvironmentBlock;
}
LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
{
const char * cp;
char* p;
int offset;
int length;
const char* envp;
DWORD cchEnvironmentBlock;
LPCH lpszEnvironmentBlock;
const char **mergeStrings;
int mergeStringLenth;
int mergeArraySize = 128;
int run;
int mergeLength;
int foundMerge;
char * foundEquals;
// first build an char ** of the merge env strings
mergeStrings = (LPCSTR*) malloc(mergeArraySize * sizeof(char *));
ZeroMemory(mergeStrings,mergeArraySize * sizeof(char *));
mergeStringLenth = 0;
cp = merge;
while( *cp && *(cp+1)) {
length = strlen(cp);
if (mergeStringLenth == mergeArraySize ) {
mergeArraySize += 128;
mergeStrings = (LPCSTR*) realloc(mergeStrings, mergeArraySize * sizeof(char *));
}
mergeStrings[mergeStringLenth] = cp;
cp += length + 1;
mergeStringLenth++;
}
offset = 0;
cchEnvironmentBlock = 128;
lpszEnvironmentBlock = (LPCH) malloc(cchEnvironmentBlock * sizeof(CHAR));
envp = original;
while ((original != NULL) && (*envp && *(envp+1)))
{
length = strlen(envp);
while ((offset + length + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
}
p = &(lpszEnvironmentBlock[offset]);
// check if this value is in the mergeStrings
foundMerge = 0;
for (run = 0; run < mergeStringLenth; run ++) {
if (mergeStrings[run] == NULL) {
continue;
}
mergeLength =strlen(mergeStrings[run]);
foundEquals = strstr(mergeStrings[run],"=");
if (foundEquals == NULL) {
continue;
}
#ifdef _WIN32
if (strnicmp(envp,mergeStrings[run],foundEquals - mergeStrings[run] + 1) == 0) {
#else
if (strncmp(envp,mergeStrings[run],foundEquals - mergeStrings[run] + 1) == 0) {
#endif
// found variable in merge list ... use this ....
if (*(foundEquals + 1) == '\0') {
// check if the argument is set ... if not remove variable ...
foundMerge = 1;
} else {
while ((offset + mergeLength + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
}
foundMerge = 1;
CopyMemory(p, mergeStrings[run], mergeLength);
mergeStrings[run] = NULL;
p[mergeLength] = '\0';
offset += (mergeLength + 1);
}
}
}
if (foundMerge == 0) {
CopyMemory(p, envp, length * sizeof(CHAR));
p[length] = '\0';
offset += (length + 1);
}
envp += (length +1);
}
// now merge the not already merged env
for (run = 0; run < mergeStringLenth; run ++) {
if (mergeStrings[run] == NULL) {
continue;
}
mergeLength =strlen(mergeStrings[run]);
while ((offset + mergeLength + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
}
p = &(lpszEnvironmentBlock[offset]);
CopyMemory(p, mergeStrings[run], mergeLength);
mergeStrings[run] = NULL;
p[mergeLength] = '\0';
offset += (mergeLength + 1);
}
lpszEnvironmentBlock[offset] = '\0';
free(mergeStrings);
return lpszEnvironmentBlock;
}
LPWCH GetEnvironmentStringsW(VOID)
{
return NULL;
@ -513,3 +293,256 @@ BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock)
#endif
LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
{
const char* cp;
char* p;
int offset;
int length;
const char* envp;
DWORD cchEnvironmentBlock;
LPCH lpszEnvironmentBlock;
const char** mergeStrings;
int mergeStringLength;
int mergeArraySize = 128;
int run;
int mergeLength;
int foundMerge;
char* foundEquals;
mergeStrings = (LPCSTR*) calloc(mergeArraySize, sizeof(char*));
if (!mergeStrings)
return NULL;
mergeStringLength = 0;
cp = merge;
while (*cp && *(cp + 1))
{
length = strlen(cp);
if (mergeStringLength == mergeArraySize)
{
mergeArraySize += 128;
mergeStrings = (LPCSTR*) realloc(mergeStrings, mergeArraySize * sizeof(char*));
if (!mergeStrings)
return NULL;
}
mergeStrings[mergeStringLength] = cp;
cp += length + 1;
mergeStringLength++;
}
offset = 0;
cchEnvironmentBlock = 128;
lpszEnvironmentBlock = (LPCH) malloc(cchEnvironmentBlock * sizeof(CHAR));
if (!lpszEnvironmentBlock)
return NULL;
envp = original;
while ((original != NULL) && (*envp && *(envp+1)))
{
length = strlen(envp);
while ((offset + length + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
if (!lpszEnvironmentBlock)
return NULL;
}
p = &(lpszEnvironmentBlock[offset]);
// check if this value is in the mergeStrings
foundMerge = 0;
for (run = 0; run < mergeStringLength; run ++)
{
if (!mergeStrings[run])
continue;
mergeLength = strlen(mergeStrings[run]);
foundEquals = strstr(mergeStrings[run], "=");
if (!foundEquals)
continue;
if (strncmp(envp, mergeStrings[run], foundEquals - mergeStrings[run] + 1) == 0)
{
// found variable in merge list ... use this ....
if (*(foundEquals + 1) == '\0')
{
// check if the argument is set ... if not remove variable ...
foundMerge = 1;
}
else
{
while ((offset + mergeLength + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
if (!lpszEnvironmentBlock)
return NULL;
}
foundMerge = 1;
CopyMemory(p, mergeStrings[run], mergeLength);
mergeStrings[run] = NULL;
p[mergeLength] = '\0';
offset += (mergeLength + 1);
}
}
}
if (foundMerge == 0)
{
CopyMemory(p, envp, length * sizeof(CHAR));
p[length] = '\0';
offset += (length + 1);
}
envp += (length +1);
}
// now merge the not already merged env
for (run = 0; run < mergeStringLength; run ++)
{
if (!mergeStrings[run])
continue;
mergeLength = strlen(mergeStrings[run]);
while ((offset + mergeLength + 8) > cchEnvironmentBlock)
{
cchEnvironmentBlock *= 2;
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
if (!lpszEnvironmentBlock)
return NULL;
}
p = &(lpszEnvironmentBlock[offset]);
CopyMemory(p, mergeStrings[run], mergeLength);
mergeStrings[run] = NULL;
p[mergeLength] = '\0';
offset += (mergeLength + 1);
}
lpszEnvironmentBlock[offset] = '\0';
free(mergeStrings);
return lpszEnvironmentBlock;
}
DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
{
int vLength = 0;
char* env = NULL;
char* foundEquals;
const char* penvb = envBlock;
int nLength, fLength, lpNameLength;
if (!lpName || NULL == envBlock)
return 0;
lpNameLength = strlen(lpName);
if (lpNameLength < 1)
return 0;
while (*penvb && *(penvb + 1))
{
fLength = strlen(penvb);
foundEquals = strstr(penvb,"=");
if (!foundEquals)
{
/* if no = sign is found the envBlock is broken */
return 0;
}
nLength = foundEquals - penvb;
if (nLength != lpNameLength)
{
penvb += (fLength +1);
continue;
}
if (strncmp(penvb, lpName, nLength) == 0)
{
env = foundEquals + 1;
break;
}
penvb += (fLength +1);
}
if (!env)
return 0;
vLength = strlen(env);
if ((vLength + 1 > nSize) || (!lpBuffer))
return vLength + 1;
CopyMemory(lpBuffer, env, vLength + 1);
return vLength;
}
BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue)
{
int length;
char* envstr;
char* newEB;
if (!lpName)
return FALSE;
if (lpValue)
{
length = strlen(lpName) + strlen(lpValue) + 2; /* +2 because of = and \0 */
envstr = (char*) malloc(length + 1); /* +1 because of closing \0 */
if (!envstr)
return FALSE;
sprintf_s(envstr, length, "%s=%s", lpName, lpValue);
}
else
{
length = strlen(lpName) + 2; /* +2 because of = and \0 */
envstr = (char*) malloc(length + 1); /* +1 because of closing \0 */
if (!envstr)
return FALSE;
sprintf_s(envstr, length, "%s=", lpName);
}
envstr[length] = '\0';
newEB = MergeEnvironmentStrings((LPCSTR) *envBlock, envstr);
free(envstr);
if (*envBlock)
free(*envBlock);
*envBlock = newEB;
return TRUE;
}

View File

@ -276,8 +276,9 @@ BOOL CloseHandle(HANDLE hObject)
}
BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle,
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)
{
*((ULONG_PTR*) lpTargetHandle) = hSourceHandle;
return TRUE;
}

View File

@ -366,6 +366,8 @@ typedef NTSTATUS (WINAPI * NT_DEVICE_IO_CONTROL_FILE_FN)(HANDLE FileHandle, HAND
typedef NTSTATUS (WINAPI * NT_CLOSE_FN)(HANDLE Handle);
typedef NTSTATUS (WINAPI * NT_WAIT_FOR_SINGLE_OBJECT_FN)(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout);
static RTL_INIT_ANSI_STRING_FN pRtlInitAnsiString = NULL;
static RTL_INIT_UNICODE_STRING_FN pRtlInitUnicodeString = NULL;
static RTL_ANSI_STRING_TO_UNICODE_STRING_FN pRtlAnsiStringToUnicodeString = NULL;
@ -377,6 +379,7 @@ static NT_READ_FILE_FN pNtReadFile = NULL;
static NT_WRITE_FILE_FN pNtWriteFile = NULL;
static NT_DEVICE_IO_CONTROL_FILE_FN pNtDeviceIoControlFile = NULL;
static NT_CLOSE_FN pNtClose = NULL;
static NT_WAIT_FOR_SINGLE_OBJECT_FN pNtWaitForSingleObject = NULL;
static void NtdllModuleInit()
{
@ -402,6 +405,7 @@ static void NtdllModuleInit()
pNtWriteFile = (NT_WRITE_FILE_FN) GetProcAddress(NtdllModule, "NtWriteFile");
pNtDeviceIoControlFile = (NT_DEVICE_IO_CONTROL_FILE_FN) GetProcAddress(NtdllModule, "NtDeviceIoControlFile");
pNtClose = (NT_CLOSE_FN) GetProcAddress(NtdllModule, "NtClose");
pNtWaitForSingleObject = (NT_WAIT_FOR_SINGLE_OBJECT_FN) GetProcAddress(NtdllModule, "NtWaitForSingleObject");
}
VOID _RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
@ -533,5 +537,15 @@ NTSTATUS _NtClose(HANDLE Handle)
return pNtClose(Handle);
}
NTSTATUS _NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
{
NtdllModuleInit();
if (!pNtWaitForSingleObject)
return STATUS_INTERNAL_ERROR;
return pNtWaitForSingleObject(Handle, Alertable, Timeout);
}
#endif

View File

@ -147,15 +147,17 @@ RPC_STATUS RpcStringBindingParseW(RPC_WSTR StringBinding, RPC_WSTR* ObjUuid, RPC
RPC_STATUS RpcStringFreeA(RPC_CSTR* String)
{
WLog_ERR(TAG, "Not implemented");
free(String);
if (String)
free(*String);
return RPC_S_OK;
}
RPC_STATUS RpcStringFreeW(RPC_WSTR* String)
{
WLog_ERR(TAG, "Not implemented");
free(String);
if (String)
free(*String);
return RPC_S_OK;
}

View File

@ -52,6 +52,16 @@ int ArrayList_Count(wArrayList *arrayList)
return arrayList->size;
}
/**
* Gets the internal list of items contained in the ArrayList.
*/
int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems)
{
*ppItems = (ULONG_PTR*) arrayList->array;
return arrayList->size;
}
/**
* Gets a value indicating whether the ArrayList has a fixed size.
*/

View File

@ -33,9 +33,50 @@
* http://www.pomakis.com/hashtable/hashtable.h
*/
static int isProbablePrime(long oddNumber)
BOOL HashTable_PointerCompare(void* pointer1, void* pointer2)
{
long i;
return (pointer1 == pointer2);
}
UINT32 HashTable_PointerHash(void* pointer)
{
return ((UINT32) (UINT_PTR) pointer) >> 4;
}
BOOL HashTable_StringCompare(void* string1, void* string2)
{
if (!string1 || !string2)
return (string1 == string2);
return (strcmp((char*) string1, (char*) string2) == 0);
}
UINT32 HashTable_StringHash(void* key)
{
UINT32 c;
UINT32 hash = 5381;
BYTE* str = (BYTE*) key;
/* djb2 algorithm */
while ((c = *str++) != '\0')
hash = (hash * 33) + c;
return hash;
}
void* HashTable_StringClone(void* str)
{
return _strdup((char*) str);
}
void HashTable_StringFree(void* str)
{
free(str);
}
static int HashTable_IsProbablePrime(int oddNumber)
{
int i;
for (i = 3; i < 51; i += 2)
{
@ -48,55 +89,54 @@ static int isProbablePrime(long oddNumber)
return 1; /* maybe */
}
static long calculateIdealNumOfBuckets(wHashTable* table)
static long HashTable_CalculateIdealNumOfBuckets(wHashTable* table)
{
long idealNumOfBuckets = table->numOfElements / ((long) table->idealRatio);
int idealNumOfBuckets = table->numOfElements / ((int) table->idealRatio);
if (idealNumOfBuckets < 5)
idealNumOfBuckets = 5;
else
idealNumOfBuckets |= 0x01;
while (!isProbablePrime(idealNumOfBuckets))
while (!HashTable_IsProbablePrime(idealNumOfBuckets))
idealNumOfBuckets += 2;
return idealNumOfBuckets;
}
void HashTable_Rehash(wHashTable* table, long numOfBuckets)
void HashTable_Rehash(wHashTable* table, int numOfBuckets)
{
int index;
long hashValue;
UINT32 hashValue;
wKeyValuePair* pair;
wKeyValuePair* nextPair;
wKeyValuePair** newBucketArray;
if (numOfBuckets == 0)
numOfBuckets = calculateIdealNumOfBuckets(table);
numOfBuckets = HashTable_CalculateIdealNumOfBuckets(table);
if (numOfBuckets == table->numOfBuckets)
return; /* already the right size! */
newBucketArray = (wKeyValuePair**) malloc(numOfBuckets * sizeof(wKeyValuePair*));
newBucketArray = (wKeyValuePair**) calloc(numOfBuckets, sizeof(wKeyValuePair*));
if (newBucketArray == NULL)
if (!newBucketArray)
{
/* Couldn't allocate memory for the new array. This isn't a fatal
* error; we just can't perform the rehash. */
/*
* Couldn't allocate memory for the new array.
* This isn't a fatal error; we just can't perform the rehash.
*/
return;
}
for (index = 0; index < numOfBuckets; index++)
newBucketArray[index] = NULL;
for (index = 0; index < table->numOfBuckets; index++)
{
pair = table->bucketArray[index];
while (pair != NULL)
while (pair)
{
nextPair = pair->next;
hashValue = table->hashFunction(pair->key) % numOfBuckets;
hashValue = table->hash(pair->key) % numOfBuckets;
pair->next = newBucketArray[hashValue];
newBucketArray[hashValue] = pair;
pair = nextPair;
@ -116,40 +156,21 @@ void HashTable_SetIdealRatio(wHashTable* table, float idealRatio,
table->upperRehashThreshold = upperRehashThreshold;
}
unsigned long HashTable_StringHashFunction(void* key)
{
int c;
unsigned long hash = 5381;
unsigned char* str = (unsigned char*) key;
/* djb2 algorithm */
while ((c = *str++) != '\0')
hash = (hash * 33) + c;
return hash;
}
wKeyValuePair* HashTable_Get(wHashTable* table, void* key)
{
long hashValue = table->hashFunction(key) % table->numOfBuckets;
wKeyValuePair* pair = table->bucketArray[hashValue];
UINT32 hashValue;
wKeyValuePair* pair;
while (pair != NULL && table->keycmp(key, pair->key) != 0)
hashValue = table->hash(key) % table->numOfBuckets;
pair = table->bucketArray[hashValue];
while (pair && !table->keyCompare(key, pair->key))
pair = pair->next;
return pair;
}
static int pointercmp(void* pointer1, void* pointer2)
{
return (pointer1 != pointer2);
}
static unsigned long pointerHashFunction(void* pointer)
{
return ((unsigned long) pointer) >> 4;
}
/**
* C equivalent of the C# Hashtable Class:
* http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx
@ -179,35 +200,51 @@ int HashTable_Count(wHashTable* table)
int HashTable_Add(wHashTable* table, void* key, void* value)
{
int status = 0;
long hashValue;
UINT32 hashValue;
wKeyValuePair* pair;
wKeyValuePair* newPair;
if (!key || !value)
return -1;
if (table->keyClone)
{
key = table->keyClone(key);
if (!key)
return -1;
}
if (table->valueClone)
{
value = table->valueClone(value);
if (!value)
return -1;
}
if (table->synchronized)
EnterCriticalSection(&table->lock);
hashValue = table->hashFunction(key) % table->numOfBuckets;
hashValue = table->hash(key) % table->numOfBuckets;
pair = table->bucketArray[hashValue];
while (pair != NULL && table->keycmp(key, pair->key) != 0)
while (pair && !table->keyCompare(key, pair->key))
pair = pair->next;
if (pair)
{
if (pair->key != key)
{
if (table->keyDeallocator)
table->keyDeallocator((void*) pair->key);
if (table->keyFree)
table->keyFree(pair->key);
pair->key = key;
}
if (pair->value != value)
{
if (table->valueDeallocator)
table->valueDeallocator(pair->value);
if (table->valueFree)
table->valueFree(pair->value);
pair->value = value;
}
}
@ -249,15 +286,19 @@ int HashTable_Add(wHashTable* table, void* key, void* value)
BOOL HashTable_Remove(wHashTable* table, void* key)
{
UINT32 hashValue;
BOOL status = TRUE;
long hashValue = table->hashFunction(key) % table->numOfBuckets;
wKeyValuePair* pair = table->bucketArray[hashValue];
wKeyValuePair* pair = NULL;
wKeyValuePair* previousPair = NULL;
if (table->synchronized)
EnterCriticalSection(&table->lock);
while (pair && table->keycmp(key, pair->key) != 0)
hashValue = table->hash(key) % table->numOfBuckets;
pair = table->bucketArray[hashValue];
while (pair && !table->keyCompare(key, pair->key))
{
previousPair = pair;
pair = pair->next;
@ -269,11 +310,11 @@ BOOL HashTable_Remove(wHashTable* table, void* key)
}
else
{
if (table->keyDeallocator)
table->keyDeallocator((void*) pair->key);
if (table->keyFree)
table->keyFree(pair->key);
if (table->valueDeallocator)
table->valueDeallocator(pair->value);
if (table->valueFree)
table->valueFree(pair->value);
if (previousPair)
previousPair->next = pair->next;
@ -331,6 +372,14 @@ BOOL HashTable_SetItemValue(wHashTable* table, void* key, void* value)
BOOL status = TRUE;
wKeyValuePair* pair;
if (table->valueClone && value)
{
value = table->valueClone(value);
if (!value)
return FALSE;
}
if (table->synchronized)
EnterCriticalSection(&table->lock);
@ -368,14 +417,11 @@ void HashTable_Clear(wHashTable* table)
{
nextPair = pair->next;
if (table->pfnKeyValueFree)
table->pfnKeyValueFree(table->context, pair->key, pair->value);
if (table->keyFree)
table->keyFree(pair->key);
if (table->keyDeallocator)
table->keyDeallocator((void*) pair->key);
if (table->valueDeallocator)
table->valueDeallocator(pair->value);
if (table->valueFree)
table->valueFree(pair->value);
free(pair);
@ -410,8 +456,17 @@ int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys)
iKey = 0;
count = table->numOfElements;
pKeys = (ULONG_PTR*) calloc(count, sizeof(ULONG_PTR));
if (!pKeys)
{
if (table->synchronized)
LeaveCriticalSection(&table->lock);
return -1;
}
for (index = 0; index < table->numOfBuckets; index++)
{
pair = table->bucketArray[index];
@ -491,7 +546,7 @@ BOOL HashTable_ContainsValue(wHashTable* table, void* value)
while (pair)
{
if (table->valuecmp(value, pair->value) == 0)
if (table->valueCompare(value, pair->value))
{
status = TRUE;
break;
@ -510,19 +565,12 @@ BOOL HashTable_ContainsValue(wHashTable* table, void* value)
return status;
}
void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree)
{
table->context = context;
table->pfnKeyValueFree = pfnKeyValueFree;
}
/**
* Construction, Destruction
*/
wHashTable* HashTable_New(BOOL synchronized)
{
int index;
wHashTable* table;
table = (wHashTable*) calloc(1, sizeof(wHashTable));
@ -530,12 +578,13 @@ wHashTable* HashTable_New(BOOL synchronized)
if (table)
{
table->synchronized = synchronized;
InitializeCriticalSectionAndSpinCount(&(table->lock), 4000);
table->numOfBuckets = 64;
table->numOfElements = 0;
table->bucketArray = (wKeyValuePair**) malloc(table->numOfBuckets * sizeof(wKeyValuePair*));
table->bucketArray = (wKeyValuePair**) calloc(table->numOfBuckets, sizeof(wKeyValuePair*));
if (!table->bucketArray)
{
@ -543,18 +592,17 @@ wHashTable* HashTable_New(BOOL synchronized)
return NULL;
}
for (index = 0; index < table->numOfBuckets; index++)
table->bucketArray[index] = NULL;
table->idealRatio = 3.0;
table->lowerRehashThreshold = 0.0;
table->upperRehashThreshold = 15.0;
table->keycmp = pointercmp;
table->valuecmp = pointercmp;
table->hashFunction = pointerHashFunction;
table->keyDeallocator = NULL;
table->valueDeallocator = NULL;
table->hash = HashTable_PointerHash;
table->keyCompare = HashTable_PointerCompare;
table->valueCompare = HashTable_PointerCompare;
table->keyClone = NULL;
table->valueClone = NULL;
table->keyFree = NULL;
table->valueFree = NULL;
}
return table;
@ -576,11 +624,11 @@ void HashTable_Free(wHashTable* table)
{
nextPair = pair->next;
if (table->keyDeallocator)
table->keyDeallocator((void*) pair->key);
if (table->keyFree)
table->keyFree(pair->key);
if (table->valueDeallocator)
table->valueDeallocator(pair->value);
if (table->valueFree)
table->valueFree(pair->value);
free(pair);

View File

@ -43,6 +43,10 @@ int IniFile_Load_String(wIniFile* ini, const char* iniString)
return -1;
ini->buffer = (char*) malloc(fileSize + 2);
if (!ini->buffer)
return -1;
CopyMemory(ini->buffer, iniString, fileSize);
ini->buffer[fileSize] = '\n';
@ -53,25 +57,26 @@ int IniFile_Load_String(wIniFile* ini, const char* iniString)
return 1;
}
int IniFile_Load_File(wIniFile* ini, const char* filename)
int IniFile_Open_File(wIniFile* ini, const char* filename)
{
long int fileSize;
if (ini->readOnly)
{
ini->fp = fopen(filename, "r");
}
else
{
ini->fp = fopen(filename, "r+");
if (!ini->fp)
ini->fp = fopen(filename, "w+");
}
ini->fp = fopen(filename, "w+");
if (!ini->fp)
return -1;
return 1;
}
int IniFile_Load_File(wIniFile* ini, const char* filename)
{
int fileSize;
if (IniFile_Open_File(ini, filename) < 0)
return -1;
fseek(ini->fp, 0, SEEK_END);
fileSize = ftell(ini->fp);
fseek(ini->fp, 0, SEEK_SET);
@ -85,6 +90,9 @@ int IniFile_Load_File(wIniFile* ini, const char* filename)
ini->buffer = (char*) malloc(fileSize + 2);
if (!ini->buffer)
return -1;
if (fread(ini->buffer, fileSize, 1, ini->fp) != 1)
{
free(ini->buffer);
@ -92,6 +100,9 @@ int IniFile_Load_File(wIniFile* ini, const char* filename)
return -1;
}
fclose(ini->fp);
ini->fp = NULL;
ini->buffer[fileSize] = '\n';
ini->buffer[fileSize + 1] = '\0';
@ -147,11 +158,12 @@ wIniFileKey* IniFile_Key_New(const char* name, const char* value)
void IniFile_Key_Free(wIniFileKey* key)
{
if (key)
{
free(key->name);
free(key->value);
}
if (!key)
return;
free(key->name);
free(key->value);
free(key);
}
wIniFileSection* IniFile_Section_New(const char* name)
@ -169,41 +181,109 @@ wIniFileSection* IniFile_Section_New(const char* name)
void IniFile_Section_Free(wIniFileSection* section)
{
if (section)
{
free(section);
}
}
int index;
int IniFile_AddSection(wIniFile* ini, const char* name)
{
if ((ini->nSections + 1) >= (ini->cSections))
{
ini->cSections *= 2;
ini->sections = (wIniFileSection**) realloc(ini->sections, sizeof(wIniFileSection*) * ini->cSections);
}
ini->sections[ini->nSections] = IniFile_Section_New(name);
ini->nSections++;
return 1;
}
int IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* name, const char* value)
{
if (!section)
return -1;
if ((section->nKeys + 1) >= (section->cKeys))
return;
for (index = 0; index < section->nKeys; index++)
{
section->cKeys *= 2;
section->keys = (wIniFileKey**) realloc(section->keys, sizeof(wIniFileKey*) * section->cKeys);
IniFile_Key_Free(section->keys[index]);
}
section->keys[section->nKeys] = IniFile_Key_New(name, value);
section->nKeys++;
free(section);
}
return 1;
wIniFileSection* IniFile_GetSection(wIniFile* ini, const char* name)
{
int index;
wIniFileSection* section = NULL;
for (index = 0; index < ini->nSections; index++)
{
if (_stricmp(name, ini->sections[index]->name) == 0)
{
section = ini->sections[index];
break;
}
}
return section;
}
wIniFileSection* IniFile_AddSection(wIniFile* ini, const char* name)
{
wIniFileSection* section;
if (!name)
return NULL;
section = IniFile_GetSection(ini, name);
if (!section)
{
if ((ini->nSections + 1) >= (ini->cSections))
{
ini->cSections *= 2;
ini->sections = (wIniFileSection**) realloc(ini->sections, sizeof(wIniFileSection*) * ini->cSections);
}
section = IniFile_Section_New(name);
ini->sections[ini->nSections] = section;
ini->nSections++;
}
return section;
}
wIniFileKey* IniFile_GetKey(wIniFile* ini, wIniFileSection* section, const char* name)
{
int index;
wIniFileKey* key = NULL;
for (index = 0; index < section->nKeys; index++)
{
if (_stricmp(name, section->keys[index]->name) == 0)
{
key = section->keys[index];
break;
}
}
return key;
}
wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* name, const char* value)
{
wIniFileKey* key;
if (!section)
return NULL;
if (!name)
return NULL;
key = IniFile_GetKey(ini, section, name);
if (!key)
{
if ((section->nKeys + 1) >= (section->cKeys))
{
section->cKeys *= 2;
section->keys = (wIniFileKey**) realloc(section->keys, sizeof(wIniFileKey*) * section->cKeys);
}
key = IniFile_Key_New(name, value);
section->keys[section->nKeys] = key;
section->nKeys++;
}
else
{
free(key->value);
key->value = _strdup(value);
}
return key;
}
int IniFile_Load(wIniFile* ini)
@ -277,14 +357,14 @@ int IniFile_Load(wIniFile* ini)
return 1;
}
int IniFile_ParseString(wIniFile* ini, const char* iniString)
int IniFile_ReadBuffer(wIniFile* ini, const char* buffer)
{
int status;
ini->readOnly = TRUE;
ini->filename = NULL;
status = IniFile_Load_String(ini, iniString);
status = IniFile_Load_String(ini, buffer);
if (status < 0)
return status;
@ -294,14 +374,16 @@ int IniFile_ParseString(wIniFile* ini, const char* iniString)
return status;
}
int IniFile_Parse(wIniFile* ini, const char* filename)
int IniFile_ReadFile(wIniFile* ini, const char* filename)
{
int status;
ini->readOnly = TRUE;
free(ini->filename);
ini->filename = _strdup(filename);
status = IniFile_Load_File(ini, ini->filename);
status = IniFile_Load_File(ini, filename);
if (status < 0)
return status;
@ -311,40 +393,6 @@ int IniFile_Parse(wIniFile* ini, const char* filename)
return status;
}
wIniFileSection* IniFile_GetSection(wIniFile* ini, const char* name)
{
int index;
wIniFileSection* section = NULL;
for (index = 0; index < ini->nSections; index++)
{
if (_stricmp(name, ini->sections[index]->name) == 0)
{
section = ini->sections[index];
break;
}
}
return section;
}
wIniFileKey* IniFile_GetKey(wIniFile* ini, wIniFileSection* section, const char* name)
{
int index;
wIniFileKey* key = NULL;
for (index = 0; index < section->nKeys; index++)
{
if (_stricmp(name, section->keys[index]->name) == 0)
{
key = section->keys[index];
break;
}
}
return key;
}
char** IniFile_GetSectionNames(wIniFile* ini, int* count)
{
char* p;
@ -425,12 +473,12 @@ char** IniFile_GetSectionKeyNames(wIniFile* ini, const char* section, int* count
return keyNames;
}
char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const char* key)
const char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const char* key)
{
char* value = NULL;
const char* value = NULL;
wIniFileKey* pKey = NULL;
wIniFileSection* pSection = NULL;
pSection = IniFile_GetSection(ini, section);
if (!pSection)
@ -441,14 +489,14 @@ char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const char*
if (!pKey)
return NULL;
value = pKey->value;
value = (const char*) pKey->value;
return value;
}
UINT32 IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key)
int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key)
{
UINT32 value = 0;
int value = 0;
wIniFileKey* pKey = NULL;
wIniFileSection* pSection = NULL;
@ -467,6 +515,137 @@ UINT32 IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* ke
return value;
}
int IniFile_SetKeyValueString(wIniFile* ini, const char* section, const char* key, const char* value)
{
wIniFileKey* pKey = NULL;
wIniFileSection* pSection = NULL;
pSection = IniFile_GetSection(ini, section);
if (!pSection)
pSection = IniFile_AddSection(ini, section);
if (!pSection)
return -1;
pKey = IniFile_AddKey(ini, pSection, key, value);
if (!pKey)
return -1;
return 1;
}
int IniFile_SetKeyValueInt(wIniFile* ini, const char* section, const char* key, int value)
{
char strVal[128];
wIniFileKey* pKey = NULL;
wIniFileSection* pSection = NULL;
sprintf_s(strVal, sizeof(strVal), "%d", value);
pSection = IniFile_GetSection(ini, section);
if (!pSection)
pSection = IniFile_AddSection(ini, section);
if (!pSection)
return -1;
pKey = IniFile_AddKey(ini, pSection, key, strVal);
if (!pKey)
return -1;
return 1;
}
char* IniFile_WriteBuffer(wIniFile* ini)
{
int i, j;
int offset;
int size;
char* buffer;
wIniFileKey* key;
wIniFileSection* section;
size = 0;
for (i = 0; i < ini->nSections; i++)
{
section = ini->sections[i];
size += strlen(section->name) + 3;
for (j = 0; j < section->nKeys; j++)
{
key = section->keys[j];
size += strlen(key->name) + strlen(key->value) + 2;
}
size += 1;
}
size += 1;
buffer = malloc(size + 1);
if (!buffer)
return NULL;
offset = 0;
for (i = 0; i < ini->nSections; i++)
{
section = ini->sections[i];
sprintf_s(&buffer[offset], size - offset, "[%s]\n", section->name);
offset += strlen(section->name) + 3;
for (j = 0; j < section->nKeys; j++)
{
key = section->keys[j];
sprintf_s(&buffer[offset], size - offset, "%s=%s\n", key->name, key->value);
offset += strlen(key->name) + strlen(key->value) + 2;
}
sprintf_s(&buffer[offset], size - offset, "\n");
offset += 1;
}
buffer[offset] = '\0';
size += 1;
return buffer;
}
int IniFile_WriteFile(wIniFile* ini, const char* filename)
{
int length;
char* buffer;
buffer = IniFile_WriteBuffer(ini);
if (!buffer)
return -1;
length = strlen(buffer);
ini->readOnly = FALSE;
if (!filename)
filename = ini->filename;
if (IniFile_Open_File(ini, filename) < 0)
return -1;
fwrite((void*) buffer, length, 1, ini->fp);
fclose(ini->fp);
free(buffer);
return 1;
}
wIniFile* IniFile_New()
{
wIniFile* ini = (wIniFile*) calloc(1, sizeof(wIniFile));
@ -483,10 +662,19 @@ wIniFile* IniFile_New()
void IniFile_Free(wIniFile* ini)
{
if (ini)
{
free(ini->filename);
int index;
free(ini);
if (!ini)
return;
free(ini->filename);
for (index = 0; index < ini->nSections; index++)
{
IniFile_Section_Free(ini->sections[index]);
}
free(ini->sections);
free(ini);
}

View File

@ -11,7 +11,7 @@ static char* val1 = "val1";
static char* val2 = "val2";
static char* val3 = "val3";
int TestHashTable(int argc, char* argv[])
int test_hash_table_pointer()
{
int count;
char* value;
@ -137,5 +137,153 @@ int TestHashTable(int argc, char* argv[])
HashTable_Free(table);
return 1;
}
int test_hash_table_string()
{
int count;
char* value;
wHashTable* table;
table = HashTable_New(TRUE);
table->hash = HashTable_StringHash;
table->keyCompare = HashTable_StringCompare;
table->valueCompare = HashTable_StringCompare;
table->keyClone = HashTable_StringClone;
table->valueClone = HashTable_StringClone;
table->keyFree = HashTable_StringFree;
table->valueFree = HashTable_StringFree;
HashTable_Add(table, key1, val1);
HashTable_Add(table, key2, val2);
HashTable_Add(table, key3, val3);
count = HashTable_Count(table);
if (count != 3)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 3, count);
return -1;
}
HashTable_Remove(table, key2);
count = HashTable_Count(table);
if (count != 2)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 2, count);
return -1;
}
HashTable_Remove(table, key3);
count = HashTable_Count(table);
if (count != 1)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 1, count);
return -1;
}
HashTable_Remove(table, key1);
count = HashTable_Count(table);
if (count != 0)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 0, count);
return -1;
}
HashTable_Add(table, key1, val1);
HashTable_Add(table, key2, val2);
HashTable_Add(table, key3, val3);
count = HashTable_Count(table);
if (count != 3)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 3, count);
return -1;
}
value = (char*) HashTable_GetItemValue(table, key1);
if (strcmp(value, val1) != 0)
{
printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value);
return -1;
}
value = (char*) HashTable_GetItemValue(table, key2);
if (strcmp(value, val2) != 0)
{
printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value);
return -1;
}
value = (char*) HashTable_GetItemValue(table, key3);
if (strcmp(value, val3) != 0)
{
printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value);
return -1;
}
HashTable_SetItemValue(table, key2, "apple");
value = (char*) HashTable_GetItemValue(table, key2);
if (strcmp(value, "apple") != 0)
{
printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value);
return -1;
}
if (!HashTable_Contains(table, key2))
{
printf("HashTable_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE);
return -1;
}
if (!HashTable_Remove(table, key2))
{
printf("HashTable_Remove: Expected : %d, Actual: %d\n", TRUE, FALSE);
return -1;
}
if (HashTable_Remove(table, key2))
{
printf("HashTable_Remove: Expected : %d, Actual: %d\n", FALSE, TRUE);
return -1;
}
HashTable_Clear(table);
count = HashTable_Count(table);
if (count != 0)
{
printf("HashTable_Count: Expected : %d, Actual: %d\n", 0, count);
return -1;
}
HashTable_Free(table);
return 1;
}
int TestHashTable(int argc, char* argv[])
{
if (test_hash_table_pointer() < 0)
return 1;
if (test_hash_table_string() < 0)
return 1;
return 0;
}

View File

@ -32,9 +32,9 @@ int TestIni(int argc, char* argv[])
int i, j;
int nKeys;
int nSections;
char* sValue;
UINT32 iValue;
wIniFile* ini;
const char* sValue;
char** keyNames;
char** sectionNames;
@ -42,7 +42,7 @@ int TestIni(int argc, char* argv[])
ini = IniFile_New();
IniFile_ParseString(ini, TEST_INI_01);
IniFile_ReadBuffer(ini, TEST_INI_01);
sectionNames = IniFile_GetSectionNames(ini, &nSections);
@ -109,7 +109,7 @@ int TestIni(int argc, char* argv[])
ini = IniFile_New();
IniFile_ParseString(ini, TEST_INI_02);
IniFile_ReadBuffer(ini, TEST_INI_02);
sectionNames = IniFile_GetSectionNames(ini, &nSections);

View File

@ -482,6 +482,9 @@ int _bind(SOCKET s, const struct sockaddr* addr, int namelen)
status = bind(fd, addr, (socklen_t) namelen);
if (status < 0)
return SOCKET_ERROR;
return status;
}
@ -502,6 +505,9 @@ int _connect(SOCKET s, const struct sockaddr* name, int namelen)
status = connect(fd, name, (socklen_t) namelen);
if (status < 0)
return SOCKET_ERROR;
return status;
}
@ -684,9 +690,15 @@ int _shutdown(SOCKET s, int how)
SOCKET _socket(int af, int type, int protocol)
{
int fd;
SOCKET s;
s = (SOCKET) socket(af, type, protocol);
fd = socket(af, type, protocol);
if (fd < 1)
return INVALID_SOCKET;
s = (SOCKET) fd;
return s;
}

View File

@ -18,6 +18,10 @@
winpr_module_add(wtsapi.c
wtsapi.h)
if(WIN32)
winpr_module_add(wtsapi_win32.c wtsapi_win32.h)
endif()
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -32,6 +32,10 @@
#include "wtsapi.h"
#ifdef _WIN32
#include "wtsapi_win32.h"
#endif
#include "../log.h"
#define TAG WINPR_TAG("wtsapi")
@ -193,8 +197,10 @@ int WtsApi32_InitializeWtsApi(void)
WTSAPI32_LOAD_PROC(IsChildSessionsEnabled, WTS_IS_CHILD_SESSIONS_ENABLED_FN);
WTSAPI32_LOAD_PROC(GetChildSessionId, WTS_GET_CHILD_SESSION_ID_FN);
WTSAPI32_LOAD_PROC(GetActiveConsoleSessionId, WTS_GET_ACTIVE_CONSOLE_SESSION_ID_FN);
#endif
g_WtsApi = &WtsApi32_WtsApiFunctionTable;
Win32_InitializeWinSta(g_WtsApi);
#endif
return 1;
}
@ -599,16 +605,16 @@ void InitializeWtsApiStubs_Env()
void InitializeWtsApiStubs_FreeRDS()
{
char* prefix;
char* libdir;
wIniFile* ini;
const char* prefix;
const char* libdir;
if (g_WtsApi)
return;
ini = IniFile_New();
if (IniFile_Parse(ini, "/var/run/freerds.instance") < 0)
if (IniFile_ReadFile(ini, "/var/run/freerds.instance") < 0)
{
IniFile_Free(ini);
WLog_ERR(TAG, "failed to parse freerds.instance");
@ -646,6 +652,7 @@ void InitializeWtsApiStubs(void)
g_Initialized = TRUE;
InitializeWtsApiStubs_Env();
#ifdef _WIN32
WtsApi32_InitializeWtsApi();
#endif

View File

@ -0,0 +1,731 @@
/**
* WinPR: Windows Portable Runtime
* Windows Terminal Services API
*
* Copyright 2013-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/io.h>
#include <winpr/nt.h>
#include <winpr/library.h>
#include <winpr/wtsapi.h>
#include "wtsapi_win32.h"
#include "wtsapi.h"
#define WTSAPI_CHANNEL_MAGIC 0x44484356
struct _WTSAPI_CHANNEL
{
UINT32 magic;
HANDLE hServer;
DWORD SessionId;
HANDLE hFile;
HANDLE hEvent;
char* VirtualName;
DWORD flags;
BYTE* chunk;
BOOL dynamic;
BOOL readSync;
BOOL readAsync;
BOOL readDone;
UINT32 readSize;
UINT32 readOffset;
BYTE* readBuffer;
BOOL showProtocol;
BOOL waitObjectMode;
OVERLAPPED overlapped;
CHANNEL_PDU_HEADER* header;
};
typedef struct _WTSAPI_CHANNEL WTSAPI_CHANNEL;
static BOOL g_Initialized = FALSE;
static HMODULE g_WinStaModule = NULL;
typedef HANDLE (WINAPI * fnWinStationVirtualOpen)(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName);
typedef HANDLE (WINAPI * fnWinStationVirtualOpenEx)(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName, DWORD flags);
static fnWinStationVirtualOpen pfnWinStationVirtualOpen = NULL;
static fnWinStationVirtualOpenEx pfnWinStationVirtualOpenEx = NULL;
BOOL WINAPI Win32_WTSVirtualChannelClose(HANDLE hChannel);
BOOL Win32_WTSVirtualChannelReadAsync(WTSAPI_CHANNEL* pChannel)
{
BOOL status = TRUE;
DWORD numBytes = 0;
if (pChannel->readAsync)
return TRUE;
ZeroMemory(&(pChannel->overlapped), sizeof(OVERLAPPED));
pChannel->overlapped.hEvent = pChannel->hEvent;
ResetEvent(pChannel->hEvent);
if (pChannel->showProtocol)
{
ZeroMemory(pChannel->header, sizeof(CHANNEL_PDU_HEADER));
status = ReadFile(pChannel->hFile, pChannel->header,
sizeof(CHANNEL_PDU_HEADER), &numBytes, &(pChannel->overlapped));
}
else
{
status = ReadFile(pChannel->hFile, pChannel->chunk,
CHANNEL_CHUNK_LENGTH, &numBytes, &(pChannel->overlapped));
if (status)
{
pChannel->readOffset = 0;
pChannel->header->length = numBytes;
pChannel->readDone = TRUE;
SetEvent(pChannel->hEvent);
return TRUE;
}
}
if (status)
{
fprintf(stderr, "Unexpected ReadFile status: %d numBytes: %d\n", status, numBytes);
return FALSE; /* ReadFile should return FALSE and set ERROR_IO_PENDING */
}
if (GetLastError() != ERROR_IO_PENDING)
{
fprintf(stderr, "ReadFile: GetLastError() = %d\n", GetLastError());
return FALSE;
}
pChannel->readAsync = TRUE;
return TRUE;
}
HANDLE WINAPI Win32_WTSVirtualChannelOpen_Internal(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName, DWORD flags)
{
HANDLE hFile;
HANDLE hChannel;
WTSAPI_CHANNEL* pChannel;
if (!pVirtualName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
hFile = pfnWinStationVirtualOpenEx(hServer, SessionId, pVirtualName, flags);
if (!hFile)
return NULL;
pChannel = (WTSAPI_CHANNEL*) calloc(1, sizeof(WTSAPI_CHANNEL));
if (!pChannel)
{
CloseHandle(hFile);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
hChannel = (HANDLE) pChannel;
pChannel->magic = WTSAPI_CHANNEL_MAGIC;
pChannel->hServer = hServer;
pChannel->SessionId = SessionId;
pChannel->hFile = hFile;
pChannel->VirtualName = _strdup(pVirtualName);
pChannel->flags = flags;
pChannel->dynamic = (flags & WTS_CHANNEL_OPTION_DYNAMIC) ? TRUE : FALSE;
pChannel->showProtocol = pChannel->dynamic;
pChannel->readSize = CHANNEL_PDU_LENGTH;
pChannel->readBuffer = (BYTE*) malloc(pChannel->readSize);
pChannel->header = (CHANNEL_PDU_HEADER*) pChannel->readBuffer;
pChannel->chunk = &(pChannel->readBuffer[sizeof(CHANNEL_PDU_HEADER)]);
pChannel->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
pChannel->overlapped.hEvent = pChannel->hEvent;
if (!pChannel->hEvent || !pChannel->VirtualName || !pChannel->readBuffer)
{
Win32_WTSVirtualChannelClose(hChannel);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
return hChannel;
}
HANDLE WINAPI Win32_WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName)
{
return Win32_WTSVirtualChannelOpen_Internal(hServer, SessionId, pVirtualName, 0);
}
HANDLE WINAPI Win32_WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags)
{
return Win32_WTSVirtualChannelOpen_Internal(0, SessionId, pVirtualName, flags);
}
BOOL WINAPI Win32_WTSVirtualChannelClose(HANDLE hChannel)
{
BOOL status = TRUE;
WTSAPI_CHANNEL* pChannel = (WTSAPI_CHANNEL*) hChannel;
if (!pChannel || (pChannel->magic != WTSAPI_CHANNEL_MAGIC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (pChannel->hFile)
{
if (pChannel->readAsync)
{
CancelIo(pChannel->hFile);
pChannel->readAsync = FALSE;
}
status = CloseHandle(pChannel->hFile);
pChannel->hFile = NULL;
}
if (pChannel->hEvent)
{
CloseHandle(pChannel->hEvent);
pChannel->hEvent = NULL;
}
if (pChannel->VirtualName)
{
free(pChannel->VirtualName);
pChannel->VirtualName = NULL;
}
if (pChannel->readBuffer)
{
free(pChannel->readBuffer);
pChannel->readBuffer = NULL;
}
pChannel->magic = 0;
free(pChannel);
return status;
}
BOOL WINAPI Win32_WTSVirtualChannelRead_Static(WTSAPI_CHANNEL* pChannel, DWORD dwMilliseconds, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesTransferred)
{
if (pChannel->readDone)
{
DWORD numBytesRead = 0;
DWORD numBytesToRead = 0;
*lpNumberOfBytesTransferred = 0;
numBytesToRead = nNumberOfBytesToRead;
if (numBytesToRead > (pChannel->header->length - pChannel->readOffset))
numBytesToRead = (pChannel->header->length - pChannel->readOffset);
CopyMemory(lpBuffer, &(pChannel->chunk[pChannel->readOffset]), numBytesToRead);
*lpNumberOfBytesTransferred += numBytesToRead;
pChannel->readOffset += numBytesToRead;
if (pChannel->readOffset != pChannel->header->length)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
else
{
pChannel->readDone = FALSE;
Win32_WTSVirtualChannelReadAsync(pChannel);
}
return TRUE;
}
else if (pChannel->readSync)
{
BOOL bSuccess;
OVERLAPPED overlapped;
DWORD numBytesRead = 0;
DWORD numBytesToRead = 0;
*lpNumberOfBytesTransferred = 0;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
numBytesToRead = nNumberOfBytesToRead;
if (numBytesToRead > (pChannel->header->length - pChannel->readOffset))
numBytesToRead = (pChannel->header->length - pChannel->readOffset);
if (ReadFile(pChannel->hFile, lpBuffer, numBytesToRead, &numBytesRead, &overlapped))
{
*lpNumberOfBytesTransferred += numBytesRead;
pChannel->readOffset += numBytesRead;
if (pChannel->readOffset != pChannel->header->length)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
pChannel->readSync = FALSE;
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
if (GetLastError() != ERROR_IO_PENDING)
return FALSE;
bSuccess = GetOverlappedResult(pChannel->hFile, &overlapped, &numBytesRead, TRUE);
if (!bSuccess)
return FALSE;
*lpNumberOfBytesTransferred += numBytesRead;
pChannel->readOffset += numBytesRead;
if (pChannel->readOffset != pChannel->header->length)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
pChannel->readSync = FALSE;
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
else if (pChannel->readAsync)
{
BOOL bSuccess;
DWORD numBytesRead = 0;
DWORD numBytesToRead = 0;
*lpNumberOfBytesTransferred = 0;
if (WaitForSingleObject(pChannel->hEvent, dwMilliseconds) != WAIT_TIMEOUT)
{
bSuccess = GetOverlappedResult(pChannel->hFile,
&(pChannel->overlapped), &numBytesRead, TRUE);
pChannel->readOffset = 0;
pChannel->header->length = numBytesRead;
if (!bSuccess && (GetLastError() != ERROR_MORE_DATA))
return FALSE;
numBytesToRead = nNumberOfBytesToRead;
if (numBytesRead < numBytesToRead)
{
numBytesToRead = numBytesRead;
nNumberOfBytesToRead = numBytesRead;
}
CopyMemory(lpBuffer, pChannel->chunk, numBytesToRead);
*lpNumberOfBytesTransferred += numBytesToRead;
((BYTE*) lpBuffer) += numBytesToRead;
nNumberOfBytesToRead -= numBytesToRead;
pChannel->readOffset += numBytesToRead;
pChannel->readAsync = FALSE;
if (!nNumberOfBytesToRead)
{
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
pChannel->readSync = TRUE;
numBytesRead = 0;
bSuccess = Win32_WTSVirtualChannelRead_Static(pChannel, dwMilliseconds,
lpBuffer, nNumberOfBytesToRead, &numBytesRead);
*lpNumberOfBytesTransferred += numBytesRead;
return bSuccess;
}
else
{
SetLastError(ERROR_IO_INCOMPLETE);
return FALSE;
}
}
return FALSE;
}
BOOL WINAPI Win32_WTSVirtualChannelRead_Dynamic(WTSAPI_CHANNEL* pChannel, DWORD dwMilliseconds, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesTransferred)
{
if (pChannel->readSync)
{
BOOL bSuccess;
OVERLAPPED overlapped;
DWORD numBytesRead = 0;
DWORD numBytesToRead = 0;
*lpNumberOfBytesTransferred = 0;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
numBytesToRead = nNumberOfBytesToRead;
if (numBytesToRead > (pChannel->header->length - pChannel->readOffset))
numBytesToRead = (pChannel->header->length - pChannel->readOffset);
if (ReadFile(pChannel->hFile, lpBuffer, numBytesToRead, &numBytesRead, &overlapped))
{
*lpNumberOfBytesTransferred += numBytesRead;
pChannel->readOffset += numBytesRead;
if (pChannel->readOffset != pChannel->header->length)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
pChannel->readSync = FALSE;
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
if (GetLastError() != ERROR_IO_PENDING)
return FALSE;
bSuccess = GetOverlappedResult(pChannel->hFile, &overlapped, &numBytesRead, TRUE);
if (!bSuccess)
return FALSE;
*lpNumberOfBytesTransferred += numBytesRead;
pChannel->readOffset += numBytesRead;
if (pChannel->readOffset != pChannel->header->length)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
pChannel->readSync = FALSE;
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
else if (pChannel->readAsync)
{
BOOL bSuccess;
DWORD numBytesRead = 0;
*lpNumberOfBytesTransferred = 0;
if (WaitForSingleObject(pChannel->hEvent, dwMilliseconds) != WAIT_TIMEOUT)
{
bSuccess = GetOverlappedResult(pChannel->hFile,
&(pChannel->overlapped), &numBytesRead, TRUE);
if (pChannel->showProtocol)
{
if (numBytesRead != sizeof(CHANNEL_PDU_HEADER))
return FALSE;
if (!bSuccess && (GetLastError() != ERROR_MORE_DATA))
return FALSE;
CopyMemory(lpBuffer, pChannel->header, numBytesRead);
*lpNumberOfBytesTransferred += numBytesRead;
((BYTE*) lpBuffer) += numBytesRead;
nNumberOfBytesToRead -= numBytesRead;
}
pChannel->readAsync = FALSE;
if (!pChannel->header->length)
{
Win32_WTSVirtualChannelReadAsync(pChannel);
return TRUE;
}
pChannel->readSync = TRUE;
pChannel->readOffset = 0;
if (!nNumberOfBytesToRead)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
numBytesRead = 0;
bSuccess = Win32_WTSVirtualChannelRead_Dynamic(pChannel, dwMilliseconds,
lpBuffer, nNumberOfBytesToRead, &numBytesRead);
*lpNumberOfBytesTransferred += numBytesRead;
return bSuccess;
}
else
{
SetLastError(ERROR_IO_INCOMPLETE);
return FALSE;
}
}
return FALSE;
}
BOOL WINAPI Win32_WTSVirtualChannelRead(HANDLE hChannel, DWORD dwMilliseconds, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesTransferred)
{
WTSAPI_CHANNEL* pChannel = (WTSAPI_CHANNEL*) hChannel;
if (!pChannel || (pChannel->magic != WTSAPI_CHANNEL_MAGIC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!pChannel->waitObjectMode)
{
OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
if (ReadFile(pChannel->hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesTransferred, &overlapped))
return TRUE;
if (GetLastError() != ERROR_IO_PENDING)
return FALSE;
if (!dwMilliseconds)
{
CancelIo(pChannel->hFile);
*lpNumberOfBytesTransferred = 0;
return TRUE;
}
if (WaitForSingleObject(pChannel->hFile, dwMilliseconds) != WAIT_TIMEOUT)
return GetOverlappedResult(pChannel->hFile, &overlapped, lpNumberOfBytesTransferred, FALSE);
CancelIo(pChannel->hFile);
SetLastError(ERROR_IO_INCOMPLETE);
return FALSE;
}
else
{
if (pChannel->dynamic)
{
return Win32_WTSVirtualChannelRead_Dynamic(pChannel, dwMilliseconds,
lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesTransferred);
}
else
{
return Win32_WTSVirtualChannelRead_Static(pChannel, dwMilliseconds,
lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesTransferred);
}
}
return FALSE;
}
BOOL WINAPI Win32_WTSVirtualChannelWrite(HANDLE hChannel, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesTransferred)
{
OVERLAPPED overlapped;
WTSAPI_CHANNEL* pChannel = (WTSAPI_CHANNEL*) hChannel;
if (!pChannel || (pChannel->magic != WTSAPI_CHANNEL_MAGIC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
if (WriteFile(pChannel->hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesTransferred, &overlapped))
return TRUE;
if (GetLastError() == ERROR_IO_PENDING)
return GetOverlappedResult(pChannel->hFile, &overlapped, lpNumberOfBytesTransferred, TRUE);
return FALSE;
}
#ifndef FILE_DEVICE_TERMSRV
#define FILE_DEVICE_TERMSRV 0x00000038
#endif
BOOL Win32_WTSVirtualChannelPurge_Internal(HANDLE hChannelHandle, ULONG IoControlCode)
{
DWORD error;
NTSTATUS ntstatus;
IO_STATUS_BLOCK ioStatusBlock;
WTSAPI_CHANNEL* pChannel = (WTSAPI_CHANNEL*) hChannelHandle;
if (!pChannel || (pChannel->magic != WTSAPI_CHANNEL_MAGIC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ntstatus = _NtDeviceIoControlFile(pChannel->hFile, 0, 0, 0, &ioStatusBlock, IoControlCode, 0, 0, 0, 0);
if (ntstatus == STATUS_PENDING)
{
ntstatus = _NtWaitForSingleObject(pChannel->hFile, 0, 0);
if (ntstatus >= 0)
ntstatus = ioStatusBlock.Status;
}
if (ntstatus == STATUS_BUFFER_OVERFLOW)
{
ntstatus = STATUS_BUFFER_TOO_SMALL;
error = _RtlNtStatusToDosError(ntstatus);
SetLastError(error);
return FALSE;
}
if (ntstatus < 0)
{
error = _RtlNtStatusToDosError(ntstatus);
SetLastError(error);
return FALSE;
}
return TRUE;
}
BOOL WINAPI Win32_WTSVirtualChannelPurgeInput(HANDLE hChannelHandle)
{
return Win32_WTSVirtualChannelPurge_Internal(hChannelHandle, (FILE_DEVICE_TERMSRV << 16) | 0x0107);
}
BOOL WINAPI Win32_WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle)
{
return Win32_WTSVirtualChannelPurge_Internal(hChannelHandle, (FILE_DEVICE_TERMSRV << 16) | 0x010B);
}
BOOL WINAPI Win32_WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned)
{
WTSAPI_CHANNEL* pChannel = (WTSAPI_CHANNEL*) hChannelHandle;
if (!pChannel || (pChannel->magic != WTSAPI_CHANNEL_MAGIC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (WtsVirtualClass == WTSVirtualClientData)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
else if (WtsVirtualClass == WTSVirtualFileHandle)
{
*pBytesReturned = sizeof(HANDLE);
*ppBuffer = LocalAlloc(LMEM_ZEROINIT, *pBytesReturned);
if (*ppBuffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
CopyMemory(*ppBuffer, &(pChannel->hFile), *pBytesReturned);
}
else if (WtsVirtualClass == WTSVirtualEventHandle)
{
*pBytesReturned = sizeof(HANDLE);
*ppBuffer = LocalAlloc(LMEM_ZEROINIT, *pBytesReturned);
if (*ppBuffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
CopyMemory(*ppBuffer, &(pChannel->hEvent), *pBytesReturned);
Win32_WTSVirtualChannelReadAsync(pChannel);
pChannel->waitObjectMode = TRUE;
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
VOID WINAPI Win32_WTSFreeMemory(PVOID pMemory)
{
LocalFree(pMemory);
return TRUE;
}
BOOL WINAPI Win32_WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
{
return TRUE;
}
BOOL WINAPI Win32_WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries)
{
return WTSFreeMemoryExW(WTSTypeClass, pMemory, NumberOfEntries);
}
int Win32_InitializeWinSta(PWtsApiFunctionTable pWtsApi)
{
g_WinStaModule = LoadLibraryA("winsta.dll");
if (!g_WinStaModule)
return -1;
pfnWinStationVirtualOpen = (fnWinStationVirtualOpen) GetProcAddress(g_WinStaModule, "WinStationVirtualOpen");
pfnWinStationVirtualOpenEx = (fnWinStationVirtualOpenEx) GetProcAddress(g_WinStaModule, "WinStationVirtualOpenEx");
if (!pfnWinStationVirtualOpenEx)
return -1;
pWtsApi->pVirtualChannelOpen = Win32_WTSVirtualChannelOpen;
pWtsApi->pVirtualChannelOpenEx = Win32_WTSVirtualChannelOpenEx;
pWtsApi->pVirtualChannelClose = Win32_WTSVirtualChannelClose;
pWtsApi->pVirtualChannelRead = Win32_WTSVirtualChannelRead;
pWtsApi->pVirtualChannelWrite = Win32_WTSVirtualChannelWrite;
pWtsApi->pVirtualChannelPurgeInput = Win32_WTSVirtualChannelPurgeInput;
pWtsApi->pVirtualChannelPurgeOutput = Win32_WTSVirtualChannelPurgeOutput;
pWtsApi->pVirtualChannelQuery = Win32_WTSVirtualChannelQuery;
pWtsApi->pFreeMemory = Win32_WTSFreeMemory;
//pWtsApi->pFreeMemoryExW = Win32_WTSFreeMemoryExW;
//pWtsApi->pFreeMemoryExA = Win32_WTSFreeMemoryExA;
return 1;
}

View File

@ -0,0 +1,27 @@
/**
* WinPR: Windows Portable Runtime
* Windows Terminal Services API
*
* Copyright 2013-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_WTSAPI_WIN32_PRIVATE_H
#define WINPR_WTSAPI_WIN32_PRIVATE_H
#include <winpr/wtsapi.h>
int Win32_InitializeWinSta(PWtsApiFunctionTable pWtsApi);
#endif /* WINPR_WTSAPI_WIN32_PRIVATE_H */