diff --git a/README b/README index 6c67f0102..f40c20c56 100644 --- a/README +++ b/README @@ -8,10 +8,12 @@ interoperability can finally liberate your computing experience. Resources --------- -Website: http://www.freerdp.com/ -Wiki: https://github.com/FreeRDP/FreeRDP/wiki +Project website: http://www.freerdp.com/ +Issue tracker: https://github.com/FreeRDP/FreeRDP/issues Sources: https://github.com/FreeRDP/FreeRDP/ -API doc: http://www.freerdp.com/api/ +Wiki: https://github.com/FreeRDP/FreeRDP/wiki +Downloads and other resources: http://pub.freerdp.com +API doc: http://pub.freerdp.com/api/ IRC channel: #freerdp @ irc.freenode.net Mailing list: https://lists.sourceforge.net/lists/listinfo/freerdp-devel diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 1147fa816..854fd46ab 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -26,9 +26,12 @@ #include #include +#include +#include #include #include #include +#include #include @@ -92,9 +95,15 @@ struct _RDPEI_PLUGIN RDPINPUT_TOUCH_FRAME frame; RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS]; RDPINPUT_CONTACT_POINT* contactPoints; + + HANDLE mutex; + HANDLE event; + HANDLE thread; }; typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN; +int rdpei_send_frame(RdpeiClientContext* context); + const char* RDPEI_EVENTID_STRINGS[] = { "", @@ -106,6 +115,67 @@ const char* RDPEI_EVENTID_STRINGS[] = "EVENTID_DISMISS_HOVERING_CONTACT" }; +int rdpei_add_frame(RdpeiClientContext* context) +{ + int i; + RDPINPUT_CONTACT_DATA* contact; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; + + rdpei->frame.contactCount = 0; + + for (i = 0; i < rdpei->maxTouchContacts; i++) + { + contact = (RDPINPUT_CONTACT_DATA*) &(rdpei->contactPoints[i].data); + + if (rdpei->contactPoints[i].dirty) + { + CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); + rdpei->contactPoints[i].dirty = FALSE; + rdpei->frame.contactCount++; + } + else if (rdpei->contactPoints[i].active) + { + if (contact->contactFlags & CONTACT_FLAG_DOWN) + { + contact->contactFlags = CONTACT_FLAG_UPDATE; + contact->contactFlags |= CONTACT_FLAG_INRANGE; + contact->contactFlags |= CONTACT_FLAG_INCONTACT; + } + + CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); + rdpei->frame.contactCount++; + } + } + + return 1; +} + +static void* rdpei_schedule_thread(void* arg) +{ + DWORD status; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg; + RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface; + + while (1) + { + status = WaitForSingleObject(rdpei->event, 20); + + WaitForSingleObject(rdpei->mutex, INFINITE); + + rdpei_add_frame(context); + + if (rdpei->frame.contactCount > 0) + rdpei_send_frame(context); + + if (status == WAIT_OBJECT_0) + ResetEvent(rdpei->event); + + ReleaseMutex(rdpei->mutex); + } + + return NULL; +} + int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength) { int status; @@ -118,7 +188,7 @@ int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL); #ifdef WITH_DEBUG_RDPEI - printf("rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n", + fprintf(stderr, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n", eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status); #endif @@ -147,6 +217,13 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) Stream_SealLength(s); + if (!rdpei->thread) + { + rdpei->mutex = CreateMutex(NULL, FALSE, NULL); + rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL); + rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL); + } + status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength); Stream_Free(s, TRUE); @@ -180,7 +257,12 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) #endif rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */ - rdpei_write_8byte_unsigned(s, frame->frameOffset); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ + + /** + * the time offset from the previous frame (in microseconds). + * If this is the first frame being transmitted then this field MUST be set to zero. + */ + rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ Stream_EnsureRemainingCapacity(s, frame->contactCount * 32); @@ -248,8 +330,13 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_ s = Stream_New(NULL, pduLength); Stream_Seek(s, RDPINPUT_HEADER_LENGTH); - rdpei_write_4byte_unsigned(s, frame->frameOffset); /* FOUR_BYTE_UNSIGNED_INTEGER */ - rdpei_write_2byte_unsigned(s, 1); /* TWO_BYTE_UNSIGNED_INTEGER */ + /** + * the time that has elapsed (in milliseconds) from when the oldest touch frame + * was generated to when it was encoded for transmission by the client. + */ + rdpei_write_4byte_unsigned(s, frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */ + + rdpei_write_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */ rdpei_write_touch_frame(s, frame); @@ -270,7 +357,7 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) if (protocolVersion != RDPINPUT_PROTOCOL_V1) { - printf("Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); + fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); return -1; } @@ -296,7 +383,7 @@ int rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */ #ifdef WITH_DEBUG_RDPEI - printf("rdpei_recv_pdu: eventId: %d (%s) length: %d\n", + fprintf(stderr, "rdpei_recv_pdu: eventId: %d (%s) length: %d\n", eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength); #endif @@ -443,88 +530,157 @@ int rdpei_send_frame(RdpeiClientContext* context) int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact) { + RDPINPUT_CONTACT_POINT* contactPoint; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; - if (rdpei->frame.contactCount < MAX_CONTACTS) - { - CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); - rdpei->frame.contactCount++; - } + WaitForSingleObject(rdpei->mutex, INFINITE); - rdpei_send_frame(context); + contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId]; + CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA)); + contactPoint->dirty = TRUE; + + SetEvent(rdpei->event); + + ReleaseMutex(rdpei->mutex); return 1; } -int rdpei_contact_begin(RdpeiClientContext* context, int externalId) +int rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y) { int i; int contactId = -1; + RDPINPUT_CONTACT_DATA contact; + RDPINPUT_CONTACT_POINT* contactPoint = NULL; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; /* Create a new contact point in an empty slot */ for (i = 0; i < rdpei->maxTouchContacts; i++) { - if (!rdpei->contactPoints[i].flags) - { - rdpei->contactPoints[i].flags = 1; - rdpei->contactPoints[i].contactId = i; + contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i]; - if (!rdpei->contactPoints[i].externalId) - { - rdpei->contactPoints[i].externalId = externalId; - contactId = rdpei->contactPoints[i].contactId; - break; - } + if (!contactPoint->active) + { + contactPoint->contactId = i; + contactId = contactPoint->contactId; + contactPoint->externalId = externalId; + contactPoint->active = TRUE; + contactPoint->state = RDPINPUT_CONTACT_STATE_ENGAGED; + break; } } + if (contactId >= 0) + { + ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); + + contactPoint->lastX = x; + contactPoint->lastY = y; + + contact.x = x; + contact.y = y; + contact.contactId = (UINT32) contactId; + + contact.contactFlags |= CONTACT_FLAG_DOWN; + contact.contactFlags |= CONTACT_FLAG_INRANGE; + contact.contactFlags |= CONTACT_FLAG_INCONTACT; + + context->AddContact(context, &contact); + } + return contactId; } -int rdpei_contact_update(RdpeiClientContext* context, int externalId) +int rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int y) { int i; int contactId = -1; + RDPINPUT_CONTACT_DATA contact; + RDPINPUT_CONTACT_POINT* contactPoint = NULL; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; for (i = 0; i < rdpei->maxTouchContacts; i++) { - if (!rdpei->contactPoints[i].flags) + contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i]; + + if (!contactPoint->active) continue; - if (rdpei->contactPoints[i].externalId == externalId) + if (contactPoint->externalId == externalId) { - contactId = rdpei->contactPoints[i].contactId; + contactId = contactPoint->contactId; break; } } + if (contactId >= 0) + { + ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); + + contactPoint->lastX = x; + contactPoint->lastY = y; + + contact.x = x; + contact.y = y; + contact.contactId = (UINT32) contactId; + + contact.contactFlags |= CONTACT_FLAG_UPDATE; + contact.contactFlags |= CONTACT_FLAG_INRANGE; + contact.contactFlags |= CONTACT_FLAG_INCONTACT; + + context->AddContact(context, &contact); + } + return contactId; } -int rdpei_contact_end(RdpeiClientContext* context, int externalId) +int rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y) { int i; int contactId = -1; + RDPINPUT_CONTACT_DATA contact; + RDPINPUT_CONTACT_POINT* contactPoint; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; for (i = 0; i < rdpei->maxTouchContacts; i++) { - if (!rdpei->contactPoints[i].flags) + contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i]; + + if (!contactPoint->active) continue; - if (rdpei->contactPoints[i].externalId == externalId) + if (contactPoint->externalId == externalId) { - contactId = rdpei->contactPoints[i].contactId; - rdpei->contactPoints[i].externalId = 0; - rdpei->contactPoints[i].flags = 0; - rdpei->contactPoints[i].contactId = 0; + contactId = contactPoint->contactId; break; } } + if (contactId >= 0) + { + ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); + + if ((contactPoint->lastX != x) && (contactPoint->lastY != y)) + { + context->TouchUpdate(context, externalId, x, y); + } + + contact.x = x; + contact.y = y; + contact.contactId = (UINT32) contactId; + + contact.contactFlags |= CONTACT_FLAG_UP; + + context->AddContact(context, &contact); + + contactPoint->externalId = 0; + contactPoint->active = FALSE; + contactPoint->flags = 0; + contactPoint->contactId = 0; + contactPoint->state = RDPINPUT_CONTACT_STATE_OUT_OF_RANGE; + } + return contactId; } @@ -568,9 +724,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) context->GetVersion = rdpei_get_version; context->AddContact = rdpei_add_contact; - context->ContactBegin = rdpei_contact_begin; - context->ContactUpdate = rdpei_contact_update; - context->ContactEnd = rdpei_contact_end; + context->TouchBegin = rdpei_touch_begin; + context->TouchUpdate = rdpei_touch_update; + context->TouchEnd = rdpei_touch_end; rdpei->iface.pInterface = (void*) context; diff --git a/channels/rdpei/client/rdpei_main.h b/channels/rdpei/client/rdpei_main.h index 8c0137ce4..c0d0d2d67 100644 --- a/channels/rdpei/client/rdpei_main.h +++ b/channels/rdpei/client/rdpei_main.h @@ -31,31 +31,70 @@ #include -#define RDPINPUT_HEADER_LENGTH 6 +#define RDPINPUT_HEADER_LENGTH 6 /* Protocol Version */ -#define RDPINPUT_PROTOCOL_V1 0x00010000 +#define RDPINPUT_PROTOCOL_V1 0x00010000 /* Client Ready Flags */ -#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001 -#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002 +#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001 +#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002 /* Input Event Ids */ -#define EVENTID_SC_READY 0x0001 -#define EVENTID_CS_READY 0x0002 -#define EVENTID_TOUCH 0x0003 -#define EVENTID_SUSPEND_TOUCH 0x0004 -#define EVENTID_RESUME_TOUCH 0x0005 -#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006 +#define EVENTID_SC_READY 0x0001 +#define EVENTID_CS_READY 0x0002 +#define EVENTID_TOUCH 0x0003 +#define EVENTID_SUSPEND_TOUCH 0x0004 +#define EVENTID_RESUME_TOUCH 0x0005 +#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006 + +#define RDPINPUT_CONTACT_STATE_INITIAL 0x0000 +#define RDPINPUT_CONTACT_STATE_ENGAGED 0x0001 +#define RDPINPUT_CONTACT_STATE_HOVERING 0x0002 +#define RDPINPUT_CONTACT_STATE_OUT_OF_RANGE 0x0003 + +/** + * Touch Contact State Transitions + * + * ENGAGED -> UPDATE | INRANGE | INCONTACT -> ENGAGED + * ENGAGED -> UP | INRANGE -> HOVERING + * ENGAGED -> UP -> OUT_OF_RANGE + * ENGAGED -> UP | CANCELED -> OUT_OF_RANGE + * + * HOVERING -> UPDATE | INRANGE -> HOVERING + * HOVERING -> DOWN | INRANGE | INCONTACT -> ENGAGED + * HOVERING -> UPDATE -> OUT_OF_RANGE + * HOVERING -> UPDATE | CANCELED -> OUT_OF_RANGE + * + * OUT_OF_RANGE -> DOWN | INRANGE | INCONTACT -> ENGAGED + * OUT_OF_RANGE -> UPDATE | INRANGE -> HOVERING + * + * When a contact is in the "hovering" or "engaged" state, it is referred to as being "active". + * "Hovering" contacts are in range of the digitizer, while "engaged" contacts are in range of + * the digitizer and in contact with the digitizer surface. MS-RDPEI remotes only active contacts + * and contacts that are transitioning to the "out of range" state; see section 2.2.3.3.1.1 for + * an enumeration of valid state flags combinations. + * + * When transitioning from the "engaged" state to the "hovering" state, or from the "engaged" + * state to the "out of range" state, the contact position cannot change; it is only allowed + * to change after the transition has taken place. + * + */ struct _RDPINPUT_CONTACT_POINT { + int lastX; + int lastY; + BOOL dirty; + BOOL active; + UINT32 state; UINT32 flags; UINT32 contactId; int externalId; + RDPINPUT_CONTACT_DATA data; }; typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT; diff --git a/channels/server/channels.c b/channels/server/channels.c index 18facafd5..eeae1dc22 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -552,9 +552,25 @@ void* WTSVirtualChannelOpenEx( if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) { + for (i = 0; i < client->settings->ChannelCount; i++) + { + if (client->settings->ChannelDefArray[i].joined && + strncmp(client->settings->ChannelDefArray[i].Name, "drdynvc", 7) == 0) + { + break; + } + } + if (i >= client->settings->ChannelCount) + { + DEBUG_DVC("Dynamic virtual channel not registered."); + SetLastError(ERROR_NOT_FOUND); + return NULL; + } + if (vcm->drdynvc_channel == NULL || vcm->drdynvc_state != DRDYNVC_STATE_READY) { DEBUG_DVC("Dynamic virtual channel not ready."); + SetLastError(ERROR_NOT_READY); return NULL; } @@ -586,7 +602,10 @@ void* WTSVirtualChannelOpenEx( len = strlen(pVirtualName); if (len > 8) + { + SetLastError(ERROR_NOT_FOUND); return NULL; + } for (i = 0; i < client->settings->ChannelCount; i++) { @@ -598,7 +617,10 @@ void* WTSVirtualChannelOpenEx( } if (i >= client->settings->ChannelCount) + { + SetLastError(ERROR_NOT_FOUND); return NULL; + } channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle; diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake index 1632a7c18..161f5c061 100644 --- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake +++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake @@ -11,7 +11,7 @@ - + diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 51a6a4695..2d8ea7f8b 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -258,6 +258,8 @@ int android_freerdp_run(freerdp* instance) void* wfds[32]; fd_set rfds_set; fd_set wfds_set; + int select_status; + struct timeval timeout; memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); @@ -269,7 +271,7 @@ int android_freerdp_run(freerdp* instance) } ((androidContext*)instance->context)->is_connected = TRUE; - while (1) + while (!freerdp_shall_disconnect(instance)) { rcount = 0; wcount = 0; @@ -307,7 +309,14 @@ int android_freerdp_run(freerdp* instance) if (max_fds == 0) break; - if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); + + if (select_status == 0) + continue; + else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || @@ -495,9 +504,6 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE; settings->SoftwareGdi = TRUE; - - /* enable NSCodec */ - settings->NSCodec = TRUE; settings->BitmapCacheV3Enabled = TRUE; switch ((int) security) @@ -561,6 +567,11 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( settings->LargePointerFlag = TRUE; settings->FrameMarkerCommandEnabled = TRUE; } + else + { + /* enable NSCodec if we don't use remotefx */ + settings->NSCodec = TRUE; + } /* store performance settings */ if (disableWallpaper == JNI_TRUE) diff --git a/client/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml index 5dfbf0c24..4bff58d5f 100644 --- a/client/Android/FreeRDPCore/res/values-nl/strings.xml +++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml @@ -105,6 +105,10 @@ 3G Instellingen 3G Scherm 3G Prestatie + Gateway + Gateway inschakelen + Gateway instellingen + SDCard aankoppelen Beveiliging Automatisch diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index 751c235b9..3f481cb6a 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -7,7 +7,7 @@ android:versionName="@GIT_REVISION@" > - + + + aFreeRDP + + aFreeRDP + Remote Computers + diff --git a/client/Android/aFreeRDP/res/values-nl/strings.xml b/client/Android/aFreeRDP/res/values-nl/strings.xml new file mode 100644 index 000000000..f0aa7c6af --- /dev/null +++ b/client/Android/aFreeRDP/res/values-nl/strings.xml @@ -0,0 +1,7 @@ + + + aFreeRDP + + aFreeRDP + Remote Computers + diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index 9db6b4dff..a0d7e5a04 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -325,11 +325,11 @@ char* xf_input_touch_state_string(DWORD flags) return "TouchUnknown"; } -int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags) +int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, int evtype) { int x, y; int touchId; - RDPINPUT_CONTACT_DATA contact; + int contactId; RdpeiClientContext* rdpei = xfi->rdpei; if (!rdpei) @@ -338,32 +338,23 @@ int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags) touchId = event->detail; x = (int) event->event_x; y = (int) event->event_y; - ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); - contact.fieldsPresent = 0; - contact.x = x; - contact.y = y; - contact.contactFlags = flags; - - if (flags & CONTACT_FLAG_DOWN) + if (evtype == XI_TouchBegin) { - contact.contactId = rdpei->ContactBegin(rdpei, touchId); - contact.contactFlags |= CONTACT_FLAG_INRANGE; - contact.contactFlags |= CONTACT_FLAG_INCONTACT; + //printf("TouchBegin: %d\n", touchId); + contactId = rdpei->TouchBegin(rdpei, touchId, x, y); } - else if (flags & CONTACT_FLAG_UPDATE) + else if (evtype == XI_TouchUpdate) { - contact.contactId = rdpei->ContactUpdate(rdpei, touchId); - contact.contactFlags |= CONTACT_FLAG_INRANGE; - contact.contactFlags |= CONTACT_FLAG_INCONTACT; + //printf("TouchUpdate: %d\n", touchId); + contactId = rdpei->TouchUpdate(rdpei, touchId, x, y); } - else if (flags & CONTACT_FLAG_UP) + else if (evtype == XI_TouchEnd) { - contact.contactId = rdpei->ContactEnd(rdpei, touchId); + //printf("TouchEnd: %d\n", touchId); + contactId = rdpei->TouchEnd(rdpei, touchId, x, y); } - rdpei->AddContact(rdpei, &contact); - return 0; } @@ -378,15 +369,15 @@ int xf_input_handle_event_remote(xfInfo* xfi, XEvent* event) switch (cookie->evtype) { case XI_TouchBegin: - xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_DOWN); + xf_input_touch_remote(xfi, cookie->data, XI_TouchBegin); break; case XI_TouchUpdate: - xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UPDATE); + xf_input_touch_remote(xfi, cookie->data, XI_TouchUpdate); break; case XI_TouchEnd: - xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UP); + xf_input_touch_remote(xfi, cookie->data, XI_TouchEnd); break; default: diff --git a/client/X11/xf_interface.c b/client/X11/xf_interface.c index 13ac4d9ac..5741e1a0e 100644 --- a/client/X11/xf_interface.c +++ b/client/X11/xf_interface.c @@ -1610,9 +1610,7 @@ xfInfo* freerdp_client_new(int argc, char** argv) for (index = 0; index < argc; index++) instance->context->argv[index] = _strdup(argv[index]); - xfi = (xfInfo*) malloc(sizeof(xfInfo)); - ZeroMemory(xfi, sizeof(xfInfo)); - + xfi = (xfInfo*) instance->context; ((xfContext*) instance->context)->xfi = xfi; xfi->instance = instance; @@ -1685,24 +1683,24 @@ void freerdp_client_free(xfInfo* xfi) if (xfi) { int index; + freerdp* instance; rdpContext* context; + context = (rdpContext*) xfi->context; + instance = context->instance; + xf_window_free(xfi); free(xfi->bmp_codec_none); XCloseDisplay(xfi->display); - context = (rdpContext*) xfi->context; - for (index = 0; index < context->argc; index++) free(context->argv[index]); free(context->argv); - freerdp_context_free(xfi->instance); - freerdp_free(xfi->instance); - - free(xfi); + freerdp_context_free(instance); + freerdp_free(instance); } } diff --git a/client/X11/xf_interface.h b/client/X11/xf_interface.h index 34c2c2870..d584808b7 100644 --- a/client/X11/xf_interface.h +++ b/client/X11/xf_interface.h @@ -34,7 +34,7 @@ #include #include -typedef struct xf_info xfInfo; +typedef struct xf_context xfInfo; #ifdef __cplusplus extern "C" { diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index a7ff67ce0..e7db12cc6 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -195,12 +195,13 @@ void xf_kbd_focus_in(xfInfo* xfi) Window wdummy; UINT32 state = 0; - input = xfi->instance->input; - - syncFlags = xf_kbd_get_toggle_keys_state(xfi); - XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state); - - input->FocusInEvent(input, syncFlags, mouseX, mouseY); + if (xfi->display && xfi->window) + { + input = xfi->instance->input; + syncFlags = xf_kbd_get_toggle_keys_state(xfi); + XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state); + input->FocusInEvent(input, syncFlags, mouseX, mouseY); + } } BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym) diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 3b530a529..19417d0d6 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -54,17 +54,14 @@ struct xf_glyph }; typedef struct xf_glyph xfGlyph; +typedef struct xf_context xfContext; + struct xf_context { rdpContext _p; xfInfo* xfi; - rdpSettings* settings; -}; -typedef struct xf_context xfContext; -struct xf_info -{ freerdp* instance; xfContext* context; rdpContext* _context; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 57bf9a74c..77353ff81 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -126,6 +126,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "glyph-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "glyph cache" }, { "codec-cache", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "bitmap codec cache" }, { "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" }, + { "max-fast-path-size", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "maximum fast-path update size" }, { "async-input", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous input" }, { "async-update", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous update" }, { "async-transport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous transport (unstable)" }, @@ -1571,6 +1572,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->FastPathInput = arg->Value ? TRUE : FALSE; settings->FastPathOutput = arg->Value ? TRUE : FALSE; } + CommandLineSwitchCase(arg, "max-fast-path-size") + { + settings->MultifragMaxRequestSize = atoi(arg->Value); + } CommandLineSwitchCase(arg, "async-input") { settings->AsyncInput = arg->Value ? TRUE : FALSE; diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index ee0cdddc0..a5aeafd66 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -138,11 +138,13 @@ ios_run_freerdp(freerdp * instance) void* wfds[32]; fd_set rfds_set; fd_set wfds_set; + struct timeval timeout; + int select_status; memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); - while (1) + while (!freerdp_shall_disconnect(instance)) { rcount = wcount = 0; @@ -179,11 +181,19 @@ ios_run_freerdp(freerdp * instance) FD_SET(fds, &rfds_set); } - + if (max_fds == 0) break; - - if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); + + // timeout? + if (select_status == 0) + continue; + else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || @@ -191,7 +201,7 @@ ios_run_freerdp(freerdp * instance) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - NSLog(@"%s: max_sck is zero.", __func__); + NSLog(@"%s: select failed!", __func__); break; } } diff --git a/client/iOS/Models/Encryptor.m b/client/iOS/Models/Encryptor.m index 112572218..f4f6ad2f0 100644 --- a/client/iOS/Models/Encryptor.m +++ b/client/iOS/Models/Encryptor.m @@ -44,8 +44,7 @@ if (CCKeyDerivationPBKDF != NULL) { - int rounds = CCCalibratePBKDF(kCCPBKDF2, strlen(plaintext_password_data), TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, TSXEncryptorPBKDF2KeySize, 100); - int ret = CCKeyDerivationPBKDF(kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data)-1, (const uint8_t*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, rounds, derived_key, TSXEncryptorPBKDF2KeySize); + int ret = CCKeyDerivationPBKDF(kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data)-1, (const uint8_t*)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1, TSXEncryptorPBKDF2Rounds, derived_key, TSXEncryptorPBKDF2KeySize); //NSLog(@"CCKeyDerivationPBKDF ret = %d; key: %@", ret, [NSData dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]); if (ret) diff --git a/client/iOS/Models/RDPSession.m b/client/iOS/Models/RDPSession.m index d43f27959..df924e29f 100644 --- a/client/iOS/Models/RDPSession.m +++ b/client/iOS/Models/RDPSession.m @@ -101,9 +101,12 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect" settings->FrameMarkerCommandEnabled = TRUE; settings->FrameAcknowledge = 10; } - - // enable NSCodec - settings->NSCodec = TRUE; + else + { + // enable NSCodec if remotefx is not used + settings->NSCodec = TRUE; + } + settings->BitmapCacheV3Enabled = TRUE; // Performance flags diff --git a/config.h.in b/config.h.in index c5071fb89..63de66d8d 100755 --- a/config.h.in +++ b/config.h.in @@ -68,6 +68,7 @@ #cmakedefine WITH_DEBUG_RFX #cmakedefine WITH_DEBUG_SCARD #cmakedefine WITH_DEBUG_SVC +#cmakedefine WITH_DEBUG_RDPEI #cmakedefine WITH_DEBUG_TIMEZONE #cmakedefine WITH_DEBUG_TRANSPORT #cmakedefine WITH_DEBUG_WND diff --git a/include/freerdp/client/rdpei.h b/include/freerdp/client/rdpei.h index a38c940dc..d7881b11c 100644 --- a/include/freerdp/client/rdpei.h +++ b/include/freerdp/client/rdpei.h @@ -66,9 +66,9 @@ typedef struct _rdpei_client_context RdpeiClientContext; typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context); typedef int (*pcRdpeiAddContact)(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact); -typedef int (*pcRdpeiContactBegin)(RdpeiClientContext* context, int externalId); -typedef int (*pcRdpeiContactUpdate)(RdpeiClientContext* context, int externalId); -typedef int (*pcRdpeiContactEnd)(RdpeiClientContext* context, int externalId); +typedef int (*pcRdpeiTouchBegin)(RdpeiClientContext* context, int externalId, int x, int y); +typedef int (*pcRdpeiTouchUpdate)(RdpeiClientContext* context, int externalId, int x, int y); +typedef int (*pcRdpeiTouchEnd)(RdpeiClientContext* context, int externalId, int x, int y); struct _rdpei_client_context { @@ -78,9 +78,10 @@ struct _rdpei_client_context pcRdpeiGetVersion GetVersion; pcRdpeiAddContact AddContact; - pcRdpeiContactBegin ContactBegin; - pcRdpeiContactUpdate ContactUpdate; - pcRdpeiContactEnd ContactEnd; + + pcRdpeiTouchBegin TouchBegin; + pcRdpeiTouchUpdate TouchUpdate; + pcRdpeiTouchEnd TouchEnd; }; #endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */ diff --git a/include/freerdp/crypto/ber.h b/include/freerdp/crypto/ber.h index 2f04c87e3..59e1cceea 100644 --- a/include/freerdp/crypto/ber.h +++ b/include/freerdp/crypto/ber.h @@ -54,10 +54,9 @@ FREERDP_API BOOL ber_read_length(wStream* s, int* length); FREERDP_API int ber_write_length(wStream* s, int length); -FREERDP_API int _ber_skip_length(int length); -FREERDP_API int ber_get_content_length(int length); +FREERDP_API int _ber_sizeof_length(int length); FREERDP_API BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc); -FREERDP_API void ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc); +FREERDP_API int ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc); FREERDP_API BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length); FREERDP_API void ber_write_application_tag(wStream* s, BYTE tag, int length); FREERDP_API BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length); @@ -65,21 +64,21 @@ FREERDP_API BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count); FREERDP_API void ber_write_enumerated(wStream* s, BYTE enumerated, BYTE count); FREERDP_API BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc); FREERDP_API int ber_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc); -FREERDP_API int ber_skip_contextual_tag(int length); +FREERDP_API int ber_sizeof_contextual_tag(int length); FREERDP_API BOOL ber_read_sequence_tag(wStream* s, int* length); FREERDP_API int ber_write_sequence_tag(wStream* s, int length); -FREERDP_API int ber_skip_sequence(int length); -FREERDP_API int ber_skip_sequence_tag(int length); +FREERDP_API int ber_sizeof_sequence(int length); +FREERDP_API int ber_sizeof_sequence_tag(int length); FREERDP_API BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding); -FREERDP_API void ber_write_octet_string(wStream* s, const BYTE* oct_str, int length); +FREERDP_API int ber_write_octet_string(wStream* s, const BYTE* oct_str, int length); FREERDP_API BOOL ber_read_octet_string_tag(wStream* s, int* length); FREERDP_API int ber_write_octet_string_tag(wStream* s, int length); -FREERDP_API int ber_skip_octet_string(int length); +FREERDP_API int ber_sizeof_octet_string(int length); FREERDP_API BOOL ber_read_BOOL(wStream* s, BOOL* value); FREERDP_API void ber_write_BOOL(wStream* s, BOOL value); FREERDP_API BOOL ber_read_integer(wStream* s, UINT32* value); FREERDP_API int ber_write_integer(wStream* s, UINT32 value); FREERDP_API BOOL ber_read_integer_length(wStream* s, int* length); -FREERDP_API int ber_skip_integer(UINT32 value); +FREERDP_API int ber_sizeof_integer(UINT32 value); #endif /* FREERDP_CRYPTO_BER_H */ diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index 258ee2ebb..c396679b3 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -62,7 +62,7 @@ FREERDP_API int tls_wait_read(rdpTls* tls); FREERDP_API int tls_wait_write(rdpTls* tls); FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname); -FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint); +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); FREERDP_API BOOL tls_print_error(char* func, SSL* connection, int value); diff --git a/include/freerdp/error.h b/include/freerdp/error.h index 27d54886a..8b0abd8f0 100644 --- a/include/freerdp/error.h +++ b/include/freerdp/error.h @@ -147,6 +147,7 @@ extern int connectErrorCode; #define MCSCONNECTINITIALERROR ERRORSTART + 7 #define TLSCONNECTERROR ERRORSTART + 8 #define AUTHENTICATIONERROR ERRORSTART + 9 +#define INSUFFICIENTPRIVILEGESERROR ERRORSTART + 10 #ifdef __cplusplus } diff --git a/include/freerdp/server/audin.h b/include/freerdp/server/audin.h index 9eb5f4be9..885c1674c 100644 --- a/include/freerdp/server/audin.h +++ b/include/freerdp/server/audin.h @@ -90,7 +90,15 @@ struct _audin_server_context psAudinServerReceiveSamples ReceiveSamples; }; +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API audin_server_context* audin_server_context_new(WTSVirtualChannelManager* vcm); FREERDP_API void audin_server_context_free(audin_server_context* context); +#ifdef __cplusplus +} +#endif + #endif /* FREERDP_CHANNEL_AUDIN_SERVER_H */ diff --git a/include/freerdp/server/rdpsnd.h b/include/freerdp/server/rdpsnd.h index 6349874fe..8b0c163c2 100644 --- a/include/freerdp/server/rdpsnd.h +++ b/include/freerdp/server/rdpsnd.h @@ -91,7 +91,15 @@ struct _rdpsnd_server_context psRdpsndServerActivated Activated; }; +#ifdef __cplusplus +extern "C" { +#endif + FREERDP_API rdpsnd_server_context* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm); FREERDP_API void rdpsnd_server_context_free(rdpsnd_server_context* context); +#ifdef __cplusplus +} +#endif + #endif /* FREERDP_CHANNEL_RDPSND_SERVER_H */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 8bdf4ef9f..1b3d6ca90 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1177,7 +1177,7 @@ struct rdp_settings /* NSCodec */ ALIGN64 BOOL NSCodec; /* 3712 */ ALIGN64 UINT32 NSCodecId; /* 3713 */ - ALIGN64 BOOL FrameAcknowledge; /* 3714 */ + ALIGN64 UINT32 FrameAcknowledge; /* 3714 */ UINT64 padding3776[3776 - 3715]; /* 3715 */ /* JPEG */ diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index a5f3f7ee7..04df95e42 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -2242,6 +2242,8 @@ BOOL rdp_read_multifragment_update_capability_set(wStream* s, UINT16 length, rdp return FALSE; Stream_Read_UINT32(s, multifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ + if (settings->RemoteFxCodec && settings->MultifragMaxRequestSize < multifragMaxRequestSize) + settings->MultifragMaxRequestSize = multifragMaxRequestSize; return TRUE; } diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 9b4643ccd..b28437ea5 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -109,12 +109,12 @@ BOOL freerdp_connect(freerdp* instance) if (!status) { fprintf(stderr, "freerdp_post_connect failed\n"); - + if (!connectErrorCode) { connectErrorCode = POSTCONNECTERROR; } - + return FALSE; } @@ -153,6 +153,11 @@ BOOL freerdp_connect(freerdp* instance) } } + if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) + { + connectErrorCode = INSUFFICIENTPRIVILEGESERROR; + } + if (!connectErrorCode) { connectErrorCode = UNDEFINEDCONNECTERROR; diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index d07ff21d6..0c4908afa 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -35,6 +35,8 @@ #include "rpc_client.h" +#include "../rdp.h" + wStream* rpc_client_fragment_pool_take(rdpRpc* rpc) { wStream* fragment = NULL; @@ -156,6 +158,15 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) if (StubLength == 4) { //fprintf(stderr, "Ignoring TsProxySendToServer Response\n"); + printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id); + + /* received a disconnect request from the server? */ + if (header->common.call_id == rpc->PipeCallId && header->common.pfc_flags & PFC_LAST_FRAG) + { + ((freerdp*)rpc->settings->instance)->context->rdp->disconnect = TRUE; + ((freerdp*)rpc->settings->instance)->context->rdp->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING; + } + rpc_client_fragment_pool_return(rpc, fragment); return 0; } diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 7d2b4a7fc..c6bb45dd1 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1371,8 +1371,14 @@ BOOL tsg_disconnect(rdpTsg* tsg) tsg->rpc->client->SynchronousReceive = TRUE; - if (!TsProxyCloseChannel(tsg, NULL)) - return FALSE; + /* if we are already in state pending (i.e. if a server initiated disconnect was issued) + we have to skip TsProxyCloseChannel - see Figure 13 in section 3.2.3 + */ + if (tsg->state != TSG_STATE_TUNNEL_CLOSE_PENDING) + { + if (!TsProxyCloseChannel(tsg, NULL)) + return FALSE; + } if (!TsProxyMakeTunnelCall(tsg, &tsg->TunnelContext, TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST, NULL, NULL)) return FALSE; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index cee59322a..e8a04af9b 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -240,6 +240,8 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings) Stream_Seek_UINT32(s); /* CodePage */ Stream_Read_UINT32(s, flags); /* flags */ + settings->AudioCapture = ((flags & RNS_INFO_AUDIOCAPTURE) ? TRUE : FALSE); + settings->AudioPlayback = ((flags & INFO_NOAUDIOPLAYBACK) ? FALSE : TRUE); settings->AutoLogonEnabled = ((flags & INFO_AUTOLOGON) ? TRUE : FALSE); settings->RemoteApplicationMode = ((flags & INFO_RAIL) ? TRUE : FALSE); settings->RemoteConsoleAudio = ((flags & INFO_REMOTECONSOLEAUDIO) ? TRUE : FALSE); diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 8ab89ebd1..2b4b71992 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -101,6 +101,9 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp); SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp); SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp); +#define ber_sizeof_sequence_octet_string(length) ber_sizeof_contextual_tag(ber_sizeof_octet_string(length)) + ber_sizeof_octet_string(length) +#define ber_write_sequence_octet_string(stream, context, value, length) ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), TRUE) + ber_write_octet_string(stream, value, length) + /** * Initialize NTLMSSP authentication module (client). * @param credssp @@ -112,7 +115,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) int length; freerdp* instance; rdpSettings* settings; - + settings = credssp->settings; instance = (freerdp*) settings->instance; @@ -238,7 +241,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) ZeroMemory(&output_buffer, sizeof(SecBuffer)); ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* + /* * from tspkg.dll: 0x00000132 * ISC_REQ_MUTUAL_AUTH * ISC_REQ_CONFIDENTIALITY @@ -456,7 +459,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) ZeroMemory(&output_buffer_desc, sizeof(SecBufferDesc)); ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes)); - /* + /* * from tspkg.dll: 0x00000112 * ASC_REQ_MUTUAL_AUTH * ASC_REQ_CONFIDENTIALITY @@ -783,24 +786,13 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) return SEC_E_OK; } -int credssp_skip_ts_password_creds(rdpCredssp* credssp) +int credssp_sizeof_ts_password_creds(rdpCredssp* credssp) { - int length; - int ts_password_creds_length = 0; + int length = 0; - length = ber_skip_octet_string(credssp->identity.DomainLength * 2); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; - - length = ber_skip_octet_string(credssp->identity.UserLength * 2); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; - - length = ber_skip_octet_string(credssp->identity.PasswordLength * 2); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; - - length = ber_skip_sequence(ts_password_creds_length); + length += ber_sizeof_sequence_octet_string(credssp->identity.DomainLength * 2); + length += ber_sizeof_sequence_octet_string(credssp->identity.UserLength * 2); + length += ber_sizeof_sequence_octet_string(credssp->identity.PasswordLength * 2); return length; } @@ -842,47 +834,36 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, wStream* s) credssp->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; } -void credssp_write_ts_password_creds(rdpCredssp* credssp, wStream* s) +int credssp_write_ts_password_creds(rdpCredssp* credssp, wStream* s) { - int length; - - length = credssp_skip_ts_password_creds(credssp); + int size = 0; + int innerSize = credssp_sizeof_ts_password_creds(credssp); /* TSPasswordCreds (SEQUENCE) */ - length = ber_get_content_length(length); - ber_write_sequence_tag(s, length); + + size += ber_write_sequence_tag(s, innerSize); /* [0] domainName (OCTET STRING) */ - ber_write_contextual_tag(s, 0, credssp->identity.DomainLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2); + size += ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->identity.Domain, credssp->identity.DomainLength * 2); /* [1] userName (OCTET STRING) */ - ber_write_contextual_tag(s, 1, credssp->identity.UserLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2); + size += ber_write_sequence_octet_string(s, 1, (BYTE*) credssp->identity.User, credssp->identity.UserLength * 2); /* [2] password (OCTET STRING) */ - ber_write_contextual_tag(s, 2, credssp->identity.PasswordLength * 2 + 2, TRUE); - ber_write_octet_string(s, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2); + size += ber_write_sequence_octet_string(s, 2, (BYTE*) credssp->identity.Password, credssp->identity.PasswordLength * 2); + + return size; } -int credssp_skip_ts_credentials(rdpCredssp* credssp) +int credssp_sizeof_ts_credentials(rdpCredssp* credssp) { - int length; - int ts_password_creds_length; - int ts_credentials_length = 0; + int size = 0; - length = ber_skip_integer(0); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; + size += ber_sizeof_integer(1); + size += ber_sizeof_contextual_tag(ber_sizeof_integer(1)); + size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp))); - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); - length = ber_skip_octet_string(ts_password_creds_length); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; - - length = ber_skip_sequence(ts_credentials_length); - - return length; + return size; } void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) @@ -909,28 +890,28 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) Stream_Free(s, FALSE); } -void credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) +int credssp_write_ts_credentials(rdpCredssp* credssp, wStream* s) { - int length; - int ts_password_creds_length; - - length = credssp_skip_ts_credentials(credssp); - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); + int size = 0; + int innerSize = credssp_sizeof_ts_credentials(credssp); + int passwordSize; /* TSCredentials (SEQUENCE) */ - length = ber_get_content_length(length); - length -= ber_write_sequence_tag(s, length); + size += ber_write_sequence_tag(s, innerSize); /* [0] credType (INTEGER) */ - length -= ber_write_contextual_tag(s, 0, 3, TRUE); - length -= ber_write_integer(s, 1); + size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), TRUE); + size += ber_write_integer(s, 1); /* [1] credentials (OCTET STRING) */ - length -= 1; - length -= ber_write_contextual_tag(s, 1, length, TRUE); - length -= ber_write_octet_string_tag(s, ts_password_creds_length); - credssp_write_ts_password_creds(credssp, s); + passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)); + + size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), TRUE); + size += ber_write_octet_string_tag(s, passwordSize); + size += credssp_write_ts_password_creds(credssp, s); + + return size; } /** @@ -943,7 +924,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) wStream* s; int length; - length = credssp_skip_ts_credentials(credssp); + length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp)); sspi_SecBufferAlloc(&credssp->ts_credentials, length); s = Stream_New(credssp->ts_credentials.pvBuffer, length); @@ -1029,41 +1010,40 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) return SEC_E_OK; } -int credssp_skip_nego_token(int length) +int credssp_sizeof_nego_token(int length) { - length = der_skip_octet_string(length); - length += der_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_nego_tokens(int length) +int credssp_sizeof_nego_tokens(int length) { - length = credssp_skip_nego_token(length); - length += der_skip_sequence_tag(length); - length += der_skip_sequence_tag(length); - length += der_skip_contextual_tag(length); + length = credssp_sizeof_nego_token(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_pub_key_auth(int length) +int credssp_sizeof_pub_key_auth(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_auth_info(int length) +int credssp_sizeof_auth_info(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_ts_request(int length) +int credssp_sizeof_ts_request(int length) { - length += ber_skip_integer(2); - length += ber_skip_contextual_tag(3); - length += der_skip_sequence_tag(length); + length += ber_sizeof_integer(2); + length += ber_sizeof_contextual_tag(3); return length; } @@ -1081,18 +1061,18 @@ void credssp_send(rdpCredssp* credssp) int pub_key_auth_length; int auth_info_length; - nego_tokens_length = (credssp->negoToken.cbBuffer > 0) ? credssp_skip_nego_tokens(credssp->negoToken.cbBuffer) : 0; - pub_key_auth_length = (credssp->pubKeyAuth.cbBuffer > 0) ? credssp_skip_pub_key_auth(credssp->pubKeyAuth.cbBuffer) : 0; - auth_info_length = (credssp->authInfo.cbBuffer > 0) ? credssp_skip_auth_info(credssp->authInfo.cbBuffer) : 0; + nego_tokens_length = (credssp->negoToken.cbBuffer > 0) ? credssp_sizeof_nego_tokens(credssp->negoToken.cbBuffer) : 0; + pub_key_auth_length = (credssp->pubKeyAuth.cbBuffer > 0) ? credssp_sizeof_pub_key_auth(credssp->pubKeyAuth.cbBuffer) : 0; + auth_info_length = (credssp->authInfo.cbBuffer > 0) ? credssp_sizeof_auth_info(credssp->authInfo.cbBuffer) : 0; length = nego_tokens_length + pub_key_auth_length + auth_info_length; - ts_request_length = credssp_skip_ts_request(length); - s = Stream_New(NULL, ts_request_length); + ts_request_length = credssp_sizeof_ts_request(length); + + s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length)); /* TSRequest */ - length = der_get_content_length(ts_request_length); - der_write_sequence_tag(s, length); /* SEQUENCE */ + ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */ /* [0] version */ ber_write_contextual_tag(s, 0, 3, TRUE); @@ -1102,27 +1082,31 @@ void credssp_send(rdpCredssp* credssp) if (nego_tokens_length > 0) { length = nego_tokens_length; - length -= der_write_contextual_tag(s, 1, der_get_content_length(length), TRUE); /* NegoData */ - length -= der_write_sequence_tag(s, der_get_content_length(length)); /* SEQUENCE OF NegoDataItem */ - length -= der_write_sequence_tag(s, der_get_content_length(length)); /* NegoDataItem */ - length -= der_write_contextual_tag(s, 0, der_get_content_length(length), TRUE); /* [0] negoToken */ - der_write_octet_string(s, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */ + + length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))), TRUE); /* NegoData */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer))); /* SEQUENCE OF NegoDataItem */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(credssp->negoToken.cbBuffer)); /* NegoDataItem */ + length -= ber_write_sequence_octet_string(s, 0, (BYTE*) credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); /* OCTET STRING */ + + // assert length == 0 } /* [2] authInfo (OCTET STRING) */ if (auth_info_length > 0) { length = auth_info_length; - length -= ber_write_contextual_tag(s, 2, ber_get_content_length(length), TRUE); - ber_write_octet_string(s, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); + length -= ber_write_sequence_octet_string(s, 2, credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); + + // assert length == 0 } /* [3] pubKeyAuth (OCTET STRING) */ if (pub_key_auth_length > 0) { length = pub_key_auth_length; - length -= ber_write_contextual_tag(s, 3, ber_get_content_length(length), TRUE); - ber_write_octet_string(s, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); + length -= ber_write_sequence_octet_string(s, 3, credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); + + // assert length == 0 } Stream_SealLength(s); diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 6fef8dff2..e5cc520b7 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -831,11 +831,16 @@ BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* d return TRUE; } +int update_approximate_dstblt_order(ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt) +{ + return 32; +} + BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt) { orderInfo->fieldFlags = 0; - Stream_EnsureRemainingCapacity(s, 64); + Stream_EnsureRemainingCapacity(s, update_approximate_dstblt_order(orderInfo, dstblt)); orderInfo->fieldFlags |= ORDER_FIELD_01; update_write_coord(s, dstblt->nLeftRect); @@ -867,11 +872,16 @@ BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* p return update_read_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7); } +int update_approximate_patblt_order(ORDER_INFO* orderInfo, PATBLT_ORDER* patblt) +{ + return 32; +} + BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt) { orderInfo->fieldFlags = 0; - Stream_EnsureRemainingCapacity(s, 64); + Stream_EnsureRemainingCapacity(s, update_approximate_patblt_order(orderInfo, patblt)); orderInfo->fieldFlags |= ORDER_FIELD_01; update_write_coord(s, patblt->nLeftRect); @@ -917,11 +927,16 @@ BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* s return TRUE; } +int update_approximate_scrblt_order(ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt) +{ + return 32; +} + BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt) { orderInfo->fieldFlags = 0; - Stream_EnsureRemainingCapacity(s, 32); + Stream_EnsureRemainingCapacity(s, update_approximate_scrblt_order(orderInfo, scrblt)); orderInfo->fieldFlags |= ORDER_FIELD_01; update_write_coord(s, scrblt->nLeftRect); @@ -986,11 +1001,16 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return TRUE; } +int update_approximate_opaque_rect_order(ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect) +{ + return 32; +} + BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect) { BYTE byte; - Stream_EnsureRemainingCapacity(s, 32); + Stream_EnsureRemainingCapacity(s, update_approximate_opaque_rect_order(orderInfo, opaque_rect)); orderInfo->fieldFlags = 0; @@ -1025,9 +1045,15 @@ BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NI ORDER_FIELD_COORD(3, draw_nine_grid->srcRight); ORDER_FIELD_COORD(4, draw_nine_grid->srcBottom); ORDER_FIELD_UINT16(5, draw_nine_grid->bitmapId); + return TRUE; } +int update_approximate_draw_nine_grid_order(ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid) +{ + return 32; +} + BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid) { return TRUE; @@ -1046,12 +1072,20 @@ BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DST { if (Stream_GetRemainingLength(s) < 2) return FALSE; + Stream_Read_UINT16(s, multi_dstblt->cbData); + return update_read_delta_rects(s, multi_dstblt->rectangles, multi_dstblt->numRectangles); } + return TRUE; } +int update_approximate_multi_dstblt_order(ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt) +{ + return 32; +} + BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt) { return TRUE; @@ -1076,13 +1110,20 @@ BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PAT { if (Stream_GetRemainingLength(s) < 2) return FALSE; + Stream_Read_UINT16(s, multi_patblt->cbData); + if (!update_read_delta_rects(s, multi_patblt->rectangles, multi_patblt->numRectangles)) return FALSE; } return TRUE; } +int update_approximate_multi_patblt_order(ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt) +{ + return 32; +} + BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt) { return TRUE; @@ -1103,12 +1144,18 @@ BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCR { if (Stream_GetRemainingLength(s) < 2) return FALSE; + Stream_Read_UINT16(s, multi_scrblt->cbData); return update_read_delta_rects(s, multi_scrblt->rectangles, multi_scrblt->numRectangles); } return TRUE; } +int update_approximate_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt) +{ + return 32; +} + BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt) { return TRUE; @@ -1127,6 +1174,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte; } @@ -1135,6 +1183,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8); } @@ -1143,6 +1192,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, byte); multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16); } @@ -1156,9 +1206,15 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT Stream_Read_UINT16(s, multi_opaque_rect->cbData); return update_read_delta_rects(s, multi_opaque_rect->rectangles, multi_opaque_rect->numRectangles); } + return TRUE; } +int update_approximate_multi_opaque_rect_order(ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + return 32; +} + BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) { return TRUE; @@ -1177,9 +1233,15 @@ BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, M { FIELD_SKIP_BUFFER16(s, multi_draw_nine_grid->cbData); } + return TRUE; } +int update_approximate_multi_draw_nine_grid_order(ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) +{ + return 32; +} + BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) { return TRUE; @@ -1200,9 +1262,14 @@ BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* return TRUE; } +int update_approximate_line_to_order(ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to) +{ + return 32; +} + BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to) { - Stream_EnsureRemainingCapacity(s, 32); + Stream_EnsureRemainingCapacity(s, update_approximate_line_to_order(orderInfo, line_to)); orderInfo->fieldFlags = 0; @@ -1267,6 +1334,11 @@ BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDE return TRUE; } +int update_approximate_polyline_order(ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline) +{ + return 32; +} + BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline) { return TRUE; @@ -1290,11 +1362,16 @@ BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* m return TRUE; } +int update_approximate_memblt_order(ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt) +{ + return 32; +} + BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt) { UINT16 cacheId; - Stream_EnsureRemainingCapacity(s, 32); + Stream_EnsureRemainingCapacity(s, update_approximate_memblt_order(orderInfo, memblt)); cacheId = (memblt->cacheId & 0xFF) | ((memblt->colorIndex & 0xFF) << 8); @@ -1347,9 +1424,15 @@ BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* ORDER_FIELD_UINT16(16, mem3blt->cacheIndex); mem3blt->colorIndex = (mem3blt->cacheId >> 8); mem3blt->cacheId = (mem3blt->cacheId & 0xFF); + return TRUE; } +int update_approximate_mem3blt_order(ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt) +{ + return 32; +} + BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt) { return TRUE; @@ -1366,6 +1449,11 @@ BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMA return TRUE; } +int update_approximate_save_bitmap_order(ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap) +{ + return 32; +} + BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap) { return TRUE; @@ -1404,18 +1492,23 @@ BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDE if (Stream_GetRemainingLength(s) < glyph_index->cbData) return FALSE; - memcpy(glyph_index->data, Stream_Pointer(s), glyph_index->cbData); + CopyMemory(glyph_index->data, Stream_Pointer(s), glyph_index->cbData); Stream_Seek(s, glyph_index->cbData); } return TRUE; } +int update_approximate_glyph_index_order(ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index) +{ + return 64; +} + BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index) { orderInfo->fieldFlags = 0; - Stream_EnsureRemainingCapacity(s, 64); + Stream_EnsureRemainingCapacity(s, update_approximate_glyph_index_order(orderInfo, glyph_index)); orderInfo->fieldFlags |= ORDER_FIELD_01; Stream_Write_UINT8(s, glyph_index->cacheId); @@ -1500,16 +1593,24 @@ BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, fast_index->cbData); if (Stream_GetRemainingLength(s) < fast_index->cbData) return FALSE; - memcpy(fast_index->data, Stream_Pointer(s), fast_index->cbData); + + CopyMemory(fast_index->data, Stream_Pointer(s), fast_index->cbData); Stream_Seek(s, fast_index->cbData); } + return TRUE; } +int update_approximate_fast_index_order(ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index) +{ + return 32; +} + BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index) { return TRUE; @@ -1545,7 +1646,7 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ if (Stream_GetRemainingLength(s) < fast_glyph->cbData) return FALSE; - memcpy(fast_glyph->data, Stream_Pointer(s), fast_glyph->cbData); + CopyMemory(fast_glyph->data, Stream_Pointer(s), fast_glyph->cbData); phold = Stream_Pointer(s); if (!Stream_SafeSeek(s, 1)) @@ -1575,9 +1676,15 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ Stream_Pointer(s) = phold + fast_glyph->cbData; } + return TRUE; } +int update_approximate_fast_glyph_order(ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph) +{ + return 32; +} + BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph) { return TRUE; @@ -1596,18 +1703,25 @@ BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, polygon_sc->cbData); - if (polygon_sc->points == NULL) + if (!polygon_sc->points) polygon_sc->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_sc->numPoints); else polygon_sc->points = (DELTA_POINT*) realloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints); return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart); } + return TRUE; } +int update_approximate_polygon_sc_order(ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc) +{ + return 32; +} + BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc) { return TRUE; @@ -1631,9 +1745,10 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ { if (Stream_GetRemainingLength(s) < 1) return FALSE; + Stream_Read_UINT8(s, polygon_cb->cbData); - if (polygon_cb->points == NULL) + if (!polygon_cb->points) polygon_cb->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_cb->numPoints); else polygon_cb->points = (DELTA_POINT*) realloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints); @@ -1644,9 +1759,15 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE; polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F); + return TRUE; } +int update_approximate_polygon_cb_order(ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb) +{ + return 32; +} + BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb) { return TRUE; @@ -1664,6 +1785,11 @@ BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ return TRUE; } +int update_approximate_ellipse_sc_order(ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) +{ + return 32; +} + BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) { return TRUE; @@ -1682,6 +1808,11 @@ BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ return update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8); } +int update_approximate_ellipse_cb_order(ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb) +{ + return 32; +} + BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb) { return TRUE; @@ -1735,11 +1866,16 @@ BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap return TRUE; } +int update_approximate_cache_bitmap_order(CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags) +{ + return 64 + cache_bitmap->bitmapLength; +} + BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags) { *flags = NO_BITMAP_COMPRESSION_HDR; - Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap->bitmapLength); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_order(cache_bitmap, compressed, flags)); if ((*flags & NO_BITMAP_COMPRESSION_HDR) == 0) cache_bitmap->bitmapLength += 8; @@ -1845,11 +1981,16 @@ BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_ return TRUE; } +int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags) +{ + return 64 + cache_bitmap_v2->bitmapLength; +} + BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags) { BYTE bitsPerPixelId; - Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap_v2->bitmapLength); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_v2_order(cache_bitmap_v2, compressed, flags)); bitsPerPixelId = BPP_CBR2[cache_bitmap_v2->bitmapBpp]; @@ -1947,6 +2088,12 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_ return TRUE; } +int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags) +{ + BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData; + return 64 + bitmapData->length; +} + BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags) { BYTE bitsPerPixelId; @@ -1954,7 +2101,7 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache bitmapData = &cache_bitmap_v3->bitmapData; - Stream_EnsureRemainingCapacity(s, 64 + bitmapData->length); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_v3_order(cache_bitmap_v3, flags)); bitsPerPixelId = BPP_CBR23[cache_bitmap_v3->bpp]; @@ -2009,6 +2156,11 @@ BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* ca return TRUE; } +int update_approximate_cache_color_table_order(CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags) +{ + return 16 + (256 * 4); +} + BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags) { int i; @@ -2017,7 +2169,7 @@ BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* c if (cache_color_table->numberColors != 256) return FALSE; - Stream_EnsureRemainingCapacity(s, 16 + (256 * 4)); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_color_table_order(cache_color_table, flags)); Stream_Write_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */ Stream_Write_UINT16(s, cache_color_table->numberColors); /* numberColors (2 bytes) */ @@ -2077,13 +2229,18 @@ BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_or return TRUE; } +int update_approximate_cache_glyph_order(CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags) +{ + return 2 + cache_glyph->cGlyphs * 32; +} + BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags) { int i; INT16 lsi16; GLYPH_DATA* glyph; - Stream_EnsureRemainingCapacity(s, 2 + cache_glyph->cGlyphs * 32); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_glyph_order(cache_glyph, flags)); Stream_Write_UINT8(s, cache_glyph->cacheId); /* cacheId (1 byte) */ Stream_Write_UINT8(s, cache_glyph->cGlyphs); /* cGlyphs (1 byte) */ @@ -2161,12 +2318,17 @@ BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_gl return TRUE; } +int update_approximate_cache_glyph_v2_order(CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags) +{ + return 8 + cache_glyph_v2->cGlyphs * 32; +} + BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags) { int i; GLYPH_DATA_V2* glyph; - Stream_EnsureRemainingCapacity(s, cache_glyph_v2->cGlyphs * 32); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_glyph_v2_order(cache_glyph_v2, flags)); *flags = (cache_glyph_v2->cacheId & 0x000F) | ((cache_glyph_v2->flags & 0x000F) << 4) | @@ -2312,6 +2474,11 @@ BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, U return TRUE; } +int update_approximate_cache_brush_order(CACHE_BRUSH_ORDER* cache_brush, UINT16* flags) +{ + return 64; +} + BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, UINT16* flags) { int i; @@ -2319,7 +2486,7 @@ BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, BYTE iBitmapFormat; BOOL compressed = FALSE; - Stream_EnsureRemainingCapacity(s, 64); + Stream_EnsureRemainingCapacity(s, update_approximate_cache_brush_order(cache_brush, flags)); iBitmapFormat = BPP_BMF[cache_brush->bpp]; @@ -2430,6 +2597,12 @@ BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITM return TRUE; } +int update_approximate_create_offscreen_bitmap_order(CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + OFFSCREEN_DELETE_LIST* deleteList = &(create_offscreen_bitmap->deleteList); + return 8 + deleteList->cIndices * 2; +} + BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) { UINT16 flags; @@ -2438,7 +2611,7 @@ BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BIT deleteList = &(create_offscreen_bitmap->deleteList); - Stream_EnsureRemainingCapacity(s, 8 + deleteList->cIndices * 2); + Stream_EnsureRemainingCapacity(s, update_approximate_create_offscreen_bitmap_order(create_offscreen_bitmap)); flags = create_offscreen_bitmap->id & 0x7FFF; @@ -2477,9 +2650,14 @@ BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_s return TRUE; } +int update_approximate_switch_surface_order(SWITCH_SURFACE_ORDER* switch_surface) +{ + return 2; +} + BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface) { - Stream_EnsureRemainingCapacity(s, 2); + Stream_EnsureRemainingCapacity(s, update_approximate_switch_surface_order(switch_surface)); Stream_Write_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ @@ -2503,6 +2681,7 @@ BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITM Stream_Read_UINT16(s, nineGridInfo->ulTopHeight); /* ulTopHeight (2 bytes) */ Stream_Read_UINT16(s, nineGridInfo->ulBottomHeight); /* ulBottomHeight (2 bytes) */ update_read_colorref(s, &nineGridInfo->crTransparent); /* crTransparent (4 bytes) */ + return TRUE; } @@ -2510,7 +2689,9 @@ BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker { if (Stream_GetRemainingLength(s) < 4) return FALSE; + Stream_Read_UINT32(s, frame_marker->action); /* action (4 bytes) */ + return TRUE; } diff --git a/libfreerdp/core/orders.h b/libfreerdp/core/orders.h index 7860694fa..d4d161b8b 100644 --- a/libfreerdp/core/orders.h +++ b/libfreerdp/core/orders.h @@ -195,87 +195,156 @@ BOOL update_read_bounds(wStream* s, rdpBounds* bounds); BOOL update_write_bounds(wStream* s, ORDER_INFO* orderInfo); BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); +int update_approximate_dstblt_order(ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); + BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); +int update_approximate_patblt_order(ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); + BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); +int update_approximate_scrblt_order(ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); + BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); +int update_approximate_opaque_rect_order(ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); + BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); +int update_approximate_draw_nine_grid_order(ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); + BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); +int update_approximate_multi_dstblt_order(ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); + BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); +int update_approximate_multi_patblt_order(ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); + BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); +int update_approximate_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); + BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); +int update_approximate_multi_opaque_rect_order(ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); + BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); +int update_approximate_multi_draw_nine_grid_order(ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); + BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); +int update_approximate_line_to_order(ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); + BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); +int update_approximate_polyline_order(ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); + BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); +int update_approximate_memblt_order(ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); + BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); +int update_approximate_mem3blt_order(ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); + BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); +int update_approximate_save_bitmap_order(ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); + BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); +int update_approximate_glyph_index_order(ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); + BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); +int update_approximate_fast_index_order(ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); + BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); +int update_approximate_fast_glyph_order(ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); + BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); +int update_approximate_polygon_sc_order(ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); + BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); +int update_approximate_polygon_cb_order(ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); + BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); +int update_approximate_ellipse_sc_order(ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); + BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); +int update_approximate_ellipse_cb_order(ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16 flags); +int update_approximate_cache_bitmap_order(CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags); BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16* flags); + BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16 flags); +int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags); BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16* flags); + BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16 flags); +int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags); BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16* flags); + BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16 flags); +int update_approximate_cache_color_table_order(CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags); BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16* flags); + BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16 flags); +int update_approximate_cache_glyph_order(CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags); BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16* flags); + BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags); +int update_approximate_cache_glyph_v2_order(CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags); BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags); + BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16 flags); +int update_approximate_cache_brush_order(CACHE_BRUSH_ORDER* cache_brush, UINT16* flags); BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16* flags); BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); +int update_approximate_create_offscreen_bitmap_order(CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); + BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface); +int update_approximate_switch_surface_order(SWITCH_SURFACE_ORDER* switch_surface); BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface); + BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); BOOL update_write_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); + BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker); BOOL update_write_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker); + BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); BOOL update_write_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); + BOOL update_read_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next); BOOL update_write_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next); + BOOL update_read_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); BOOL update_write_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); + BOOL update_read_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); BOOL update_write_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); + BOOL update_read_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); BOOL update_write_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); + BOOL update_read_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); BOOL update_write_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); + BOOL update_read_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); BOOL update_write_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); + BOOL update_read_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); BOOL update_write_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 5e61a9f17..40e066747 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -138,6 +138,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) if(Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, client->ack_frame_id); + IFCALL(client->update->SurfaceFrameAcknowledge, client->update->context, client->ack_frame_id); break; case DATA_PDU_TYPE_REFRESH_RECT: diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index a9331106a..a0ad86406 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -120,6 +120,9 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port) UINT32 option_value; socklen_t option_len; + if (hostname == NULL) + return FALSE; + if (hostname[0] == '/') { tcp->sockfd = freerdp_uds_connect(hostname); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 9984791d2..59ed98a8b 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -487,6 +487,45 @@ static void update_end_paint(rdpContext* context) Stream_Free(s, TRUE); } +static void update_flush(rdpContext* context) +{ + rdpUpdate* update = context->update; + + if (update->numberOrders > 0) + { + update->EndPaint(context); + update->BeginPaint(context); + } +} + +static void update_force_flush(rdpContext* context) +{ + rdpUpdate* update = context->update; + + if (update->numberOrders > 0) + { + update->EndPaint(context); + update->BeginPaint(context); + } +} + +static BOOL update_check_flush(rdpContext* context, int size) +{ + wStream* s; + rdpUpdate* update = context->update; + rdpSettings* settings = context->settings; + + s = update->us; + + if (Stream_GetPosition(s) + size + 256 >= settings->MultifragMaxRequestSize) + { + update_flush(context); + return TRUE; + } + + return FALSE; +} + static void update_set_bounds(rdpContext* context, rdpBounds* bounds) { rdpUpdate* update = context->update; @@ -743,6 +782,8 @@ static void update_send_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_DSTBLT); + update_check_flush(context, headerLength + update_approximate_dstblt_order(&orderInfo, dstblt)); + s = update->us; offset = Stream_GetPosition(s); @@ -765,6 +806,8 @@ static void update_send_patblt(rdpContext* context, PATBLT_ORDER* patblt) headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_PATBLT); + update_check_flush(context, headerLength + update_approximate_patblt_order(&orderInfo, patblt)); + s = update->us; offset = Stream_GetPosition(s); @@ -787,6 +830,8 @@ static void update_send_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_SCRBLT); + update_check_flush(context, headerLength + update_approximate_scrblt_order(&orderInfo, scrblt)); + s = update->us; offset = Stream_GetPosition(s); @@ -809,6 +854,8 @@ static void update_send_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaq headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_OPAQUE_RECT); + update_check_flush(context, headerLength + update_approximate_opaque_rect_order(&orderInfo, opaque_rect)); + s = update->us; offset = Stream_GetPosition(s); @@ -831,6 +878,8 @@ static void update_send_line_to(rdpContext* context, LINE_TO_ORDER* line_to) headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_LINE_TO); + update_check_flush(context, headerLength + update_approximate_line_to_order(&orderInfo, line_to)); + s = update->us; offset = Stream_GetPosition(s); @@ -853,6 +902,8 @@ static void update_send_memblt(rdpContext* context, MEMBLT_ORDER* memblt) headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_MEMBLT); + update_check_flush(context, headerLength + update_approximate_memblt_order(&orderInfo, memblt)); + s = update->us; offset = Stream_GetPosition(s); @@ -875,6 +926,8 @@ static void update_send_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyp headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_GLYPH_INDEX); + update_check_flush(context, headerLength + update_approximate_glyph_index_order(&orderInfo, glyph_index)); + s = update->us; offset = Stream_GetPosition(s); @@ -903,6 +956,8 @@ static void update_send_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* ca orderType = cache_bitmap->compressed ? ORDER_TYPE_CACHE_BITMAP_COMPRESSED : ORDER_TYPE_BITMAP_UNCOMPRESSED; + update_check_flush(context, headerLength + update_approximate_cache_bitmap_order(cache_bitmap, cache_bitmap->compressed, &extraFlags)); + s = update->us; bm = Stream_GetPosition(s); @@ -922,13 +977,6 @@ static void update_send_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* ca Stream_SetPosition(s, em); update->numberOrders++; - - /** - * temporary workaround to avoid PDUs exceeding maximum size - */ - - update->EndPaint(context); - update->BeginPaint(context); } static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) @@ -941,12 +989,16 @@ static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + extraFlags = 0; headerLength = 6; orderType = cache_bitmap_v2->compressed ? ORDER_TYPE_BITMAP_COMPRESSED_V2 : ORDER_TYPE_BITMAP_UNCOMPRESSED_V2; + update_check_flush(context, headerLength + update_approximate_cache_bitmap_v2_order(cache_bitmap_v2, cache_bitmap_v2->compressed, &extraFlags)); + s = update->us; bm = Stream_GetPosition(s); @@ -967,12 +1019,7 @@ static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD update->numberOrders++; - /** - * temporary workaround to avoid PDUs exceeding maximum size - */ - - update->EndPaint(context); - update->BeginPaint(context); + update_force_flush(context); } static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3) @@ -985,10 +1032,14 @@ static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORD INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + extraFlags = 0; headerLength = 6; orderType = ORDER_TYPE_BITMAP_COMPRESSED_V3; + update_check_flush(context, headerLength + update_approximate_cache_bitmap_v3_order(cache_bitmap_v3, &extraFlags)); + s = update->us; bm = Stream_GetPosition(s); @@ -1009,12 +1060,7 @@ static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORD update->numberOrders++; - /** - * temporary workaround to avoid PDUs exceeding maximum size - */ - - update->EndPaint(context); - update->BeginPaint(context); + update_force_flush(context); } static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table) @@ -1026,9 +1072,13 @@ static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + flags = 0; headerLength = 6; + update_check_flush(context, headerLength + update_approximate_cache_color_table_order(cache_color_table, &flags)); + s = update->us; bm = Stream_GetPosition(s); @@ -1048,6 +1098,8 @@ static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph) @@ -1059,9 +1111,13 @@ static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cach INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + flags = 0; headerLength = 6; + update_check_flush(context, headerLength + update_approximate_cache_glyph_order(cache_glyph, &flags)); + s = update->us; bm = Stream_GetPosition(s); @@ -1081,6 +1137,8 @@ static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cach Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2) @@ -1092,9 +1150,13 @@ static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + flags = 0; headerLength = 6; + update_check_flush(context, headerLength + update_approximate_cache_glyph_v2_order(cache_glyph_v2, &flags)); + s = update->us; bm = Stream_GetPosition(s); @@ -1114,6 +1176,8 @@ static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) @@ -1125,9 +1189,13 @@ static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cach INT16 orderLength; rdpUpdate* update = context->update; + update_force_flush(context); + flags = 0; headerLength = 6; + update_check_flush(context, headerLength + update_approximate_cache_brush_order(cache_brush, &flags)); + s = update->us; bm = Stream_GetPosition(s); @@ -1147,6 +1215,8 @@ static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cach Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) @@ -1158,10 +1228,14 @@ static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREAT int headerLength; rdpUpdate* update = context->update; + update_force_flush(context); + headerLength = 1; orderType = ORDER_TYPE_CREATE_OFFSCREEN_BITMAP; controlFlags = ORDER_SECONDARY | (orderType << 2); + update_check_flush(context, headerLength + update_approximate_create_offscreen_bitmap_order(create_offscreen_bitmap)); + s = update->us; bm = Stream_GetPosition(s); @@ -1176,6 +1250,8 @@ static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREAT Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface) @@ -1187,10 +1263,14 @@ static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE int headerLength; rdpUpdate* update = context->update; + update_force_flush(context); + headerLength = 1; orderType = ORDER_TYPE_SWITCH_SURFACE; controlFlags = ORDER_SECONDARY | (orderType << 2); + update_check_flush(context, headerLength + update_approximate_switch_surface_order(switch_surface)); + s = update->us; bm = Stream_GetPosition(s); @@ -1205,6 +1285,8 @@ static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE Stream_SetPosition(s, em); update->numberOrders++; + + update_force_flush(context); } static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index 3809f6dfc..38d98f411 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -30,7 +30,7 @@ BOOL ber_read_length(wStream* s, int* length) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -38,7 +38,7 @@ BOOL ber_read_length(wStream* s, int* length) { byte &= ~(0x80); - if(Stream_GetRemainingLength(s) < byte) + if (Stream_GetRemainingLength(s) < byte) return FALSE; if (byte == 1) @@ -63,33 +63,29 @@ BOOL ber_read_length(wStream* s, int* length) int ber_write_length(wStream* s, int length) { - if (length > 0x7F) + if (length > 0xFF) { - Stream_Write_UINT8(s, 0x82); + Stream_Write_UINT8(s, 0x80 ^ 2); Stream_Write_UINT16_BE(s, length); return 3; } - else + if (length > 0x7F) { + Stream_Write_UINT8(s, 0x80 ^ 1); Stream_Write_UINT8(s, length); - return 1; + return 2; } + Stream_Write_UINT8(s, length); + return 1; } -int _ber_skip_length(int length) +int _ber_sizeof_length(int length) { - if (length > 0x80) + if (length > 0xFF) return 3; - else - return 1; -} - -int ber_get_content_length(int length) -{ - if (length > 0x81) - return length - 4; - else - return length - 2; + if (length > 0x7F) + return 2; + return 1; } /** @@ -103,7 +99,7 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -120,9 +116,10 @@ BOOL ber_read_universal_tag(wStream* s, BYTE tag, BOOL pc) * @param pc primitive (FALSE) or constructed (TRUE) */ -void ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) +int ber_write_universal_tag(wStream* s, BYTE tag, BOOL pc) { Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); + return 1; } /** @@ -138,14 +135,14 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) if (tag > 30) { - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) return FALSE; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -156,7 +153,7 @@ BOOL ber_read_application_tag(wStream* s, BYTE tag, int* length) } else { - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -195,7 +192,7 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -211,19 +208,19 @@ BOOL ber_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc) int ber_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc) { Stream_Write_UINT8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_contextual_tag(int length) +int ber_sizeof_contextual_tag(int length) { - return _ber_skip_length(length) + 1; + return 1 + _ber_sizeof_length(length); } BOOL ber_read_sequence_tag(wStream* s, int* length) { BYTE byte; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, byte); @@ -242,24 +239,24 @@ BOOL ber_read_sequence_tag(wStream* s, int* length) int ber_write_sequence_tag(wStream* s, int length) { Stream_Write_UINT8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_sequence(int length) +int ber_sizeof_sequence(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } -int ber_skip_sequence_tag(int length) +int ber_sizeof_sequence_tag(int length) { - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } BOOL ber_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { int length; - if(!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || + if (!ber_read_universal_tag(s, BER_TAG_ENUMERATED, FALSE) || !ber_read_length(s, &length)) return FALSE; @@ -284,11 +281,11 @@ void ber_write_enumerated(wStream* s, BYTE enumerated, BYTE count) BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) { - if(!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || + if (!ber_read_universal_tag(s, BER_TAG_BIT_STRING, FALSE) || !ber_read_length(s, length)) return FALSE; - if(Stream_GetRemainingLength(s) < 1) + if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Read_UINT8(s, *padding); return TRUE; @@ -301,11 +298,14 @@ BOOL ber_read_bit_string(wStream* s, int* length, BYTE* padding) * @param length string length */ -void ber_write_octet_string(wStream* s, const BYTE* oct_str, int length) +int ber_write_octet_string(wStream* s, const BYTE* oct_str, int length) { - ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); - ber_write_length(s, length); + int size = 0; + size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); + size += ber_write_length(s, length); Stream_Write(s, oct_str, length); + size += length; + return size; } BOOL ber_read_octet_string_tag(wStream* s, int* length) @@ -319,12 +319,12 @@ int ber_write_octet_string_tag(wStream* s, int length) { ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); ber_write_length(s, length); - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } -int ber_skip_octet_string(int length) +int ber_sizeof_octet_string(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } /** @@ -419,50 +419,56 @@ BOOL ber_read_integer(wStream* s, UINT32* value) int ber_write_integer(wStream* s, UINT32 value) { - ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); - - if (value <= 0xFF) + if (value < 0x80) { + ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 1); Stream_Write_UINT8(s, value); - return 2; - } - else if (value < 0xFF80) - { - ber_write_length(s, 2); - Stream_Write_UINT16_BE(s, value); return 3; } - else if (value < 0xFF8000) + else if (value < 0x8000) { + ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); + ber_write_length(s, 2); + Stream_Write_UINT16_BE(s, value); + return 4; + } + else if (value < 0x800000) + { + ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 3); Stream_Write_UINT8(s, (value >> 16)); Stream_Write_UINT16_BE(s, (value & 0xFFFF)); - return 4; + return 5; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x80000000) { + ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); ber_write_length(s, 4); Stream_Write_UINT32_BE(s, value); - return 5; + return 6; } return 0; } -int ber_skip_integer(UINT32 value) +int ber_sizeof_integer(UINT32 value) { - if (value <= 0xFF) + if (value < 0x80) { - return _ber_skip_length(1) + 2; + return 3; } - else if (value <= 0xFFFF) + else if (value < 0x8000) { - return _ber_skip_length(2) + 3; + return 4; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x800000) { - return _ber_skip_length(4) + 5; + return 5; + } + else if (value < 0x80000000) + { + return 6; } return 0; diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index 5bfaa5c42..3d86944ae 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -34,12 +34,14 @@ #include static const char certificate_store_dir[] = "certs"; +static const char certificate_server_dir[] = "server"; static const char certificate_known_hosts_file[] = "known_hosts"; #include void certificate_store_init(rdpCertificateStore* certificate_store) { + char* server_path; rdpSettings* settings; settings = certificate_store->settings; @@ -58,6 +60,16 @@ void certificate_store_init(rdpCertificateStore* certificate_store) fprintf(stderr, "creating directory %s\n", certificate_store->path); } + server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir); + + if (!PathFileExistsA(server_path)) + { + CreateDirectoryA(server_path, 0); + fprintf(stderr, "creating directory %s\n", server_path); + } + + free(server_path); + certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file); if (PathFileExistsA(certificate_store->file) == FALSE) diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 483945f62..2ffa2bd84 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -430,6 +430,7 @@ char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths) *lengths = NULL ; return NULL; } + GENERAL_NAMES_free(subject_alt_names); return strings; } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 920f20488..78b9b637e 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -627,7 +627,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) else if (match == -1) { /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ - tls_print_certificate_error(hostname, fingerprint); + tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file); if (instance->VerifyChangedCertificate) accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, ""); @@ -668,7 +668,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) return verification_status; } -void tls_print_certificate_error(char* hostname, char* fingerprint) +void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file) { fprintf(stderr, "The host key for %s has changed\n", hostname); fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); @@ -679,7 +679,7 @@ void tls_print_certificate_error(char* hostname, char* fingerprint) fprintf(stderr, "It is also possible that a host key has just been changed.\n"); fprintf(stderr, "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint); fprintf(stderr, "Please contact your system administrator.\n"); - fprintf(stderr, "Add correct host key in ~/.freerdp/known_hosts to get rid of this message.\n"); + fprintf(stderr, "Add correct host key in %s to get rid of this message.\n", hosts_file); fprintf(stderr, "Host key for %s has changed and you have requested strict checking.\n", hostname); fprintf(stderr, "Host key verification failed.\n"); } diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index 0d246f6ce..157b365b6 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -148,7 +148,9 @@ void ArrayList_Shift(wArrayList* arrayList, int index, int count) } else if (count < 0) { - MoveMemory(&arrayList->array[index], &arrayList->array[index - count], (arrayList->size + count) * sizeof(void*)); + int chunk = arrayList->size - index + count; + if (chunk > 0) + MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void*)); arrayList->size += count; } }