freerdp: merge with master

This commit is contained in:
Marc-André Moreau 2013-06-28 12:50:24 -04:00
commit 863b51f938
39 changed files with 351 additions and 161 deletions

View File

@ -329,8 +329,9 @@ if(APPLE)
set(DIRECTFB_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
set(GSTREAMER_FEATURE_TYPE "OPTIONAL")
set(X11_FEATURE_TYPE "DISABLED")
set(X11_FEATURE_TYPE "OPTIONAL")
if(IOS)
set(X11_FEATURE_TYPE "DISABLED")
set(ALSA_FEATURE_TYPE "DISABLED")
set(PULSE_FEATURE_TYPE "DISABLED")
set(CUPS_FEATURE_TYPE "DISABLED")
@ -353,6 +354,11 @@ endif()
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
if (${WITH_DIRECTFB})
message(WARNING "
DIRECTFB is orphaned and not maintained see docs/README.directfb for details
")
endif()
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION})

View File

@ -376,16 +376,13 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
{
DEBUG_WARN("channel rejected by plugin");
channel->status = 1;
ArrayList_Add(dvcman->channels, channel);
free(channel);
return 1;
}
}
}
channel->status = 1;
ArrayList_Add(dvcman->channels, channel);
free(channel);
return 1;
}

View File

@ -40,7 +40,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-interlocked)
MODULES winpr-crt winpr-synch winpr-interlocked winpr-error)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)

View File

@ -669,7 +669,6 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder * decoder, TS_AM_MEDIA_TYPE *
return FALSE;
}
return TRUE;
}
@ -1133,12 +1132,12 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
{
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
start_time, end_time, duration, mdecoder->last_sample_end_time);
}
else
{
DEBUG_DVC("tsmf_gstreamer_decodeEX_AUDIO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
DEBUG_DVC("tsmf_gstreamer_decodeEx_AUDIO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
start_time, end_time, duration, mdecoder->last_sample_end_time);
}
@ -1176,7 +1175,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
*/
if (start_time > (mdecoder->last_sample_end_time + 10000000) || (end_time + 10000000) < mdecoder->last_sample_end_time)
{
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%llu] > last_sample_end_time=[%llu]", start_time, mdecoder->last_sample_end_time);
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_end_time=[%"PRIu64"]", start_time, mdecoder->last_sample_end_time);
DEBUG_DVC("tsmf_gstreamer_decodeEx: Stream seek detected - flushing element.");
tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL);
gst_object_unref(mdecoder->pipe);
@ -1205,7 +1204,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
if (fout)
{
fprintf(fout, "%"PRIu64"\n", (long unsigned int) start_time);
fprintf(fout, "%"PRIu64"\n", start_time);
fclose(fout);
}
@ -1231,7 +1230,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
if (fin)
{
UINT64 AStartTime = 0;
fscanf(fin, "%"PRIu64, (long unsigned int*) &AStartTime);
fscanf(fin, "%"PRIu64, &AStartTime);
fclose(fin);
if (start_time > AStartTime)
{
@ -1265,7 +1264,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
if (fin)
{
UINT64 VStartTime = 0;
fscanf(fin, "%"PRIu64, (long unsigned int*) &VStartTime);
fscanf(fin, "%"PRIu64, &VStartTime);
fclose(fin);
if (start_time > VStartTime)
{
@ -1283,7 +1282,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
pthread_mutex_unlock(&mdecoder->gst_mutex);
DEBUG_WARN("tsmf_gstreamer_decodeEx: gst_buffer_try_new_and_alloc(%d) failed.", data_size);
return FALSE;
}
}
gst_buffer_set_caps(gst_buf, mdecoder->gst_caps);
memcpy(GST_BUFFER_MALLOCDATA(gst_buf), data, data_size);
GST_BUFFER_TIMESTAMP(gst_buf) = tsmf_gstreamer_timestamp_ms_to_gst(start_time);
@ -1325,20 +1324,21 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder * decoder, UINT32 newVolum
if (mdecoder->shutdown)
return;
if (!mdecoder->aVolume)
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
return;
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
mdecoder->gstMuted = (BOOL) muted;
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
mdecoder->gstVolume = (double) newVolume / (double) 10000;
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
if (!mdecoder->aVolume)
return;
if (!G_IS_OBJECT(mdecoder->aVolume))
return;
mdecoder->gstMuted = (BOOL) muted;
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
g_object_set(mdecoder->aVolume, "mute", mdecoder->gstMuted, NULL);
mdecoder->gstVolume = (double) newVolume / (double) 10000;
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
g_object_set(mdecoder->aVolume, "volume", mdecoder->gstVolume, NULL);
}
@ -1482,7 +1482,7 @@ static UINT64 tsmf_gstreamer_get_running_time(ITSMFDecoder * decoder)
GstFormat fmt = GST_FORMAT_TIME;
gint64 pos = 0;
gst_element_query_position (mdecoder->outsink, &fmt, &pos);
DEBUG_DVC("tsmf_gstreamer_current_pos=[%llu]", pos);
DEBUG_DVC("tsmf_gstreamer_current_pos=[%"PRIu64"]", pos);
return pos/100;
}
@ -1524,13 +1524,14 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
{
if (info->noutput > 0)
{
if (info->outputs[0] == primary_output)
if (info->outputs[0] == primary_output || i == 0)
{
mdecoder->xOffset = info->x;
mdecoder->yOffset = info->y;
}
DEBUG_DVC("output %d ID: %lu (x,y): (%d,%d) (w,h): (%d,%d) primary: %d", i, info->outputs[0], info->x, info->y, info->width, info->height, (info->outputs[0] == primary_output));
}
XRRFreeCrtcInfo(info);
}
}
}
@ -1545,7 +1546,12 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
if(mdecoder->subwin)
{
XMoveWindow(mdecoder->disp, mdecoder->subwin, anewX, anewY);
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
if(newWidth > 0 && newHeight > 0) {
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
} else {
XResizeWindow(mdecoder->disp, mdecoder->subwin, 1, 1);
}
XSync(mdecoder->disp, FALSE);
XShapeCombineRectangles (mdecoder->disp, mdecoder->subwin, ShapeBounding, 0, 0,(XRectangle*) rectangles, numRectangles, ShapeSet, Unsorted);
XSync(mdecoder->disp, FALSE);
@ -1599,7 +1605,7 @@ ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
decoder->xOffset = 0;
decoder->yOffset = 0;
decoder->offsetObtained = FALSE;
decoder->gstVolume = 1.0;
decoder->gstVolume = 0.5;
decoder->gstMuted = FALSE;
decoder->state = GST_STATE_VOID_PENDING; /* No real state yet */
pthread_mutex_init(&decoder->gst_mutex, NULL);

View File

@ -127,8 +127,6 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
return 0;
}
static TSMF_PRESENTATION* pexisted = 0;
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
{
int status = 0;
@ -136,15 +134,16 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
DEBUG_DVC("");
if (pexisted)
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (presentation)
{
DEBUG_DVC("Presentation already exists");
ifman->output_pending = FALSE;
return 0;
}
presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
pexisted = presentation;
if (presentation == NULL)
status = 1;
@ -283,8 +282,8 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
if (presentation)
tsmf_presentation_free(presentation);
pexisted = 0;
else
DEBUG_WARN("unknown presentation id");
Stream_EnsureRemainingCapacity(ifman->output, 4);
Stream_Write_UINT32(ifman->output, 0); /* Result */

View File

@ -84,6 +84,9 @@ struct _TSMF_PRESENTATION
UINT64 audio_start_time;
UINT64 audio_end_time;
UINT32 volume;
UINT32 muted;
HANDLE mutex;
HANDLE thread;
@ -282,6 +285,9 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
memcpy(presentation->presentation_id, guid, GUID_SIZE);
presentation->channel_callback = pChannelCallback;
presentation->volume = 5000; /* 50% */
presentation->muted = 0;
presentation->mutex = CreateMutex(NULL, FALSE, NULL);
presentation->stream_list = list_new();
@ -786,6 +792,9 @@ void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 ne
LIST_ITEM* item;
TSMF_STREAM* stream;
presentation->volume = newVolume;
presentation->muted = muted;
for (item = presentation->stream_list->head; item; item = item->next)
{
stream = (TSMF_STREAM*) item->data;
@ -964,7 +973,10 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
stream->sample_list = Queue_New(TRUE, -1, -1);
stream->sample_list->object.fnObjectFree = free;
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
stream->sample_ack_list->object.fnObjectFree = free;
WaitForSingleObject(presentation->mutex, INFINITE);
list_enqueue(presentation->stream_list, stream);
@ -1026,6 +1038,7 @@ void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s)
stream->width = mediatype.Width;
stream->height = mediatype.Height;
stream->decoder = tsmf_load_decoder(name, &mediatype);
tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted);
}
void tsmf_stream_end(TSMF_STREAM* stream)

View File

@ -248,6 +248,9 @@ public class SessionActivity extends Activity
{
Log.v(TAG, "OnConnectionFailure");
// remove pending move events
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
if(progressDialog != null)
{
progressDialog.dismiss();
@ -264,7 +267,10 @@ public class SessionActivity extends Activity
private void OnDisconnected(Context context)
{
Log.v(TAG, "OnDisconnected");
// remove pending move events
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
if(progressDialog != null)
{
progressDialog.dismiss();
@ -434,6 +440,7 @@ public class SessionActivity extends Activity
keyboardMapper = new KeyboardMapper();
keyboardMapper.init(this);
keyboardMapper.reset(this);
modifiersKeyboard = new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
specialkeysKeyboard = new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);

View File

@ -65,7 +65,9 @@ public abstract class ClipboardManagerProxy {
String data = null;
if (clip != null && clip.getItemCount() > 0) {
data = clip.getItemAt(0).getText().toString();
CharSequence cs = clip.getItemAt(0).getText();
if (cs != null)
data = cs.toString();
}
if (mListener != null) {
mListener.onClipboardChanged(data);

View File

@ -131,7 +131,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
RFX_MESSAGE* msg;
xfContext* xfc = (xfContext*) context;
size = width * height * (bpp + 7) / 8;
size = width * height * ((bpp + 7) / 8);
if (bitmap->data == NULL)
bitmap->data = (BYTE*) malloc(size);

View File

@ -134,6 +134,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "wm-class", COMMAND_LINE_VALUE_REQUIRED, "<class name>", NULL, NULL, -1, NULL, "set the WM_CLASS hint for the window instance" },
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" },
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
@ -1598,6 +1600,15 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
{
settings->WmClass = _strdup(arg->Value);
}
CommandLineSwitchCase(arg, "play-rfx")
{
settings->PlayRemoteFxFile = _strdup(arg->Value);
settings->PlayRemoteFx = TRUE;
}
CommandLineSwitchCase(arg, "auth-only")
{
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchDefault(arg)
{

3
docs/README.directfb Normal file
View File

@ -0,0 +1,3 @@
The dfreerdp FreeRDP client is currently orphaned and unmaintained so please don't expect it to build and work without problems.
If you are interested to update and maintain the dfreerdp client please let us know.

View File

@ -61,6 +61,7 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
FREERDP_API int tls_wait_read(rdpTls* tls);
FREERDP_API int tls_wait_write(rdpTls* tls);
FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname);
FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file);
FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);

View File

@ -20,17 +20,15 @@
#ifndef FREERDP_UTILS_STOPWATCH_H
#define FREERDP_UTILS_STOPWATCH_H
#include <time.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
struct _STOPWATCH
{
clock_t start;
clock_t end;
double elapsed;
clock_t count;
UINT64 start;
UINT64 end;
UINT64 elapsed;
UINT32 count;
};
typedef struct _STOPWATCH STOPWATCH;

View File

@ -500,6 +500,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
Glyph_Free(glyph_cache->context, glyph);
free(glyph->aj);
free(glyph);
glyph_cache->glyphCache[i].entries[j] = NULL;
}
}
free(glyph_cache->glyphCache[i].entries);
@ -509,6 +510,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
{
fragment = glyph_cache->fragCache.entries[i].fragment;
free(fragment);
glyph_cache->fragCache.entries[i].fragment = NULL;
}
free(glyph_cache->fragCache.entries);

View File

@ -68,9 +68,18 @@ void update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_col
pointer->height = pointer_color->height;
pointer->lengthAndMask = pointer_color->lengthAndMask;
pointer->lengthXorMask = pointer_color->lengthXorMask;
pointer->xorMaskData = pointer_color->xorMaskData;
pointer->andMaskData = pointer_color->andMaskData;
if (pointer->lengthAndMask && pointer_color->xorMaskData)
{
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
CopyMemory(pointer->andMaskData, pointer_color->andMaskData, pointer->lengthAndMask);
}
if (pointer->lengthXorMask && pointer_color->xorMaskData)
{
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
CopyMemory(pointer->xorMaskData, pointer_color->xorMaskData, pointer->lengthXorMask);
}
pointer->New(context, pointer);
pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer);
Pointer_Set(context, pointer);
@ -202,7 +211,10 @@ void pointer_cache_free(rdpPointerCache* pointer_cache)
pointer = pointer_cache->entries[i];
if (pointer != NULL)
{
Pointer_Free(pointer_cache->update->context, pointer);
pointer_cache->entries[i] = NULL;
}
}
free(pointer_cache->entries);

View File

@ -196,6 +196,8 @@ RFX_CONTEXT* rfx_context_new(void)
if (status == ERROR_SUCCESS)
{
dwSize = sizeof(dwValue);
if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
context->priv->UseThreads = dwValue ? 1 : 0;
@ -257,6 +259,9 @@ void rfx_context_free(RFX_CONTEXT* context)
{
CloseThreadpool(context->priv->ThreadPool);
DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv);
#ifdef WITH_PROFILER
fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
#endif
}
BufferPool_Free(context->priv->BufferPool);
@ -739,7 +744,10 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
if (context->priv->UseThreads)
{
for (i = 0; i < message->num_tiles; i++)
{
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
CloseThreadpoolWork(work_objects[i]);
}
free(work_objects);
free(params);

View File

@ -218,8 +218,10 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
Stream_Seek(data_in, cr_size);
}
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb);
PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb);
rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2],

View File

@ -1207,7 +1207,7 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return -1;
}
@ -1256,7 +1256,7 @@ int freerdp_set_param_int(rdpSettings* settings, int id, int param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return 0;
}
@ -1898,7 +1898,7 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return 0;
}
@ -1940,7 +1940,7 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return 0;
}
@ -2278,7 +2278,7 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return 0;
}
@ -2319,7 +2319,7 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param)
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
PubSub_OnParamChange(context->pubSub, context, &e);
return 0;
}

View File

@ -279,6 +279,14 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
{
UINT16 lengthSourceDescriptor;
if (rdp->state == CONNECTION_STATE_ACTIVE)
{
rdp->deactivation_reactivation = TRUE;
}
else
{
rdp->deactivation_reactivation = FALSE;
}
/*
* Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
* the following fields.

View File

@ -587,8 +587,15 @@ BOOL rdp_client_connect_finalize(rdpRdp* rdp)
return FALSE;
if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
return FALSE;
if (!rdp_send_client_persistent_key_list_pdu(rdp))
return FALSE;
/**
* [MS-RDPBCGR] 2.2.1.17
* Client persistent key list must be sent if a bitmap is
* stored in persistent bitmap cache or the server has advertised support for bitmap
* host cache and a deactivation reactivation sequence is *not* in progress.
*/
if (!rdp->deactivation_reactivation && rdp->settings->BitmapCachePersistEnabled)
if (!rdp_send_client_persistent_key_list_pdu(rdp))
return FALSE;
if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
return FALSE;

View File

@ -31,6 +31,7 @@
#include "message.h"
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/freerdp.h>
#include <freerdp/error.h>
@ -127,29 +128,31 @@ BOOL freerdp_connect(freerdp* instance)
update = instance->update;
s = StreamPool_Take(rdp->transport->ReceivePool, 0);
instance->update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
if (update->pcap_rfx)
if (!update->pcap_rfx)
return FALSE;
else
update->play_rfx = TRUE;
while (update->play_rfx && pcap_has_next_record(update->pcap_rfx))
while (pcap_has_next_record(update->pcap_rfx))
{
pcap_get_next_record_header(update->pcap_rfx, &record);
Stream_EnsureCapacity(s, record.length);
s = StreamPool_Take(rdp->transport->ReceivePool, record.length);
record.data = Stream_Buffer(s);
pcap_get_next_record_content(update->pcap_rfx, &record);
Stream_SetLength(s,record.length);
Stream_SetPosition(s, 0);
update->BeginPaint(update->context);
update_recv_surfcmds(update, Stream_Capacity(s), s);
update_recv_surfcmds(update, Stream_Length(s) , s);
update->EndPaint(update->context);
Stream_Release(s);
}
Stream_Release(s);
return TRUE;
}
}
@ -394,7 +397,10 @@ void freerdp_context_free(freerdp* instance)
IFCALL(instance->ContextFree, instance, instance->context);
rdp_free(instance->context->rdp);
instance->context->rdp = NULL;
graphics_free(instance->context->graphics);
instance->context->graphics = NULL;
PubSub_Free(instance->context->pubSub);

View File

@ -117,10 +117,16 @@ void Pointer_Free(rdpContext* context, rdpPointer* pointer)
pointer->Free(context, pointer);
if (pointer->xorMaskData)
{
free(pointer->xorMaskData);
pointer->xorMaskData = NULL;
}
if (pointer->andMaskData)
{
free(pointer->andMaskData);
pointer->andMaskData = NULL;
}
free(pointer);
}

View File

@ -157,6 +157,7 @@ struct rdp_rdp
UINT32 finalize_sc_pdus;
BOOL disconnect;
BOOL resendFocus;
BOOL deactivation_reactivation;
};
BOOL rdp_read_security_header(wStream* s, UINT16* flags);

View File

@ -58,15 +58,6 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3
return 0;
}
static void update_send_frame_acknowledge(rdpRdp* rdp, UINT32 frameId)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
Stream_Write_UINT32(s, frameId);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
}
static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT32 *length)
{
SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker;
@ -79,13 +70,6 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT3
IFCALL(update->SurfaceFrameMarker, update->context, marker);
if (update->context->rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE] &&
(update->context->rdp->settings->FrameAcknowledge > 0) &&
(marker->frameAction == SURFACECMD_FRAMEACTION_END))
{
update_send_frame_acknowledge(update->context->rdp, marker->frameId);
}
*length = 6;
return 0;

View File

@ -677,6 +677,7 @@ static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_
update_write_refresh_rect(s, count, areas);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id);
Stream_Release(s);
}
}
@ -705,6 +706,7 @@ static void update_send_suppress_output(rdpContext* context, BYTE allow, RECTANG
update_write_suppress_output(s, allow, area);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id);
Stream_Release(s);
}
}
@ -717,6 +719,7 @@ static void update_send_surface_command(rdpContext* context, wStream* s)
Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s));
Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s));
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update);
Stream_Release(update);
}
static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
@ -733,6 +736,8 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND*
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
update_force_flush(context);
Stream_Release(s);
}
static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
@ -747,6 +752,8 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
update_force_flush(context);
Stream_Release(s);
}
static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
@ -759,6 +766,7 @@ static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
s = rdp_data_pdu_init(rdp);
Stream_Write_UINT32(s, frameId);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
Stream_Release(s);
}
}
@ -770,6 +778,7 @@ static void update_send_synchronize(rdpContext* context)
s = fastpath_update_pdu_init(rdp->fastpath);
Stream_Zero(s, 2); /* pad2Octets (2 bytes) */
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s);
Stream_Release(s);
}
static void update_send_desktop_resize(rdpContext* context)
@ -1311,6 +1320,7 @@ static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDAT
updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT;
fastpath_send_update_pdu(rdp->fastpath, updateCode, s);
Stream_Release(s);
}
static void update_write_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color)
@ -1342,6 +1352,7 @@ static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE*
s = fastpath_update_pdu_init(rdp->fastpath);
update_write_pointer_color(s, pointer_color);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s);
Stream_Release(s);
}
static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
@ -1353,6 +1364,7 @@ static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* poi
Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
update_write_pointer_color(s, &pointer_new->colorPtrAttr);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s);
Stream_Release(s);
}
static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached)
@ -1363,6 +1375,7 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT
s = fastpath_update_pdu_init(rdp->fastpath);
Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s);
Stream_Release(s);
}
BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s)

View File

@ -100,6 +100,7 @@ BOOL tls_connect(rdpTls* tls)
CryptoCert cert;
long options = 0;
int connection_status;
char *hostname;
tls->ctx = SSL_CTX_new(TLSv1_client_method());
@ -183,7 +184,12 @@ BOOL tls_connect(rdpTls* tls)
return FALSE;
}
if (!tls_verify_certificate(tls, cert, tls->settings->ServerHostname))
if (tls->settings->GatewayUsageMethod)
hostname = tls->settings->GatewayHostname;
else
hostname = tls->settings->ServerHostname;
if (!tls_verify_certificate(tls, cert, hostname))
{
fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n");
tls_disconnect(tls);
@ -513,6 +519,26 @@ BOOL tls_print_error(char* func, SSL* connection, int value)
}
}
BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
{
if (strlen(hostname) == pattern_length)
{
if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0)
return TRUE;
}
if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.' && strlen(hostname) >= pattern_length)
{
char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ];
if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 )
{
return TRUE;
}
}
return FALSE;
}
BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
{
int match;
@ -549,11 +575,8 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
if (common_name != NULL)
{
if (strlen(hostname) == common_name_length)
{
if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0)
hostname_match = TRUE;
}
if (tls_match_hostname(common_name, common_name_length, hostname))
hostname_match = TRUE;
}
/* compare against alternative names */
@ -562,10 +585,10 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
{
for (index = 0; index < alt_names_count; index++)
{
if (strlen(hostname) == alt_names_lengths[index])
if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
{
if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0)
hostname_match = TRUE;
hostname_match = TRUE;
break;
}
}
}

View File

@ -107,7 +107,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
rdpGdi* gdi;
BOOL status;
size = width * height * (bpp + 7) / 8;
size = width * height * ((bpp + 7) / 8);
if (bitmap->data == NULL)
bitmap->data = (BYTE*) malloc(size);

View File

@ -175,7 +175,7 @@ char* gdi_convert_postfix_to_infix(char* postfix)
dl = al + bl + cl + 3;
d = malloc(cl + 1);
d = malloc(dl + 1);
sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a);
Stack_Push(stack, d);

View File

@ -154,6 +154,7 @@ XKB_KEY_NAME_SCANCODE XKB_KEY_NAME_SCANCODE_TABLE[] =
{ "LWIN", RDP_SCANCODE_LWIN},
{ "RWIN", RDP_SCANCODE_RWIN},
{ "COMP", RDP_SCANCODE_APPS},
{ "MENU", RDP_SCANCODE_APPS}, // WinMenu in xfree86 layout
{ "KPDV", RDP_SCANCODE_DIVIDE}, // KP!
{ "RCTL", RDP_SCANCODE_RCONTROL},
{ "RALT", RDP_SCANCODE_RMENU},

View File

@ -158,7 +158,7 @@ rdpPcap* pcap_open(char* name, BOOL write)
{
rdpPcap* pcap;
FILE* pcap_fp = fopen(name, write ? "w+" : "r");
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
if (pcap_fp == NULL)
{

View File

@ -70,7 +70,7 @@ void profiler_print(PROFILER* profiler)
double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch);
double avg_sec = elapsed_sec / (double) profiler->stopwatch->count;
fprintf(stderr, "| %-30.30s| %'10lu | %'9f | %'9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
}
void profiler_print_footer()

View File

@ -26,9 +26,33 @@
#include <freerdp/utils/stopwatch.h>
#ifdef _WIN32
LARGE_INTEGER stopwatch_freq = { 0, 0 };
#else
#include <sys/time.h>
#endif
void stopwatch_set_time(UINT64* usecs)
{
#ifdef _WIN32
LARGE_INTEGER perfcount;
QueryPerformanceCounter(&perfcount);
*usecs = (perfcount.QuadPart * 1000000) / stopwatch_freq.QuadPart;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
*usecs = tv.tv_sec * 1000000 + tv.tv_usec;
#endif
}
STOPWATCH* stopwatch_create()
{
STOPWATCH* sw;
#ifdef _WIN32
if (stopwatch_freq.QuadPart == 0) {
QueryPerformanceFrequency(&stopwatch_freq);
}
#endif
sw = (STOPWATCH*) malloc(sizeof(STOPWATCH));
stopwatch_reset(sw);
@ -43,13 +67,13 @@ void stopwatch_free(STOPWATCH* stopwatch)
void stopwatch_start(STOPWATCH* stopwatch)
{
stopwatch->start = clock();
stopwatch_set_time(&stopwatch->start);
stopwatch->count++;
}
void stopwatch_stop(STOPWATCH* stopwatch)
{
stopwatch->end = clock();
stopwatch_set_time(&stopwatch->end);
stopwatch->elapsed += (stopwatch->end - stopwatch->start);
}
@ -63,22 +87,12 @@ void stopwatch_reset(STOPWATCH* stopwatch)
double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch)
{
return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC;
return (stopwatch->elapsed/1000000.0);
}
void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, UINT32* sec, UINT32* usec)
{
double uelapsed;
double clocks_per_usec;
*sec = ((UINT32) stopwatch->elapsed) / CLOCKS_PER_SEC;
uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC);
clocks_per_usec = (CLOCKS_PER_SEC / 1000000);
if (clocks_per_usec > 0.0)
*usec = (UINT32)(uelapsed / clocks_per_usec);
else
*usec = 0;
*sec = stopwatch->elapsed / 1000000;
*usec = stopwatch->elapsed % 1000000;
}

View File

@ -19,11 +19,11 @@
add_subdirectory(common)
if(NOT WIN32)
if(WITH_SAMPLE)
add_subdirectory(Sample)
endif()
if(WITH_SAMPLE)
add_subdirectory(Sample)
endif()
if(NOT WIN32)
if(WITH_X11)
add_subdirectory(X11)
endif()

View File

@ -26,14 +26,13 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <freerdp/constants.h>
#include <freerdp/utils/tcp.h>
#include <freerdp/server/rdpsnd.h>
#include "sf_audin.h"
@ -41,6 +40,10 @@
#include "sfreerdp.h"
#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 1
#define SAMPLE_SERVER_DEFAULT_WIDTH 1024
#define SAMPLE_SERVER_DEFAULT_HEIGHT 768
static char* test_pcap_file = NULL;
static BOOL test_dump_rfx_realtime = TRUE;
@ -48,8 +51,8 @@ void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
{
context->rfx_context = rfx_context_new();
context->rfx_context->mode = RLGR3;
context->rfx_context->width = client->settings->DesktopWidth;
context->rfx_context->height = client->settings->DesktopHeight;
context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH;
context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT;
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8);
context->nsc_context = nsc_context_new();
@ -473,6 +476,17 @@ BOOL tf_peer_post_connect(freerdp_peer* client)
printf("Client requested desktop: %dx%dx%d\n",
client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
#if (SAMPLE_SERVER_USE_CLIENT_RESOLUTION == 1)
context->rfx_context->width = client->settings->DesktopWidth;
context->rfx_context->height = client->settings->DesktopHeight;
printf("Using resolution requested by client.\n");
#else
client->settings->DesktopWidth = context->rfx_context->width;
client->settings->DesktopHeight = context->rfx_context->height;
printf("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight);
client->update->DesktopResize(client->update->context);
#endif
/* A real server should tag the peer as activated here and start sending updates in main loop. */
test_peer_load_icon(client);
@ -554,9 +568,11 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
}
else
{
client->settings->DesktopWidth = 640;
client->settings->DesktopHeight = 480;
client->settings->DesktopWidth = SAMPLE_SERVER_DEFAULT_WIDTH;
client->settings->DesktopHeight = SAMPLE_SERVER_DEFAULT_HEIGHT;
}
context->rfx_context->width = client->settings->DesktopWidth;
context->rfx_context->height = client->settings->DesktopHeight;
update->DesktopResize(update->context);
context->activated = FALSE;
}
@ -667,6 +683,8 @@ static void* test_peer_mainloop(void* arg)
client->update->RefreshRect = tf_peer_refresh_rect;
client->update->SuppressOutput = tf_peer_suppress_output;
client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */
client->Initialize(client);
context = (testPeerContext*) client->context;
@ -681,7 +699,11 @@ static void* test_peer_mainloop(void* arg)
printf("Failed to get FreeRDP file descriptor\n");
break;
}
#ifndef _WIN32
/* winsock's select() only works with sockets ! */
WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount);
#endif
max_fds = 0;
FD_ZERO(&rfds_set);
@ -701,15 +723,27 @@ static void* test_peer_mainloop(void* arg)
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
{
#ifdef _WIN32
/* error codes set by windows sockets are not made available through errno ! */
int wsa_error = WSAGetLastError();
if (!((wsa_error == WSAEWOULDBLOCK) ||
(wsa_error == WSAEINPROGRESS) ||
(wsa_error == WSAEINTR)))
{
printf("select failed (WSAGetLastError: %d)\n", wsa_error);
break;
}
#else
/* these are not really errors */
if (!((errno == EAGAIN) ||
(errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
printf("select failed\n");
printf("select failed (errno: %d)\n", errno);
break;
}
#endif
}
if (client->CheckFileDescriptor(client) != TRUE)
@ -730,10 +764,10 @@ static void* test_peer_mainloop(void* arg)
static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
{
pthread_t th;
pthread_create(&th, 0, test_peer_mainloop, client);
pthread_detach(th);
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL);
if (hThread != NULL) {
CloseHandle(hThread);
}
}
static void test_server_mainloop(freerdp_listener* instance)
@ -800,9 +834,6 @@ int main(int argc, char* argv[])
{
freerdp_listener* instance;
/* Ignore SIGPIPE, otherwise an SSL_write failure could crash your server */
signal(SIGPIPE, SIG_IGN);
instance = freerdp_listener_new();
instance->PeerAccepted = test_peer_accepted;
@ -814,12 +845,14 @@ int main(int argc, char* argv[])
test_dump_rfx_realtime = FALSE;
/* Open the server socket and start listening. */
freerdp_wsa_startup();
if (instance->Open(instance, NULL, 3389) &&
instance->OpenLocal(instance, "/tmp/tfreerdp-server.0"))
{
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
test_server_mainloop(instance);
}
freerdp_wsa_cleanup();
freerdp_listener_free(instance);

Binary file not shown.

View File

@ -52,5 +52,6 @@ int xf_cursor_init(xfInfo* xfi)
XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask);
#endif
return 0;
}

View File

@ -35,32 +35,20 @@
#include <malloc.h>
#endif
struct _aligned_meminfo {
size_t size;
void *base_addr;
};
void* _aligned_malloc(size_t size, size_t alignment)
{
void* memptr;
/* alignment must be a power of 2 */
if (alignment % 2 == 1)
return NULL;
#ifdef ANDROID
memptr = memalign(alignment, size);
#else
if (posix_memalign(&memptr, alignment, size) != 0)
return NULL;
#endif
return memptr;
return _aligned_offset_malloc(size, alignment, 0);
}
void* _aligned_realloc(void* memblock, size_t size, size_t alignment)
{
void* memptr = NULL;
memptr = realloc(memblock, size);
return memptr;
return _aligned_offset_realloc(memblock, size, alignment, 0);
}
void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment)
@ -70,36 +58,59 @@ void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignmen
void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
{
void* memptr;
void* memptr, *tmpptr;
struct _aligned_meminfo *ameminfo;
/* alignment must be a power of 2 */
if (alignment % 2 == 1)
return NULL;
/* offset must be less than size */
if (offset >= size)
return NULL;
/* minimum alignment is pointer size */
if (alignment < sizeof(void*))
alignment = sizeof(void*);
#ifdef ANDROID
memptr = memalign(alignment, size);
#else
if (posix_memalign(&memptr, alignment, size) != 0)
/* malloc size + alignment to make sure we can align afterwards */
tmpptr = malloc(size + alignment + sizeof(struct _aligned_meminfo));
if (!tmpptr)
return NULL;
#endif
memptr = (void *)((((size_t)((PBYTE)tmpptr + alignment + offset + sizeof(struct _aligned_meminfo)) & ~(alignment - 1)) - offset));
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo))));
ameminfo->base_addr = tmpptr;
ameminfo->size = size;
return memptr;
}
void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset)
{
return NULL;
struct _aligned_meminfo *ameminfo;
void *newmem;
if (!memblock)
return _aligned_offset_malloc(size, alignment, offset);
if (size == 0)
{
_aligned_free(memblock);
return NULL;
}
/* The following is not very performant but a simple and working solution */
newmem = _aligned_offset_malloc(size, alignment, offset);
if (!newmem)
return NULL;
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
memcpy(newmem, memblock, ameminfo->size);
_aligned_free(memblock);
return newmem;
}
void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset)
@ -114,7 +125,13 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset)
void _aligned_free(void* memblock)
{
free(memblock);
struct _aligned_meminfo *ameminfo;
if (!memblock)
return;
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
free(ameminfo->base_addr);
}
#endif

View File

@ -47,6 +47,9 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj
{
WINPR_HANDLE* wHandle;
if (handle == NULL)
return FALSE;
wHandle = (WINPR_HANDLE*) handle;
*pType = wHandle->Type;

View File

@ -52,17 +52,23 @@ VOID USleep(DWORD dwMicroseconds)
#ifndef _WIN32
usleep(dwMicroseconds);
#else
UINT64 t1;
UINT64 t2;
UINT64 freq;
static LARGE_INTEGER freq = { 0, 0 };
LARGE_INTEGER t1 = { 0, 0 };
LARGE_INTEGER t2 = { 0, 0 };
QueryPerformanceCounter((LARGE_INTEGER*) &t1);
QueryPerformanceCounter((LARGE_INTEGER*) &freq);
QueryPerformanceCounter(&t1);
do
{
QueryPerformanceCounter((LARGE_INTEGER*) &t2);
if (freq.QuadPart == 0) {
QueryPerformanceFrequency(&freq);
}
while ((t2 - t1) < dwMicroseconds);
// in order to save cpu cyles we use Sleep() for the large share ...
if (dwMicroseconds >= 1000) {
Sleep(dwMicroseconds/1000);
}
// ... and busy loop until all the requested micro seconds have passed
do {
QueryPerformanceCounter(&t2);
} while (((t2.QuadPart - t1.QuadPart)*1000000)/freq.QuadPart < dwMicroseconds);
#endif
}