diff --git a/CMakeLists.txt b/CMakeLists.txt index a2e8e5baf..02aefd4e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,10 @@ if(NOT DEFINED VENDOR) set(VENDOR "FreeRDP" CACHE STRING "FreeRDP package vendor") endif() +if(NOT DEFINED PRODUCT) + set(PRODUCT "FreeRDP" CACHE STRING "FreeRDP package name") +endif() + if(NOT DEFINED FREERDP_VENDOR) set(FREERDP_VENDOR 1) endif() @@ -284,8 +288,8 @@ if(WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") # Set product and vendor for dll and exe version information. - set(RC_VERSION_VENDOR "FreeRDP") - set(RC_VERSION_PRODUCT "FreeRDP") + set(RC_VERSION_VENDOR ${VENDOR}) + set(RC_VERSION_PRODUCT ${PRODUCT}) set(RC_VERSION_PATCH ${BUILD_NUMBER}) set(RC_VERSION_DESCRIPTION ${GIT_REVISION}) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index e096a2098..42f1be86d 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -1080,8 +1080,8 @@ static WIN32ERROR cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* clip { UINT rc; - MessageQueue_PostQuit(cliprdr->queue, 0); - WaitForSingleObject(cliprdr->thread, INFINITE); + if (MessageQueue_PostQuit(cliprdr->queue, 0)) + WaitForSingleObject(cliprdr->thread, INFINITE); MessageQueue_Free(cliprdr->queue); CloseHandle(cliprdr->thread); diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 72333feaa..213b4fa2d 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -1305,8 +1305,8 @@ static WIN32ERROR drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdy { WIN32ERROR status; - MessageQueue_PostQuit(drdynvc->queue, 0); - WaitForSingleObject(drdynvc->thread, INFINITE); + if (MessageQueue_PostQuit(drdynvc->queue, 0)) + WaitForSingleObject(drdynvc->thread, INFINITE); MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 55ece049c..643192b3c 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -658,8 +658,8 @@ static void drive_free(DEVICE* device) { DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device; - MessageQueue_PostQuit(drive->IrpQueue, 0); - WaitForSingleObject(drive->thread, INFINITE); + if (MessageQueue_PostQuit(drive->IrpQueue, 0)) + WaitForSingleObject(drive->thread, INFINITE); CloseHandle(drive->thread); diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 36648e304..24ea995cd 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -1092,8 +1092,9 @@ static WIN32ERROR encomsp_virtual_channel_event_connected(encomspPlugin* encomsp static WIN32ERROR encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) { UINT rc; - MessageQueue_PostQuit(encomsp->queue, 0); - WaitForSingleObject(encomsp->thread, INFINITE); + + if (MessageQueue_PostQuit(encomsp->queue, 0)) + WaitForSingleObject(encomsp->thread, INFINITE); MessageQueue_Free(encomsp->queue); CloseHandle(encomsp->thread); diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 44d0f6f37..0d264fc58 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -328,8 +328,8 @@ static void parallel_free(DEVICE* device) { PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; - MessageQueue_PostQuit(parallel->queue, 0); - WaitForSingleObject(parallel->thread, INFINITE); + if (MessageQueue_PostQuit(parallel->queue, 0)) + WaitForSingleObject(parallel->thread, INFINITE); CloseHandle(parallel->thread); Stream_Free(parallel->device.data, TRUE); diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index aaec3ed6f..6af3b5f1a 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -586,8 +586,8 @@ static WIN32ERROR rail_virtual_channel_event_connected(railPlugin* rail, LPVOID static void rail_virtual_channel_event_disconnected(railPlugin* rail) { UINT rc; - MessageQueue_PostQuit(rail->queue, 0); - WaitForSingleObject(rail->thread, INFINITE); + if (MessageQueue_PostQuit(rail->queue, 0)) + WaitForSingleObject(rail->thread, INFINITE); MessageQueue_Free(rail->queue); CloseHandle(rail->thread); diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 651928645..939cc9589 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -1206,8 +1206,8 @@ static WIN32ERROR rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) { WIN32ERROR error; - MessageQueue_PostQuit(rdpdr->queue, 0); - WaitForSingleObject(rdpdr->thread, INFINITE); + if (MessageQueue_PostQuit(rdpdr->queue, 0)) + WaitForSingleObject(rdpdr->thread, INFINITE); MessageQueue_Free(rdpdr->queue); CloseHandle(rdpdr->thread); diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 07d3f09f6..417e03916 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -745,8 +745,8 @@ static void remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk) { UINT rc; - MessageQueue_PostQuit(remdesk->queue, 0); - WaitForSingleObject(remdesk->thread, INFINITE); + if (MessageQueue_PostQuit(remdesk->queue, 0)) + WaitForSingleObject(remdesk->thread, INFINITE); MessageQueue_Free(remdesk->queue); CloseHandle(remdesk->thread); diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 87d3262a9..8154bdd90 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -111,8 +111,8 @@ void smartcard_context_free(SMARTCARD_CONTEXT* pContext) /* cancel blocking calls like SCardGetStatusChange */ SCardCancel(pContext->hContext); - MessageQueue_PostQuit(pContext->IrpQueue, 0); - WaitForSingleObject(pContext->thread, INFINITE); + if (MessageQueue_PostQuit(pContext->IrpQueue, 0)) + WaitForSingleObject(pContext->thread, INFINITE); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); @@ -126,8 +126,8 @@ static void smartcard_free(DEVICE* device) if (smartcard->IrpQueue) { - MessageQueue_PostQuit(smartcard->IrpQueue, 0); - WaitForSingleObject(smartcard->thread, INFINITE); + if (MessageQueue_PostQuit(smartcard->IrpQueue, 0)) + WaitForSingleObject(smartcard->thread, INFINITE); MessageQueue_Free(smartcard->IrpQueue); smartcard->IrpQueue = NULL; diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 2b7c6b08c..3f876e787 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -607,8 +607,8 @@ disconnect: wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); if (input_queue) { - MessageQueue_PostQuit(input_queue, 0); - WaitForSingleObject(input_thread, INFINITE); + if (MessageQueue_PostQuit(input_queue, 0)) + WaitForSingleObject(input_thread, INFINITE); } CloseHandle(input_thread); } diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index 2a68d8ca4..4fdd56c87 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -779,8 +779,8 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) { wMessageQueue* input_queue; input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - MessageQueue_PostQuit(input_queue, 0); - WaitForSingleObject(input_thread, INFINITE); + if (MessageQueue_PostQuit(input_queue, 0)) + WaitForSingleObject(input_thread, INFINITE); CloseHandle(input_thread); } diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c index 1ed3fd41b..8680703a2 100644 --- a/client/Windows/wf_cliprdr.c +++ b/client/Windows/wf_cliprdr.c @@ -107,14 +107,14 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void *pv, ULONG cb, *pcbRead = 0; if (instance->m_lOffset.QuadPart >= instance->m_lSize.QuadPart) - return S_FALSE; + return E_FAIL; ret = cliprdr_send_request_filecontents(clipboard, (void*) This, instance->m_lIndex, FILECONTENTS_RANGE, instance->m_lOffset.HighPart, instance->m_lOffset.LowPart, cb); if (ret < 0) - return S_FALSE; + return E_FAIL; if (clipboard->req_fdata) { @@ -126,7 +126,7 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void *pv, ULONG cb, instance->m_lOffset.QuadPart += clipboard->req_fsize; if (clipboard->req_fsize < cb) - return S_FALSE; + return E_FAIL; return S_OK; } @@ -157,11 +157,11 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream* This, LARGE_INTEGER dlibMo newoffset = instance->m_lSize.QuadPart + dlibMove.QuadPart; break; default: - return S_FALSE; + return E_INVALIDARG; } if (newoffset < 0 || newoffset >= instance->m_lSize.QuadPart) - return FALSE; + return E_FAIL; instance->m_lOffset.QuadPart = newoffset; @@ -739,7 +739,7 @@ HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC* This, ULONG if (pceltFetched != 0) *pceltFetched = copied; - return (copied == celt) ? S_OK : S_FALSE; + return (copied == celt) ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC* This, ULONG celt) @@ -747,7 +747,7 @@ HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC* This, ULONG CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This; if (instance->m_nIndex + (LONG) celt > instance->m_nNumFormats) - return S_FALSE; + return E_FAIL; instance->m_nIndex += celt; @@ -1579,7 +1579,7 @@ static WIN32ERROR wf_cliprdr_server_format_data_request(CliprdrClientContext* co result = OleGetClipboard(&dataObj); - if (!SUCCEEDED(result)) + if (FAILED(result)) return ERROR_INTERNAL_ERROR; ZeroMemory(&format_etc, sizeof(FORMATETC)); @@ -1618,7 +1618,7 @@ static WIN32ERROR wf_cliprdr_server_format_data_request(CliprdrClientContext* co result = IDataObject_GetData(dataObj, &format_etc, &stg_medium); - if (!SUCCEEDED(result)) { + if (FAILED(result)) { DEBUG_CLIPRDR("dataObj->GetData failed."); } @@ -1785,7 +1785,7 @@ WIN32ERROR wf_cliprdr_server_file_contents_request(CliprdrClientContext* context hRet = OleGetClipboard(&pDataObj); - if (!SUCCEEDED(hRet)) + if (FAILED(hRet)) { WLog_ERR(TAG, "filecontents: get ole clipboard failed."); goto error; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 5a13ded31..1b771875e 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1093,9 +1093,11 @@ BOOL xf_post_connect(freerdp* instance) gdi = context->gdi; xfc->primary_buffer = gdi->primary_buffer; + xfc->palette = gdi->palette; } else { + xfc->palette = xfc->palette_hwgdi; xfc->srcBpp = settings->ColorDepth; xf_gdi_register_update_callbacks(update); } @@ -1532,8 +1534,8 @@ void* xf_client_thread(void* param) if (settings->AsyncInput) { wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - MessageQueue_PostQuit(inputQueue, 0); - WaitForSingleObject(inputThread, INFINITE); + if (MessageQueue_PostQuit(inputQueue, 0)) + WaitForSingleObject(inputThread, INFINITE); CloseHandle(inputThread); } diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 28c072e75..c05e33804 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -470,7 +470,8 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { - xf_SetWindowText(xfc, appWindow, appWindow->title); + if (appWindow->title) + xf_SetWindowText(xfc, appWindow, appWindow->title); } if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index f6461a638..5e1bdfab1 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -127,7 +127,8 @@ struct xf_context HANDLE mutex; BOOL UseXThreads; BOOL cursorHidden; - BYTE palette[256 * 4]; + BYTE* palette; + BYTE palette_hwgdi[256 * 4]; HGDI_DC hdc; UINT32 bitmap_size; diff --git a/config.h.in b/config.h.in index 528804066..ce212dd59 100644 --- a/config.h.in +++ b/config.h.in @@ -14,6 +14,9 @@ #define CMAKE_SHARED_LIBRARY_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}" #define CMAKE_SHARED_LIBRARY_PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}" +#define FREERDP_VENDOR_STRING "${VENDOR}" +#define FREERDP_PRODUCT_STRING "${PRODUCT}" + /* Include files */ #cmakedefine HAVE_FCNTL_H #cmakedefine HAVE_UNISTD_H diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index b80208238..410ad4902 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -42,6 +42,13 @@ struct _H264_CONTEXT_SUBSYSTEM }; typedef struct _H264_CONTEXT_SUBSYSTEM H264_CONTEXT_SUBSYSTEM; +enum _H264_RATECONTROL_MODE +{ + H264_RATECONTROL_VBR = 0, + H264_RATECONTROL_CQP +}; +typedef enum _H264_RATECONTROL_MODE H264_RATECONTROL_MODE; + struct _H264_CONTEXT { BOOL Compressor; @@ -49,8 +56,10 @@ struct _H264_CONTEXT UINT32 width; UINT32 height; + H264_RATECONTROL_MODE RateControlMode; UINT32 BitRate; FLOAT FrameRate; + UINT32 QP; UINT32 NumberOfThreads; int iStride[3]; diff --git a/include/freerdp/crypto/certificate.h b/include/freerdp/crypto/certificate.h index 537829615..537d9210e 100644 --- a/include/freerdp/crypto/certificate.h +++ b/include/freerdp/crypto/certificate.h @@ -35,14 +35,17 @@ typedef struct rdp_certificate_store rdpCertificateStore; struct rdp_certificate_data { char* hostname; + UINT16 port; + char* subject; + char* issuer; char* fingerprint; }; struct rdp_certificate_store { - FILE* fp; char* path; char* file; + char* legacy_file; rdpSettings* settings; rdpCertificateData* certificate_data; }; @@ -51,13 +54,29 @@ struct rdp_certificate_store extern "C" { #endif -FREERDP_API rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint); -FREERDP_API void certificate_data_free(rdpCertificateData* certificate_data); -FREERDP_API rdpCertificateStore* certificate_store_new(rdpSettings* settings); -FREERDP_API void certificate_data_replace(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data); -FREERDP_API void certificate_store_free(rdpCertificateStore* certificate_store); -FREERDP_API int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data); -FREERDP_API void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data); +FREERDP_API rdpCertificateData* certificate_data_new( + char* hostname, UINT16 port, char*subject, + char*issuer, char* fingerprint); +FREERDP_API void certificate_data_free( + rdpCertificateData* certificate_data); +FREERDP_API rdpCertificateStore* certificate_store_new( + rdpSettings* settings); +FREERDP_API BOOL certificate_data_replace( + rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data); +FREERDP_API void certificate_store_free( + rdpCertificateStore* certificate_store); +FREERDP_API int certificate_data_match( + rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data); +FREERDP_API BOOL certificate_data_print( + rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data); +FREERDP_API BOOL certificate_get_stored_data( + rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data, + char** subject, char** issuer, + char** fingerprint); #ifdef __cplusplus } diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index 44c8eef38..25d98bde3 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -133,7 +133,7 @@ FREERDP_API void crypto_cert_print_info(X509* xcert); FREERDP_API void crypto_cert_free(CryptoCert cert); FREERDP_API BOOL x509_verify_certificate(CryptoCert cert, char* certificate_store_path); -FREERDP_API rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname); +FREERDP_API rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname, UINT16 port); FREERDP_API BOOL crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* PublicKeyLength); #define TSSK_KEY_LENGTH 64 diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index b8b815730..8d8daeca1 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -98,8 +98,11 @@ FREERDP_API int tls_set_alert_code(rdpTls* tls, int level, int description); FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname); FREERDP_API int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int port); -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 void tls_print_certificate_error(char* hostname, UINT16 port, + char* fingerprint, char* hosts_file); +FREERDP_API void tls_print_certificate_name_mismatch_error( + char* hostname, UINT16 port, 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/freerdp.h b/include/freerdp/freerdp.h index c953d8a41..2df5e4c3e 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -67,7 +67,10 @@ typedef BOOL (*pPostConnect)(freerdp* instance); typedef void (*pPostDisconnect)(freerdp* instance); typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password, char** domain); typedef BOOL (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint); -typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint); +typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject, + char* issuer, char* new_fingerprint, + char* old_subject, char* old_issuer, + char* old_fingerprint); typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags); typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); @@ -207,7 +210,7 @@ struct rdp_freerdp Callback for certificate validation. Used to verify that an unknown certificate is trusted. */ ALIGN64 pVerifyChangedCertificate VerifyChangedCertificate; /**< (offset 52) - Callback for changed certificate validation. + Callback for changed certificate validation. Used when a certificate differs from stored fingerprint. If returns TRUE, the new fingerprint will be trusted and old thrown out. */ diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index fe3374b31..e7cc8b334 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1512,12 +1512,19 @@ int freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, int n return 1; } - else if (xorBpp == 24 || xorBpp == 32) + else if (xorBpp == 24 || xorBpp == 32 || xorBpp == 16 || xorBpp == 8) { int xorBytesPerPixel = xorBpp >> 3; xorStep = nWidth * xorBytesPerPixel; pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + if (xorBpp == 8 && !palette) + { + WLog_ERR(TAG, "null palette in convertion from %d bpp to %d bpp", + xorBpp, dstBitsPerPixel); + return -1; + } + for (y = 0; y < nHeight; y++) { andBit = 0x80; @@ -1536,9 +1543,23 @@ int freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, int n for (x = 0; x < nWidth; x++) { if (xorBpp == 32) + { xorPixel = *((UINT32*) xorBits); + } + else if (xorBpp == 16) + { + UINT16 r, g, b; + GetRGB16(r, g, b, *(UINT16*)xorBits); + xorPixel = ARGB32(0xFF, r, g, b); + } + else if (xorBpp == 8) + { + xorPixel = 0xFF << 24 | ((UINT32*)palette)[xorBits[0]]; + } else + { xorPixel = xorBits[0] | xorBits[1] << 8 | xorBits[2] << 16 | 0xFF << 24; + } xorBits += xorBytesPerPixel; diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index 846dec06c..45732ebe1 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -179,8 +179,6 @@ static int openh264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstS sys->EncParamExt.iUsageType = SCREEN_CONTENT_REAL_TIME; sys->EncParamExt.iPicWidth = h264->width; sys->EncParamExt.iPicHeight = h264->height; - sys->EncParamExt.iTargetBitrate = h264->BitRate; - sys->EncParamExt.iRCMode = RC_BITRATE_MODE; sys->EncParamExt.fMaxFrameRate = h264->FrameRate; sys->EncParamExt.iMaxBitrate = UNSPECIFIED_BIT_RATE; sys->EncParamExt.bEnableDenoise = 0; @@ -191,8 +189,19 @@ static int openh264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstS sys->EncParamExt.sSpatialLayers[0].fFrameRate = h264->FrameRate; sys->EncParamExt.sSpatialLayers[0].iVideoWidth = sys->EncParamExt.iPicWidth; sys->EncParamExt.sSpatialLayers[0].iVideoHeight = sys->EncParamExt.iPicHeight; - sys->EncParamExt.sSpatialLayers[0].iSpatialBitrate = sys->EncParamExt.iTargetBitrate; sys->EncParamExt.sSpatialLayers[0].iMaxSpatialBitrate = sys->EncParamExt.iMaxBitrate; + switch (h264->RateControlMode) + { + case H264_RATECONTROL_VBR: + sys->EncParamExt.iRCMode = RC_BITRATE_MODE; + sys->EncParamExt.iTargetBitrate = h264->BitRate; + sys->EncParamExt.sSpatialLayers[0].iSpatialBitrate = sys->EncParamExt.iTargetBitrate; + break; + case H264_RATECONTROL_CQP: + sys->EncParamExt.iRCMode = RC_OFF_MODE; + sys->EncParamExt.sSpatialLayers[0].iDLayerQp = h264->QP; + break; + } if (sys->EncParamExt.iMultipleThreadIdc > 1) { @@ -206,36 +215,65 @@ static int openh264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstS WLog_ERR(TAG, "Failed to initialize OpenH264 encoder (status=%ld)", status); return status; } + + status = (*sys->pEncoder)->GetOption(sys->pEncoder, ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, + &sys->EncParamExt); + + if (status < 0) + { + WLog_ERR(TAG, "Failed to get initial OpenH264 encoder parameters (status=%ld)", status); + return status; + } } else { - if (sys->EncParamExt.iTargetBitrate != h264->BitRate) + switch (h264->RateControlMode) { - sys->EncParamExt.iTargetBitrate = h264->BitRate; - bitrate.iLayer = SPATIAL_LAYER_ALL; - bitrate.iBitrate = h264->BitRate; + case H264_RATECONTROL_VBR: + if (sys->EncParamExt.iTargetBitrate != h264->BitRate) + { + sys->EncParamExt.iTargetBitrate = h264->BitRate; + bitrate.iLayer = SPATIAL_LAYER_ALL; + bitrate.iBitrate = h264->BitRate; - status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_BITRATE, - &bitrate); + status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_BITRATE, + &bitrate); - if (status < 0) - { - WLog_ERR(TAG, "Failed to set encoder bitrate (status=%ld)", status); - return status; - } - } - if (sys->EncParamExt.fMaxFrameRate != h264->FrameRate) - { - sys->EncParamExt.fMaxFrameRate = h264->FrameRate; + if (status < 0) + { + WLog_ERR(TAG, "Failed to set encoder bitrate (status=%ld)", status); + return status; + } + } + if (sys->EncParamExt.fMaxFrameRate != h264->FrameRate) + { + sys->EncParamExt.fMaxFrameRate = h264->FrameRate; - status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_FRAME_RATE, - &sys->EncParamExt.fMaxFrameRate); + status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_FRAME_RATE, + &sys->EncParamExt.fMaxFrameRate); - if (status < 0) - { - WLog_ERR(TAG, "Failed to set encoder framerate (status=%ld)", status); - return status; - } + if (status < 0) + { + WLog_ERR(TAG, "Failed to set encoder framerate (status=%ld)", status); + return status; + } + } + break; + case H264_RATECONTROL_CQP: + if (sys->EncParamExt.sSpatialLayers[0].iDLayerQp != h264->QP) + { + sys->EncParamExt.sSpatialLayers[0].iDLayerQp = h264->QP; + + status = (*sys->pEncoder)->SetOption(sys->pEncoder, ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, + &sys->EncParamExt); + + if (status < 0) + { + WLog_ERR(TAG, "Failed to set encoder parameters (status=%ld)", status); + return status; + } + } + break; } } diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index 3c8cf4182..717edc9fc 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -161,7 +161,12 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) file->MachinePorts = (UINT32*) calloc(count, sizeof(UINT32)); if (!file->MachineAddresses || !file->MachinePorts) + { + free(file->MachineAddresses); + free(file->MachinePorts); + free(tokens); return -1; + } for (i = 0; i < count; i++) { diff --git a/libfreerdp/core/autodetect.c b/libfreerdp/core/autodetect.c index 46d9b384c..1a89737c6 100644 --- a/libfreerdp/core/autodetect.c +++ b/libfreerdp/core/autodetect.c @@ -73,7 +73,7 @@ static BOOL autodetect_send_rtt_measure_request(rdpContext* context, UINT16 sequ Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */ Stream_Write_UINT16(s, requestType); /* requestType (2 bytes) */ - context->rdp->autodetect->rttMeasureStartTime = GetTickCount(); + context->rdp->autodetect->rttMeasureStartTime = GetTickCountPrecise(); return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ); } @@ -257,7 +257,7 @@ static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 respon UINT32 timeDelta; /* Compute the total time */ - timeDelta = GetTickCount() - rdp->autodetect->bandwidthMeasureStartTime; + timeDelta = GetTickCountPrecise() - rdp->autodetect->bandwidthMeasureStartTime; /* Send the result PDU to the server */ @@ -361,7 +361,7 @@ static BOOL autodetect_recv_rtt_measure_response(rdpRdp* rdp, wStream* s, AUTODE WLog_VRB(AUTODETECT_TAG, "received RTT Measure Response PDU"); - rdp->autodetect->netCharAverageRTT = GetTickCount() - rdp->autodetect->rttMeasureStartTime; + rdp->autodetect->netCharAverageRTT = GetTickCountPrecise() - rdp->autodetect->rttMeasureStartTime; if (rdp->autodetect->netCharBaseRTT == 0 || rdp->autodetect->netCharBaseRTT > rdp->autodetect->netCharAverageRTT) rdp->autodetect->netCharBaseRTT = rdp->autodetect->netCharAverageRTT; @@ -375,10 +375,10 @@ static BOOL autodetect_recv_bandwidth_measure_start(rdpRdp* rdp, wStream* s, AUT if (autodetectReqPdu->headerLength != 0x06) return FALSE; - WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Start PDU - time=%lu", GetTickCount()); + WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Start PDU - time=%lu", GetTickCountPrecise()); /* Initialize bandwidth measurement parameters */ - rdp->autodetect->bandwidthMeasureStartTime = GetTickCount(); + rdp->autodetect->bandwidthMeasureStartTime = GetTickCountPrecise(); rdp->autodetect->bandwidthMeasureByteCount = 0; /* Continuous Auto-Detection: mark the start of the measurement */ diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 52b8f46ee..5f507e392 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -376,7 +376,6 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) { int header; BYTE drawingFlags = 0; - UINT16 desktopResizeFlag; UINT16 preferredBitsPerPixel; Stream_EnsureRemainingCapacity(s, 64); @@ -406,7 +405,6 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) else preferredBitsPerPixel = 8; - desktopResizeFlag = settings->DesktopResize; Stream_Write_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ Stream_Write_UINT16(s, 1); /* receive1BitPerPixel (2 bytes) */ @@ -415,7 +413,7 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) Stream_Write_UINT16(s, settings->DesktopWidth); /* desktopWidth (2 bytes) */ Stream_Write_UINT16(s, settings->DesktopHeight); /* desktopHeight (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ - Stream_Write_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + Stream_Write_UINT16(s, settings->DesktopResize); /* desktopResizeFlag (2 bytes) */ Stream_Write_UINT16(s, 1); /* bitmapCompressionFlag (2 bytes) */ Stream_Write_UINT8(s, 0); /* highColorFlags (1 byte) */ Stream_Write_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 37c068dfc..2001feb30 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -666,7 +666,8 @@ UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, LPVOID pData, ULONG pChannelOpenEvent->UserData = pUserData; pChannelOpenEvent->pChannelOpenData = pChannelOpenData; - MessageQueue_Post(channels->queue, (void*) channels, 0, (void*) pChannelOpenEvent, NULL); + if (!MessageQueue_Post(channels->queue, (void*) channels, 0, (void*) pChannelOpenEvent, NULL)) + return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_OK; } diff --git a/libfreerdp/core/gateway/ntlm.c b/libfreerdp/core/gateway/ntlm.c index 221258d7a..68add2c6e 100644 --- a/libfreerdp/core/gateway/ntlm.c +++ b/libfreerdp/core/gateway/ntlm.c @@ -43,7 +43,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* ntlm->http = http; ntlm->Bindings = Bindings; - ntlm->table = InitSecurityInterfaceEx(SSPI_INTERFACE_WINPR); + ntlm->table = InitSecurityInterface(); if (!ntlm->table) return FALSE; @@ -85,7 +85,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* } else { - /** + /** * flags for RPC authentication: * RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: * ISC_REQ_USE_DCE_STYLE | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | @@ -122,7 +122,7 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname) if (!ntlm->ServicePrincipalName) return FALSE; - + return TRUE; } diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index 4682e995f..1154ebf39 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -323,7 +323,8 @@ wStream* rdg_build_http_request(rdpRdg* rdg, char* method) s = http_request_write(rdg->http, request); http_request_free(request); - Stream_SealLength(s); + if (s) + Stream_SealLength(s); return s; } @@ -435,9 +436,7 @@ BOOL rdg_process_in_channel_response(rdpRdg* rdg, HttpResponse* response) s = rdg_build_http_request(rdg, "RDG_IN_DATA"); if (!s) - { return FALSE; - } status = tls_write_all(rdg->tlsIn, Stream_Buffer(s), Stream_Length(s)); @@ -489,13 +488,16 @@ BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s) { HRESULT errorCode; - WLog_DBG(TAG, "Handshake response recieved"); + WLog_DBG(TAG, "Handshake response received"); if (rdg->state != RDG_CLIENT_STATE_HANDSHAKE) { return FALSE; } + if (Stream_GetRemainingLength(s) < 12) + return FALSE; + Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); @@ -519,6 +521,9 @@ BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s) return FALSE; } + if (Stream_GetRemainingLength(s) < 14) + return FALSE; + Stream_Seek(s, 10); Stream_Read_UINT32(s, errorCode); @@ -542,6 +547,9 @@ BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s) return FALSE; } + if (Stream_GetRemainingLength(s) < 12) + return FALSE; + Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); @@ -565,6 +573,9 @@ BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s) return FALSE; } + if (Stream_GetRemainingLength(s) < 12) + return FALSE; + Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); @@ -585,8 +596,11 @@ BOOL rdg_process_packet(rdpRdg* rdg, wStream* s) UINT16 type; Stream_SetPosition(s, 0); - Stream_Read_UINT16(s, type); - Stream_SetPosition(s, 0); + + if (Stream_GetRemainingLength(s) < 2) + return FALSE; + + Stream_Peek_UINT16(s, type); switch (type) { diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 6f3c67894..7c7613e24 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -321,7 +321,8 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2)) { - rts_send_flow_control_ack_pdu(rpc); + if (rts_send_flow_control_ack_pdu(rpc) < 0) + return -1; } if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength)) @@ -412,7 +413,8 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) return -1; Stream_Write(pdu->s, buffer, Stream_Length(fragment)); Stream_SealLength(pdu->s); - rpc_client_recv_pdu(rpc, pdu); + if (rpc_client_recv_pdu(rpc, pdu) < 0) + return -1; rpc_pdu_reset(pdu); } else @@ -420,7 +422,8 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED) WLog_ERR(TAG, "warning: unhandled RTS PDU"); - rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); + if (rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length) < 0) + return -1; } return 1; @@ -434,7 +437,8 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) return -1; Stream_Write(pdu->s, buffer, Stream_Length(fragment)); Stream_SealLength(pdu->s); - rpc_client_recv_pdu(rpc, pdu); + if (rpc_client_recv_pdu(rpc, pdu) < 0) + return -1; rpc_pdu_reset(pdu); return 1; diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 90f2937a8..fc158cadf 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -41,17 +41,14 @@ static BOOL update_message_BeginPaint(rdpContext* context) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, BeginPaint), NULL, NULL); - - return TRUE; } static BOOL update_message_EndPaint(rdpContext* context) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, EndPaint), NULL, NULL); - return TRUE; } static BOOL update_message_SetBounds(rdpContext* context, rdpBounds* bounds) @@ -66,23 +63,20 @@ static BOOL update_message_SetBounds(rdpContext* context, rdpBounds* bounds) CopyMemory(wParam, bounds, sizeof(rdpBounds)); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SetBounds), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_Synchronize(rdpContext* context) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, Synchronize), NULL, NULL); - return TRUE; } static BOOL update_message_DesktopResize(rdpContext* context) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, DesktopResize), NULL, NULL); - return TRUE; } static BOOL update_message_BitmapUpdate(rdpContext* context, BITMAP_UPDATE* bitmap) @@ -125,10 +119,9 @@ static BOOL update_message_BitmapUpdate(rdpContext* context, BITMAP_UPDATE* bitm wParam->rectangles[index].bitmapLength); #endif } - MessageQueue_Post(context->update->queue, (void*) context, - MakeMessageId(Update, BitmapUpdate), (void*) wParam, NULL); - return TRUE; + return MessageQueue_Post(context->update->queue, (void*) context, + MakeMessageId(Update, BitmapUpdate), (void*) wParam, NULL); } static BOOL update_message_Palette(rdpContext* context, PALETTE_UPDATE* palette) @@ -140,9 +133,8 @@ static BOOL update_message_Palette(rdpContext* context, PALETTE_UPDATE* palette) return FALSE; CopyMemory(wParam, palette, sizeof(PALETTE_UPDATE)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, Palette), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PlaySound(rdpContext* context, PLAY_SOUND_UPDATE* playSound) @@ -154,16 +146,14 @@ static BOOL update_message_PlaySound(rdpContext* context, PLAY_SOUND_UPDATE* pla return FALSE; CopyMemory(wParam, playSound, sizeof(PLAY_SOUND_UPDATE)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, PlaySound), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_SetKeyboardIndicators(rdpContext* context, UINT16 led_flags) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags, NULL); - return TRUE; } static BOOL update_message_RefreshRect(rdpContext* context, BYTE count, RECTANGLE_16* areas) @@ -175,9 +165,8 @@ static BOOL update_message_RefreshRect(rdpContext* context, BYTE count, RECTANGL return FALSE; CopyMemory(lParam, areas, sizeof(RECTANGLE_16) * count); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, RefreshRect), (void*) (size_t) count, (void*) lParam); - return TRUE; } static BOOL update_message_SuppressOutput(rdpContext* context, BYTE allow, RECTANGLE_16* area) @@ -192,9 +181,8 @@ static BOOL update_message_SuppressOutput(rdpContext* context, BYTE allow, RECTA CopyMemory(lParam, area, sizeof(RECTANGLE_16)); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SuppressOutput), (void*) (size_t) allow, (void*) lParam); - return TRUE; } static BOOL update_message_SurfaceCommand(rdpContext* context, wStream* s) @@ -215,9 +203,8 @@ static BOOL update_message_SurfaceCommand(rdpContext* context, wStream* s) wParam->pointer = wParam->buffer; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceCommand), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_SurfaceBits(rdpContext* context, SURFACE_BITS_COMMAND* surfaceBitsCommand) @@ -241,9 +228,8 @@ static BOOL update_message_SurfaceBits(rdpContext* context, SURFACE_BITS_COMMAND CopyMemory(wParam->bitmapData, surfaceBitsCommand->bitmapData, wParam->bitmapDataLength); #endif - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_SurfaceFrameMarker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker) @@ -255,18 +241,14 @@ static BOOL update_message_SurfaceFrameMarker(rdpContext* context, SURFACE_FRAME return FALSE; CopyMemory(wParam, surfaceFrameMarker, sizeof(SURFACE_FRAME_MARKER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceFrameMarker), (void*) wParam, NULL); - - return TRUE; } static BOOL update_message_SurfaceFrameAcknowledge(rdpContext* context, UINT32 frameId) { - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceFrameAcknowledge), (void*) (size_t) frameId, NULL); - - return TRUE; } /* Primary Update */ @@ -280,9 +262,8 @@ static BOOL update_message_DstBlt(rdpContext* context, DSTBLT_ORDER* dstBlt) return FALSE; CopyMemory(wParam, dstBlt, sizeof(DSTBLT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, DstBlt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PatBlt(rdpContext* context, PATBLT_ORDER* patBlt) @@ -296,9 +277,8 @@ static BOOL update_message_PatBlt(rdpContext* context, PATBLT_ORDER* patBlt) wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, PatBlt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_ScrBlt(rdpContext* context, SCRBLT_ORDER* scrBlt) @@ -310,10 +290,8 @@ static BOOL update_message_ScrBlt(rdpContext* context, SCRBLT_ORDER* scrBlt) return FALSE; CopyMemory(wParam, scrBlt, sizeof(SCRBLT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, ScrBlt), (void*) wParam, NULL); - - return TRUE; } static BOOL update_message_OpaqueRect(rdpContext* context, OPAQUE_RECT_ORDER* opaqueRect) @@ -325,9 +303,8 @@ static BOOL update_message_OpaqueRect(rdpContext* context, OPAQUE_RECT_ORDER* op return FALSE; CopyMemory(wParam, opaqueRect, sizeof(OPAQUE_RECT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, OpaqueRect), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawNineGrid(rdpContext* context, DRAW_NINE_GRID_ORDER* drawNineGrid) @@ -339,9 +316,8 @@ static BOOL update_message_DrawNineGrid(rdpContext* context, DRAW_NINE_GRID_ORDE return FALSE; CopyMemory(wParam, drawNineGrid, sizeof(DRAW_NINE_GRID_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, DrawNineGrid), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MultiDstBlt(rdpContext* context, MULTI_DSTBLT_ORDER* multiDstBlt) @@ -353,9 +329,8 @@ static BOOL update_message_MultiDstBlt(rdpContext* context, MULTI_DSTBLT_ORDER* return FALSE; CopyMemory(wParam, multiDstBlt, sizeof(MULTI_DSTBLT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiDstBlt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MultiPatBlt(rdpContext* context, MULTI_PATBLT_ORDER* multiPatBlt) @@ -369,9 +344,8 @@ static BOOL update_message_MultiPatBlt(rdpContext* context, MULTI_PATBLT_ORDER* wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiPatBlt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MultiScrBlt(rdpContext* context, MULTI_SCRBLT_ORDER* multiScrBlt) @@ -383,9 +357,8 @@ static BOOL update_message_MultiScrBlt(rdpContext* context, MULTI_SCRBLT_ORDER* return FALSE; CopyMemory(wParam, multiScrBlt, sizeof(MULTI_SCRBLT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiScrBlt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MultiOpaqueRect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multiOpaqueRect) @@ -397,9 +370,8 @@ static BOOL update_message_MultiOpaqueRect(rdpContext* context, MULTI_OPAQUE_REC return FALSE; CopyMemory(wParam, multiOpaqueRect, sizeof(MULTI_OPAQUE_RECT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiOpaqueRect), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MultiDrawNineGrid(rdpContext* context, MULTI_DRAW_NINE_GRID_ORDER* multiDrawNineGrid) @@ -413,9 +385,8 @@ static BOOL update_message_MultiDrawNineGrid(rdpContext* context, MULTI_DRAW_NIN /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MultiDrawNineGrid), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_LineTo(rdpContext* context, LINE_TO_ORDER* lineTo) @@ -427,9 +398,8 @@ static BOOL update_message_LineTo(rdpContext* context, LINE_TO_ORDER* lineTo) return FALSE; CopyMemory(wParam, lineTo, sizeof(LINE_TO_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, LineTo), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_Polyline(rdpContext* context, POLYLINE_ORDER* polyline) @@ -449,9 +419,8 @@ static BOOL update_message_Polyline(rdpContext* context, POLYLINE_ORDER* polylin } CopyMemory(wParam->points, polyline->points, sizeof(DELTA_POINT) * wParam->numDeltaEntries); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, Polyline), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MemBlt(rdpContext* context, MEMBLT_ORDER* memBlt) @@ -463,10 +432,8 @@ static BOOL update_message_MemBlt(rdpContext* context, MEMBLT_ORDER* memBlt) return FALSE; CopyMemory(wParam, memBlt, sizeof(MEMBLT_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, MemBlt), (void*) wParam, NULL); - - return TRUE; } static BOOL update_message_Mem3Blt(rdpContext* context, MEM3BLT_ORDER* mem3Blt) @@ -480,9 +447,8 @@ static BOOL update_message_Mem3Blt(rdpContext* context, MEM3BLT_ORDER* mem3Blt) wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, Mem3Blt), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_SaveBitmap(rdpContext* context, SAVE_BITMAP_ORDER* saveBitmap) @@ -494,9 +460,8 @@ static BOOL update_message_SaveBitmap(rdpContext* context, SAVE_BITMAP_ORDER* sa return FALSE; CopyMemory(wParam, saveBitmap, sizeof(SAVE_BITMAP_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, SaveBitmap), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_GlyphIndex(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex) @@ -510,9 +475,8 @@ static BOOL update_message_GlyphIndex(rdpContext* context, GLYPH_INDEX_ORDER* gl wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, GlyphIndex), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_FastIndex(rdpContext* context, FAST_INDEX_ORDER* fastIndex) @@ -524,9 +488,8 @@ static BOOL update_message_FastIndex(rdpContext* context, FAST_INDEX_ORDER* fast return FALSE; CopyMemory(wParam, fastIndex, sizeof(FAST_INDEX_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, FastIndex), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_FastGlyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph) @@ -553,9 +516,8 @@ static BOOL update_message_FastGlyph(rdpContext* context, FAST_GLYPH_ORDER* fast wParam->glyphData.aj = NULL; } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, FastGlyph), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PolygonSC(rdpContext* context, POLYGON_SC_ORDER* polygonSC) @@ -575,9 +537,8 @@ static BOOL update_message_PolygonSC(rdpContext* context, POLYGON_SC_ORDER* poly } CopyMemory(wParam->points, polygonSC, sizeof(DELTA_POINT) * wParam->numPoints); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, PolygonSC), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PolygonCB(rdpContext* context, POLYGON_CB_ORDER* polygonCB) @@ -599,9 +560,8 @@ static BOOL update_message_PolygonCB(rdpContext* context, POLYGON_CB_ORDER* poly wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, PolygonCB), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_EllipseSC(rdpContext* context, ELLIPSE_SC_ORDER* ellipseSC) @@ -613,9 +573,8 @@ static BOOL update_message_EllipseSC(rdpContext* context, ELLIPSE_SC_ORDER* elli return FALSE; CopyMemory(wParam, ellipseSC, sizeof(ELLIPSE_SC_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, EllipseSC), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_EllipseCB(rdpContext* context, ELLIPSE_CB_ORDER* ellipseCB) @@ -629,9 +588,8 @@ static BOOL update_message_EllipseCB(rdpContext* context, ELLIPSE_CB_ORDER* elli wParam->brush.data = (BYTE*) wParam->brush.p8x8; - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PrimaryUpdate, EllipseCB), (void*) wParam, NULL); - return TRUE; } /* Secondary Update */ @@ -653,9 +611,8 @@ static BOOL update_message_CacheBitmap(rdpContext* context, CACHE_BITMAP_ORDER* } CopyMemory(wParam->bitmapDataStream, cacheBitmapOrder, wParam->bitmapLength); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmap), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheBitmapV2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cacheBitmapV2Order) @@ -675,9 +632,8 @@ static BOOL update_message_CacheBitmapV2(rdpContext* context, CACHE_BITMAP_V2_OR } CopyMemory(wParam->bitmapDataStream, cacheBitmapV2Order->bitmapDataStream, wParam->bitmapLength); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmapV2), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheBitmapV3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cacheBitmapV3Order) @@ -697,9 +653,8 @@ static BOOL update_message_CacheBitmapV3(rdpContext* context, CACHE_BITMAP_V3_OR } CopyMemory(wParam->bitmapData.data, cacheBitmapV3Order->bitmapData.data, wParam->bitmapData.length); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmapV3), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheColorTable(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cacheColorTableOrder) @@ -711,9 +666,8 @@ static BOOL update_message_CacheColorTable(rdpContext* context, CACHE_COLOR_TABL return FALSE; CopyMemory(wParam, cacheColorTableOrder, sizeof(CACHE_COLOR_TABLE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheColorTable), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheGlyph(rdpContext* context, CACHE_GLYPH_ORDER* cacheGlyphOrder) @@ -725,9 +679,8 @@ static BOOL update_message_CacheGlyph(rdpContext* context, CACHE_GLYPH_ORDER* ca return FALSE; CopyMemory(wParam, cacheGlyphOrder, sizeof(CACHE_GLYPH_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheGlyph), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheGlyphV2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cacheGlyphV2Order) @@ -739,9 +692,8 @@ static BOOL update_message_CacheGlyphV2(rdpContext* context, CACHE_GLYPH_V2_ORDE return FALSE; CopyMemory(wParam, cacheGlyphV2Order, sizeof(CACHE_GLYPH_V2_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheGlyphV2), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CacheBrush(rdpContext* context, CACHE_BRUSH_ORDER* cacheBrushOrder) @@ -753,9 +705,8 @@ static BOOL update_message_CacheBrush(rdpContext* context, CACHE_BRUSH_ORDER* ca return FALSE; CopyMemory(wParam, cacheBrushOrder, sizeof(CACHE_BRUSH_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBrush), (void*) wParam, NULL); - return TRUE; } /* Alternate Secondary Update */ @@ -779,9 +730,8 @@ static BOOL update_message_CreateOffscreenBitmap(rdpContext* context, CREATE_OFF } CopyMemory(wParam->deleteList.indices, createOffscreenBitmap->deleteList.indices, wParam->deleteList.cIndices); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, CreateOffscreenBitmap), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_SwitchSurface(rdpContext* context, SWITCH_SURFACE_ORDER* switchSurface) @@ -793,9 +743,8 @@ static BOOL update_message_SwitchSurface(rdpContext* context, SWITCH_SURFACE_ORD return FALSE; CopyMemory(wParam, switchSurface, sizeof(SWITCH_SURFACE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, SwitchSurface), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_CreateNineGridBitmap(rdpContext* context, CREATE_NINE_GRID_BITMAP_ORDER* createNineGridBitmap) @@ -807,9 +756,8 @@ static BOOL update_message_CreateNineGridBitmap(rdpContext* context, CREATE_NINE return FALSE; CopyMemory(wParam, createNineGridBitmap, sizeof(CREATE_NINE_GRID_BITMAP_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, CreateNineGridBitmap), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_FrameMarker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) @@ -821,9 +769,8 @@ static BOOL update_message_FrameMarker(rdpContext* context, FRAME_MARKER_ORDER* return FALSE; CopyMemory(wParam, frameMarker, sizeof(FRAME_MARKER_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, FrameMarker), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_StreamBitmapFirst(rdpContext* context, STREAM_BITMAP_FIRST_ORDER* streamBitmapFirst) @@ -837,9 +784,8 @@ static BOOL update_message_StreamBitmapFirst(rdpContext* context, STREAM_BITMAP_ /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, StreamBitmapFirst), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_StreamBitmapNext(rdpContext* context, STREAM_BITMAP_NEXT_ORDER* streamBitmapNext) @@ -853,9 +799,8 @@ static BOOL update_message_StreamBitmapNext(rdpContext* context, STREAM_BITMAP_N /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, StreamBitmapNext), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusFirst(rdpContext* context, DRAW_GDIPLUS_FIRST_ORDER* drawGdiPlusFirst) @@ -869,9 +814,8 @@ static BOOL update_message_DrawGdiPlusFirst(rdpContext* context, DRAW_GDIPLUS_FI /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusFirst), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusNext(rdpContext* context, DRAW_GDIPLUS_NEXT_ORDER* drawGdiPlusNext) @@ -885,9 +829,8 @@ static BOOL update_message_DrawGdiPlusNext(rdpContext* context, DRAW_GDIPLUS_NEX /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusNext), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusEnd(rdpContext* context, DRAW_GDIPLUS_END_ORDER* drawGdiPlusEnd) @@ -901,9 +844,8 @@ static BOOL update_message_DrawGdiPlusEnd(rdpContext* context, DRAW_GDIPLUS_END_ /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusEnd), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusCacheFirst(rdpContext* context, DRAW_GDIPLUS_CACHE_FIRST_ORDER* drawGdiPlusCacheFirst) @@ -917,9 +859,8 @@ static BOOL update_message_DrawGdiPlusCacheFirst(rdpContext* context, DRAW_GDIPL /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusCacheFirst), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusCacheNext(rdpContext* context, DRAW_GDIPLUS_CACHE_NEXT_ORDER* drawGdiPlusCacheNext) @@ -933,9 +874,8 @@ static BOOL update_message_DrawGdiPlusCacheNext(rdpContext* context, DRAW_GDIPLU /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusCacheNext), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_DrawGdiPlusCacheEnd(rdpContext* context, DRAW_GDIPLUS_CACHE_END_ORDER* drawGdiPlusCacheEnd) @@ -949,9 +889,8 @@ static BOOL update_message_DrawGdiPlusCacheEnd(rdpContext* context, DRAW_GDIPLUS /* TODO: complete copy */ - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(AltSecUpdate, DrawGdiPlusCacheEnd), (void*) wParam, NULL); - return TRUE; } /* Window Update */ @@ -974,9 +913,8 @@ static BOOL update_message_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* } CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowCreate), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) @@ -997,9 +935,8 @@ static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* } CopyMemory(lParam, windowState, sizeof(WINDOW_STATE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowUpdate), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon) @@ -1046,9 +983,8 @@ static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* or CopyMemory(lParam->iconInfo->colorTable, windowIcon->iconInfo->colorTable, windowIcon->iconInfo->cbColorTable); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowIcon), (void*) wParam, (void*) lParam); - return TRUE; out_fail: free(lParam->iconInfo->bitsColor); @@ -1078,9 +1014,8 @@ static BOOL update_message_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_IN } CopyMemory(lParam, windowCachedIcon, sizeof(WINDOW_CACHED_ICON_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowCachedIcon), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) @@ -1092,9 +1027,8 @@ static BOOL update_message_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* return FALSE; CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowDelete), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) @@ -1115,9 +1049,8 @@ static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_IN } CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, NotifyIconCreate), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) @@ -1138,9 +1071,8 @@ static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_IN } CopyMemory(lParam, notifyIconState, sizeof(NOTIFY_ICON_STATE_ORDER)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, NotifyIconUpdate), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) @@ -1152,9 +1084,8 @@ static BOOL update_message_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_IN return FALSE; CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, NotifyIconDelete), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop) @@ -1183,9 +1114,8 @@ static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_IN CopyMemory(lParam->windowIds, monitoredDesktop->windowIds, lParam->numWindowIds); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, MonitoredDesktop), (void*) wParam, (void*) lParam); - return TRUE; } static BOOL update_message_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) @@ -1197,9 +1127,8 @@ static BOOL update_message_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER return FALSE; CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, NonMonitoredDesktop), (void*) wParam, NULL); - return TRUE; } /* Pointer Update */ @@ -1213,9 +1142,8 @@ static BOOL update_message_PointerPosition(rdpContext* context, POINTER_POSITION return FALSE; CopyMemory(wParam, pointerPosition, sizeof(POINTER_POSITION_UPDATE)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerPosition), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PointerSystem(rdpContext* context, POINTER_SYSTEM_UPDATE* pointerSystem) @@ -1227,9 +1155,8 @@ static BOOL update_message_PointerSystem(rdpContext* context, POINTER_SYSTEM_UPD return FALSE; CopyMemory(wParam, pointerSystem, sizeof(POINTER_SYSTEM_UPDATE)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerSystem), (void*) wParam, NULL); - return TRUE; } static BOOL update_message_PointerColor(rdpContext* context, POINTER_COLOR_UPDATE* pointerColor) @@ -1259,9 +1186,8 @@ static BOOL update_message_PointerColor(rdpContext* context, POINTER_COLOR_UPDAT CopyMemory(wParam->xorMaskData, pointerColor->xorMaskData, wParam->lengthXorMask); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerColor), (void*) wParam, NULL); - return TRUE; out_fail: free(wParam->andMaskData); @@ -1297,9 +1223,8 @@ static BOOL update_message_PointerNew(rdpContext* context, POINTER_NEW_UPDATE* p CopyMemory(wParam->colorPtrAttr.xorMaskData, pointerNew->colorPtrAttr.xorMaskData, wParam->colorPtrAttr.lengthXorMask); } - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerNew), (void*) wParam, NULL); - return TRUE; out_fail: free(wParam->colorPtrAttr.andMaskData); @@ -1317,9 +1242,8 @@ static BOOL update_message_PointerCached(rdpContext* context, POINTER_CACHED_UPD return FALSE; CopyMemory(wParam, pointerCached, sizeof(POINTER_CACHED_UPDATE)); - MessageQueue_Post(context->update->queue, (void*) context, + return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerCached), (void*) wParam, NULL); - return TRUE; } /* Message Queue */ @@ -2563,8 +2487,8 @@ void update_message_proxy_free(rdpUpdateProxy* message) { if (message) { - MessageQueue_PostQuit(message->update->queue, 0); - WaitForSingleObject(message->thread, INFINITE); + if (MessageQueue_PostQuit(message->update->queue, 0)) + WaitForSingleObject(message->thread, INFINITE); CloseHandle(message->thread); free(message); } @@ -2574,55 +2498,48 @@ void update_message_proxy_free(rdpUpdateProxy* message) static BOOL input_message_SynchronizeEvent(rdpInput* input, UINT32 flags) { - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, SynchronizeEvent), (void*) (size_t) flags, NULL); - return TRUE; } static BOOL input_message_KeyboardEvent(rdpInput* input, UINT16 flags, UINT16 code) { - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, KeyboardEvent), (void*) (size_t) flags, (void*) (size_t) code); - return TRUE; } static BOOL input_message_UnicodeKeyboardEvent(rdpInput* input, UINT16 flags, UINT16 code) { - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, UnicodeKeyboardEvent), (void*) (size_t) flags, (void*) (size_t) code); - return TRUE; } static BOOL input_message_MouseEvent(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { UINT32 pos = (x << 16) | y; - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, MouseEvent), (void*) (size_t) flags, (void*) (size_t) pos); - return TRUE; } static BOOL input_message_ExtendedMouseEvent(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { UINT32 pos = (x << 16) | y; - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, ExtendedMouseEvent), (void*) (size_t) flags, (void*) (size_t) pos); - return TRUE; } static BOOL input_message_FocusInEvent(rdpInput* input, UINT16 toggleStates) { - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, FocusInEvent), (void*) (size_t) toggleStates, NULL); - return TRUE; } static BOOL input_message_KeyboardPauseEvent(rdpInput* input) { - MessageQueue_Post(input->queue, (void*) input, + return MessageQueue_Post(input->queue, (void*) input, MakeMessageId(Input, KeyboardPauseEvent), NULL, NULL); - return TRUE; } /* Event Queue */ diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index d2d78da03..dbcffcdfc 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -211,7 +211,7 @@ int nla_client_init(rdpNla* nla) nla->ServicePrincipalName = spn; #endif - nla->table = InitSecurityInterfaceEx(SSPI_INTERFACE_WINPR); + nla->table = InitSecurityInterface(); nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo); if (nla->status != SEC_E_OK) @@ -498,7 +498,7 @@ int nla_server_init(rdpNla* nla) } else { - nla->table = InitSecurityInterfaceEx(0); + nla->table = InitSecurityInterface(); } nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 38f2218e1..bbde82a65 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -222,7 +222,7 @@ static BOOL freerdp_peer_initialize(freerdp_peer* client) if (!settings->RdpServerRsaKey) { - WLog_ERR(TAG, "inavlid RDP key file %s", settings->RdpKeyFile); + WLog_ERR(TAG, "invalid RDP key file %s", settings->RdpKeyFile); return FALSE; } } diff --git a/libfreerdp/core/server.c b/libfreerdp/core/server.c index 8f9072287..20f6e8809 100644 --- a/libfreerdp/core/server.c +++ b/libfreerdp/core/server.c @@ -85,22 +85,24 @@ static rdpPeerChannel* wts_get_dvc_channel_by_id(WTSVirtualChannelManager* vcm, return found ? channel : NULL; } -static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* Buffer, UINT32 Length) +static BOOL wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* Buffer, UINT32 Length) { BYTE* buffer; wtsChannelMessage* messageCtx; messageCtx = (wtsChannelMessage*) malloc(sizeof(wtsChannelMessage) + Length); + if (!messageCtx) + return FALSE; messageCtx->channelId = channel->channelId; messageCtx->length = Length; messageCtx->offset = 0; buffer = (BYTE*) (messageCtx + 1); CopyMemory(buffer, Buffer, Length); - MessageQueue_Post(channel->queue, messageCtx, 0, NULL, NULL); + return MessageQueue_Post(channel->queue, messageCtx, 0, NULL, NULL); } -static void wts_queue_send_item(rdpPeerChannel* channel, BYTE* Buffer, UINT32 Length) +static BOOL wts_queue_send_item(rdpPeerChannel* channel, BYTE* Buffer, UINT32 Length) { BYTE* buffer; UINT32 length; @@ -110,7 +112,7 @@ static void wts_queue_send_item(rdpPeerChannel* channel, BYTE* Buffer, UINT32 Le length = Length; channelId = channel->channelId; - MessageQueue_Post(channel->vcm->queue, (void*) (UINT_PTR) channelId, 0, (void*) buffer, (void*) (UINT_PTR) length); + return MessageQueue_Post(channel->vcm->queue, (void*) (UINT_PTR) channelId, 0, (void*) buffer, (void*) (UINT_PTR) length); } static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val) @@ -137,12 +139,12 @@ static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val) } } -static void wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT32 length) +static BOOL wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT32 length) { UINT16 Version; if (length < 3) - return; + return FALSE; Stream_Seek_UINT8(channel->receiveData); /* Pad (1 byte) */ Stream_Read_UINT16(channel->receiveData, Version); @@ -150,14 +152,15 @@ static void wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT DEBUG_DVC("Version: %d", Version); channel->vcm->drdynvc_state = DRDYNVC_STATE_READY; + return TRUE; } -static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s, UINT32 length) +static BOOL wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s, UINT32 length) { UINT32 CreationStatus; if (length < 4) - return; + return FALSE; Stream_Read_UINT32(s, CreationStatus); @@ -171,50 +174,55 @@ static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s DEBUG_DVC("ChannelId %d creation succeeded", channel->channelId); channel->dvc_open_state = DVC_OPEN_STATE_SUCCEEDED; } + return TRUE; } -static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, wStream* s, int cbLen, UINT32 length) +static BOOL wts_read_drdynvc_data_first(rdpPeerChannel* channel, wStream* s, int cbLen, UINT32 length) { int value; value = wts_read_variable_uint(s, cbLen, &channel->dvc_total_length); if (value == 0) - return; + return FALSE; length -= value; if (length > channel->dvc_total_length) - return; + return FALSE; Stream_SetPosition(channel->receiveData, 0); - Stream_EnsureRemainingCapacity(channel->receiveData, (int) channel->dvc_total_length); + if (!Stream_EnsureRemainingCapacity(channel->receiveData, (int) channel->dvc_total_length)) + return FALSE; Stream_Write(channel->receiveData, Stream_Pointer(s), length); + return TRUE; } -static void wts_read_drdynvc_data(rdpPeerChannel* channel, wStream* s, UINT32 length) +static BOOL wts_read_drdynvc_data(rdpPeerChannel* channel, wStream* s, UINT32 length) { + BOOL ret; if (channel->dvc_total_length > 0) { if (Stream_GetPosition(channel->receiveData) + length > channel->dvc_total_length) { channel->dvc_total_length = 0; - WLog_ERR(TAG, "incorrect fragment data, discarded."); - return; + WLog_ERR(TAG, "incorrect fragment data, discarded."); + return FALSE; } Stream_Write(channel->receiveData, Stream_Pointer(s), length); if (Stream_GetPosition(channel->receiveData) >= (int) channel->dvc_total_length) { - wts_queue_receive_data(channel, Stream_Buffer(channel->receiveData), channel->dvc_total_length); + ret = wts_queue_receive_data(channel, Stream_Buffer(channel->receiveData), channel->dvc_total_length); channel->dvc_total_length = 0; } } else { - wts_queue_receive_data(channel, Stream_Pointer(s), length); + ret = wts_queue_receive_data(channel, Stream_Pointer(s), length); } + return ret; } static void wts_read_drdynvc_close_response(rdpPeerChannel* channel) @@ -223,7 +231,7 @@ static void wts_read_drdynvc_close_response(rdpPeerChannel* channel) channel->dvc_open_state = DVC_OPEN_STATE_CLOSED; } -static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) +static BOOL wts_read_drdynvc_pdu(rdpPeerChannel* channel) { UINT32 length; int value; @@ -236,7 +244,7 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) length = Stream_GetPosition(channel->receiveData); if (length < 1) - return; + return FALSE; Stream_SetPosition(channel->receiveData, 0); Stream_Read_UINT8(channel->receiveData, value); @@ -248,14 +256,14 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) if (Cmd == CAPABILITY_REQUEST_PDU) { - wts_read_drdynvc_capabilities_response(channel, length); + return wts_read_drdynvc_capabilities_response(channel, length); } else if (channel->vcm->drdynvc_state == DRDYNVC_STATE_READY) { value = wts_read_variable_uint(channel->receiveData, cbChId, &ChannelId); if (value == 0) - return; + return FALSE; length -= value; @@ -267,16 +275,13 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) switch (Cmd) { case CREATE_REQUEST_PDU: - wts_read_drdynvc_create_response(dvc, channel->receiveData, length); - break; + return wts_read_drdynvc_create_response(dvc, channel->receiveData, length); case DATA_FIRST_PDU: - wts_read_drdynvc_data_first(dvc, channel->receiveData, Sp, length); - break; + return wts_read_drdynvc_data_first(dvc, channel->receiveData, Sp, length); case DATA_PDU: - wts_read_drdynvc_data(dvc, channel->receiveData, length); - break; + return wts_read_drdynvc_data(dvc, channel->receiveData, length); case CLOSE_REQUEST_PDU: wts_read_drdynvc_close_response(dvc); @@ -296,6 +301,7 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) { WLog_ERR(TAG, "received Cmd %d but channel is not ready.", Cmd); } + return TRUE; } static int wts_write_variable_uint(wStream* s, UINT32 val) @@ -344,32 +350,37 @@ static BOOL wts_write_drdynvc_create_request(wStream *s, UINT32 ChannelId, const return TRUE; } -static void WTSProcessChannelData(rdpPeerChannel* channel, UINT16 channelId, BYTE* data, int size, int flags, int totalSize) +static BOOL WTSProcessChannelData(rdpPeerChannel* channel, UINT16 channelId, BYTE* data, int size, int flags, int totalSize) { + BOOL ret = TRUE; + if (flags & CHANNEL_FLAG_FIRST) { Stream_SetPosition(channel->receiveData, 0); } - Stream_EnsureRemainingCapacity(channel->receiveData, size); + if (!Stream_EnsureRemainingCapacity(channel->receiveData, size)) + return FALSE; Stream_Write(channel->receiveData, data, size); if (flags & CHANNEL_FLAG_LAST) { if (Stream_GetPosition(channel->receiveData) != totalSize) { - WLog_ERR(TAG, "read error"); + WLog_ERR(TAG, "read error"); } if (channel == channel->vcm->drdynvc_channel) { - wts_read_drdynvc_pdu(channel); + ret = wts_read_drdynvc_pdu(channel); } else { - wts_queue_receive_data(channel, Stream_Buffer(channel->receiveData), Stream_GetPosition(channel->receiveData)); + ret = wts_queue_receive_data(channel, Stream_Buffer(channel->receiveData), Stream_GetPosition(channel->receiveData)); } Stream_SetPosition(channel->receiveData, 0); } + + return ret; } static int WTSReceiveChannelData(freerdp_peer* client, UINT16 channelId, BYTE* data, int size, int flags, int totalSize) @@ -1191,6 +1202,7 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, UINT32 length; UINT32 written; rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + BOOL ret = TRUE; if (!channel) return FALSE; @@ -1198,10 +1210,12 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, if (channel->channelType == RDP_PEER_CHANNEL_TYPE_SVC) { length = Length; - buffer = (BYTE*) malloc(length); + buffer = (BYTE *)malloc(length); + if (!buffer) + return FALSE; CopyMemory(buffer, Buffer, length); - wts_queue_send_item(channel, buffer, length); + ret = wts_queue_send_item(channel, buffer, length); } else if (!channel->vcm->drdynvc_channel || (channel->vcm->drdynvc_state != DRDYNVC_STATE_READY)) { @@ -1220,6 +1234,7 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, WLog_ERR(TAG, "Stream_New failed!"); return FALSE; } + buffer = Stream_Buffer(s); Stream_Seek_UINT8(s); @@ -1248,14 +1263,14 @@ BOOL WINAPI FreeRDP_WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, Length -= written; Buffer += written; - wts_queue_send_item(channel->vcm->drdynvc_channel, buffer, length); + ret = wts_queue_send_item(channel->vcm->drdynvc_channel, buffer, length); } } if (pBytesWritten) *pBytesWritten = Length; - return TRUE; + return ret; } BOOL WINAPI FreeRDP_WTSVirtualChannelPurgeInput(HANDLE hChannelHandle) diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 8015a4118..339baa684 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -28,6 +28,8 @@ #include #endif +#include + #include #include #include @@ -195,13 +197,14 @@ void settings_get_computer_name(rdpSettings* settings) GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); settings->ComputerName = (char*) malloc(nSize); - if (!settings->ComputerName) - return; + if (!settings->ComputerName) + return; GetComputerNameExA(ComputerNameNetBIOS, settings->ComputerName, &nSize); } rdpSettings* freerdp_settings_new(DWORD flags) { + char* base; rdpSettings* settings; settings = (rdpSettings*) calloc(1, sizeof(rdpSettings)); @@ -471,7 +474,34 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->HomePath = GetKnownPath(KNOWN_PATH_HOME); if (!settings->HomePath) goto out_fail; - settings->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp"); + + /* For default FreeRDP continue using same config directory + * as in old releases. + * Custom builds use / as config folder. */ + if (_stricmp(FREERDP_VENDOR_STRING, FREERDP_PRODUCT_STRING)) + { + base = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, + FREERDP_VENDOR_STRING); + if (base) + { + settings->ConfigPath = GetCombinedPath( + base, + FREERDP_PRODUCT_STRING); + } + free (base); + } else { + int i; + char product[sizeof(FREERDP_PRODUCT_STRING)]; + + memset(product, 0, sizeof(product)); + for (i=0; iConfigPath = GetKnownSubPath( + KNOWN_PATH_XDG_CONFIG_HOME, + product); + } + if (!settings->ConfigPath) goto out_fail; @@ -778,7 +808,7 @@ out_fail: void freerdp_settings_free(rdpSettings* settings) { if (!settings) - return; + return; free(settings->ServerHostname); free(settings->Username); free(settings->Password); diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index fbe804d00..74263467b 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -35,13 +36,18 @@ static const char certificate_store_dir[] = "certs"; static const char certificate_server_dir[] = "server"; -static const char certificate_known_hosts_file[] = "known_hosts"; +static const char certificate_known_hosts_file[] = "known_hosts2"; +static const char certificate_legacy_hosts_file[] = "known_hosts"; #include #include #define TAG FREERDP_TAG("crypto") +static BOOL certificate_split_line(char* line, char** host, UINT16* port, + char**subject, char**issuer, + char** fingerprint); + BOOL certificate_store_init(rdpCertificateStore* certificate_store) { char* server_path = NULL; @@ -51,12 +57,12 @@ BOOL certificate_store_init(rdpCertificateStore* certificate_store) if (!PathFileExistsA(settings->ConfigPath)) { - if (!CreateDirectoryA(settings->ConfigPath, 0)) + if (!PathMakePathA(settings->ConfigPath, 0)) { - WLog_ERR(TAG, "error creating directory '%s'", settings->ConfigPath); + WLog_ERR(TAG, "error creating directory '%s'", settings->ConfigPath); goto fail; } - WLog_INFO(TAG, "creating directory %s", settings->ConfigPath); + WLog_INFO(TAG, "creating directory %s", settings->ConfigPath); } if (!(certificate_store->path = GetCombinedPath(settings->ConfigPath, (char*) certificate_store_dir))) @@ -64,12 +70,12 @@ BOOL certificate_store_init(rdpCertificateStore* certificate_store) if (!PathFileExistsA(certificate_store->path)) { - if (!CreateDirectoryA(certificate_store->path, 0)) + if (!PathMakePathA(certificate_store->path, 0)) { - WLog_ERR(TAG, "error creating directory [%s]", certificate_store->path); + WLog_ERR(TAG, "error creating directory [%s]", certificate_store->path); goto fail; } - WLog_INFO(TAG, "creating directory [%s]", certificate_store->path); + WLog_INFO(TAG, "creating directory [%s]", certificate_store->path); } if (!(server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir))) @@ -77,34 +83,27 @@ BOOL certificate_store_init(rdpCertificateStore* certificate_store) if (!PathFileExistsA(server_path)) { - if (!CreateDirectoryA(server_path, 0)) + if (!PathMakePathA(server_path, 0)) { - WLog_ERR(TAG, "error creating directory [%s]", server_path); + WLog_ERR(TAG, "error creating directory [%s]", server_path); goto fail; } - WLog_INFO(TAG, "created directory [%s]", server_path); + WLog_INFO(TAG, "created directory [%s]", server_path); } if (!(certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file))) goto fail; - if (!PathFileExistsA(certificate_store->file)) - certificate_store->fp = fopen((char*) certificate_store->file, "w+"); - else - certificate_store->fp = fopen((char*) certificate_store->file, "r+"); - - if (!certificate_store->fp) - { - WLog_ERR(TAG, "error opening [%s]", certificate_store->file); + if (!(certificate_store->legacy_file = GetCombinedPath(settings->ConfigPath, + (char*) certificate_legacy_hosts_file))) goto fail; - } free(server_path); return TRUE; fail: - WLog_ERR(TAG, "certificate store initialization failed"); + WLog_ERR(TAG, "certificate store initialization failed"); free(server_path); free(certificate_store->path); free(certificate_store->file); @@ -113,16 +112,111 @@ fail: return FALSE; } -int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) +static int certificate_data_match_legacy(rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data) { + FILE* fp; + int match = 1; + char* data; + char* mdata; + char* pline; + char* hostname; + long size; + size_t length; + + fp = fopen(certificate_store->legacy_file, "rb"); + if (!fp) + return match; + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (size < 1) + { + fclose(fp); + return match; + } + + mdata = (char*) malloc(size + 2); + if (!mdata) + { + fclose(fp); + return match; + } + + data = mdata; + if (fread(data, size, 1, fp) != 1) + { + free(data); + fclose(fp); + return match; + } + + fclose(fp); + + data[size] = '\n'; + data[size + 1] = '\0'; + pline = StrSep(&data, "\r\n"); + + while (pline != NULL) + { + length = strlen(pline); + + if (length > 0) + { + hostname = StrSep(&pline, " \t"); + if (!hostname || !pline) + WLog_WARN(TAG, "Invalid %s entry %s %s!", certificate_legacy_hosts_file, + hostname, pline); + else if (strcmp(hostname, certificate_data->hostname) == 0) + { + match = strcmp(pline, certificate_data->fingerprint); + break; + } + } + + pline = StrSep(&data, "\r\n"); + } + free(mdata); + + /* Found a valid fingerprint in legacy file, + * copy to new file in new format. */ + if (0 == match) + { + rdpCertificateData* data = certificate_data_new(hostname, + certificate_data->port, + NULL, NULL, + pline); + if (data) + match = certificate_data_print(certificate_store, data) ? 0 : 1; + certificate_data_free(data); + } + + return match; + +} + +static int certificate_data_match_raw(rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data, + char** psubject, char** pissuer, + char** fprint) +{ + BOOL found = FALSE; FILE* fp; int length; char* data; + char* mdata; char* pline; int match = 1; long int size; + char* hostname = NULL; + char* subject = NULL; + char* issuer = NULL; + char* fingerprint = NULL; + unsigned short port = 0; - fp = certificate_store->fp; + fp = fopen(certificate_store->file, "rb"); if (!fp) return match; @@ -132,19 +226,30 @@ int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificat fseek(fp, 0, SEEK_SET); if (size < 1) - return match; - - data = (char*) malloc(size + 2); - - if (fread(data, size, 1, fp) != 1) { - free(data); + fclose(fp); return match; } + mdata = (char*) malloc(size + 2); + if (!mdata) + { + fclose(fp); + return match; + } + + data = mdata; + if (fread(data, size, 1, fp) != 1) + { + fclose(fp); + free(data); + return match; + } + fclose(fp); + data[size] = '\n'; data[size + 1] = '\0'; - pline = strtok(data, "\n"); + pline = StrSep(&data, "\r\n"); while (pline != NULL) { @@ -152,62 +257,115 @@ int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificat if (length > 0) { - length = strcspn(pline, " \t"); - pline[length] = '\0'; - - if (strcmp(pline, certificate_data->hostname) == 0) + if (!certificate_split_line(pline, &hostname, &port, + &subject, &issuer, &fingerprint)) + WLog_WARN(TAG, "Invalid %s entry %s!", + certificate_known_hosts_file, pline); + else if (strcmp(pline, certificate_data->hostname) == 0) { - pline = &pline[length + 1]; + int outLen; - if (strcmp(pline, certificate_data->fingerprint) == 0) - match = 0; - else - match = -1; - break; + if (port == certificate_data->port) + { + found = TRUE; + match = strcmp(certificate_data->fingerprint, fingerprint); + if (fingerprint && fprint) + *fprint = _strdup(fingerprint); + if (subject && psubject) + crypto_base64_decode(subject, strlen(subject), (BYTE**)psubject, &outLen); + if (issuer && pissuer) + crypto_base64_decode(issuer, strlen(issuer), (BYTE**)pissuer, &outLen); + break; + } } } - pline = strtok(NULL, "\n"); + pline = StrSep(&data, "\r\n"); } - free(data); + free(mdata); + + if ((match != 0) && !found) + match = certificate_data_match_legacy(certificate_store, certificate_data); return match; } -void certificate_data_replace(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) +BOOL certificate_get_stored_data(rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data, + char** subject, char** issuer, + char** fingerprint) +{ + int rc = certificate_data_match_raw(certificate_store, certificate_data, + subject, issuer, fingerprint); + + if ((rc == 0) || (rc == -1)) + return TRUE; + return FALSE; +} + +int certificate_data_match(rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data) +{ + return certificate_data_match_raw(certificate_store, certificate_data, + NULL, NULL, NULL); +} + +BOOL certificate_data_replace(rdpCertificateStore* certificate_store, + rdpCertificateData* certificate_data) { FILE* fp; + BOOL rc = FALSE; int length; char* data; + char* sdata; char* pline; long int size; - fp = certificate_store->fp; + fp = fopen(certificate_store->file, "rb"); if (!fp) - return; - + return FALSE; + /* Read the current contents of the file. */ fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); if (size < 1) - return; + { + fclose(fp); + return FALSE; + } data = (char*) malloc(size + 2); + if (!data) + { + fclose(fp); + return FALSE; + } if (fread(data, size, 1, fp) != 1) { + fclose(fp); free(data); - return; + return FALSE; } - + + fclose(fp); + + fp = fopen(certificate_store->file, "wb"); + + if (!fp) + { + free(data); + return FALSE; + } + /* Write the file back out, with appropriate fingerprint substitutions */ - fp = fopen(certificate_store->file, "w+"); data[size] = '\n'; data[size + 1] = '\0'; - pline = strtok(data, "\n"); // xxx: use strsep + sdata = data; + pline = StrSep(&sdata, "\r\n"); while (pline != NULL) { @@ -215,60 +373,135 @@ void certificate_data_replace(rdpCertificateStore* certificate_store, rdpCertifi if (length > 0) { - char* hostname = pline, *fingerprint; - - length = strcspn(pline, " \t"); - hostname[length] = '\0'; + UINT16 port = 0; + char* hostname = NULL; + char* fingerprint = NULL; + char* subject = NULL; + char* issuer = NULL; - /* If this is the replaced hostname, use the updated fingerprint. */ - if (strcmp(hostname, certificate_data->hostname) == 0) - fingerprint = certificate_data->fingerprint; + if (!certificate_split_line(pline, &hostname, &port, &subject, &issuer, &fingerprint)) + WLog_WARN(TAG, "Skipping invalid %s entry %s!", + certificate_known_hosts_file, pline); else - fingerprint = &hostname[length + 1]; - - fprintf(fp, "%s %s\n", hostname, fingerprint); + { + /* If this is the replaced hostname, use the updated fingerprint. */ + if ((strcmp(hostname, certificate_data->hostname) == 0) && + (port == certificate_data->port)) + { + fingerprint = certificate_data->fingerprint; + rc = TRUE; + } + fprintf(fp, "%s %hu %s %s %s\n", hostname, port, fingerprint, subject, issuer); + } } - pline = strtok(NULL, "\n"); + pline = StrSep(&sdata, "\r\n"); } - + fclose(fp); - free(data); + free(data); + + return rc; } -void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) +BOOL certificate_split_line(char* line, char** host, UINT16* port, char** subject, + char** issuer, char** fingerprint) +{ + char* cur; + size_t length = strlen(line); + + if (length <= 0) + return FALSE; + + cur = StrSep(&line, " \t"); + if (!cur) + return FALSE; + *host = cur; + + cur = StrSep(&line, " \t"); + if (!cur) + return FALSE; + + if(sscanf(cur, "%hu", port) != 1) + return FALSE; + + cur = StrSep(&line, " \t"); + if (!cur) + return FALSE; + + *fingerprint = cur; + + cur = StrSep(&line, " \t"); + if (!cur) + return FALSE; + + *subject = cur; + + cur = StrSep(&line, " \t"); + if (!cur) + return FALSE; + + *issuer = cur; + + return TRUE; +} + +BOOL certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) { FILE* fp; /* reopen in append mode */ - fp = fopen(certificate_store->file, "a"); + fp = fopen(certificate_store->file, "ab"); if (!fp) - return; + return FALSE; + + fprintf(fp, "%s %hu %s %s %s\n", certificate_data->hostname, certificate_data->port, + certificate_data->fingerprint, certificate_data->subject, + certificate_data->issuer); - fprintf(fp, "%s %s\n", certificate_data->hostname, certificate_data->fingerprint); fclose(fp); + + return TRUE; } -rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint) +rdpCertificateData* certificate_data_new(char* hostname, UINT16 port, char* subject, char* issuer, char* fingerprint) { rdpCertificateData* certdata; + if (!hostname) + return NULL; + + if (!fingerprint) + return NULL; + certdata = (rdpCertificateData *)calloc(1, sizeof(rdpCertificateData)); if (!certdata) return NULL; + certdata->port = port; certdata->hostname = _strdup(hostname); - if (!certdata->hostname) - goto out_free; + if (subject) + certdata->subject = crypto_base64_encode((BYTE*)subject, strlen(subject)); + else + certdata->subject = crypto_base64_encode((BYTE*)"", 0); + if (issuer) + certdata->issuer = crypto_base64_encode((BYTE*)issuer, strlen(subject)); + else + certdata->issuer = crypto_base64_encode((BYTE*)"", 0); certdata->fingerprint = _strdup(fingerprint); - if (!certdata->fingerprint) - goto out_free_hostname; + + if (!certdata->hostname || !certdata->subject || + !certdata->issuer || !certdata->fingerprint) + goto fail; + return certdata; -out_free_hostname: +fail: free(certdata->hostname); -out_free: + free(certdata->subject); + free(certdata->issuer); + free(certdata->fingerprint); free(certdata); return NULL; } @@ -278,6 +511,8 @@ void certificate_data_free(rdpCertificateData* certificate_data) if (certificate_data != NULL) { free(certificate_data->hostname); + free(certificate_data->subject); + free(certificate_data->issuer); free(certificate_data->fingerprint); free(certificate_data); } @@ -307,9 +542,6 @@ void certificate_store_free(rdpCertificateStore* certstore) { if (certstore != NULL) { - if (certstore->fp != NULL) - fclose(certstore->fp); - free(certstore->path); free(certstore->file); free(certstore); diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 3c54c2c3b..b82f38b54 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -288,7 +288,7 @@ static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, c BN_free(&mod); BN_CTX_free(ctx); -out_free_input_reverse: +out_free_input_reverse: free(input_reverse); return output_length; @@ -376,7 +376,7 @@ char* crypto_print_name(X509_NAME* name) { char* buffer = NULL; BIO* outBIO = BIO_new(BIO_s_mem()); - + if (X509_NAME_print_ex(outBIO, name, 0, XN_FLAG_ONELINE) > 0) { unsigned long size = BIO_number_written(outBIO); @@ -433,7 +433,7 @@ char* crypto_cert_subject_common_name(X509* xcert, int* length) } FREERDP_API void crypto_cert_subject_alt_name_free(int count, int *lengths, - char** alt_name) + char** alt_name) { int i; @@ -555,8 +555,10 @@ end: return status; } -rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname) +rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname, UINT16 port) { + char* issuer; + char* subject; char* fp; rdpCertificateData* certdata; @@ -564,7 +566,13 @@ rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname) if (!fp) return NULL; - certdata = certificate_data_new(hostname, fp); + issuer = crypto_cert_issuer(xcert); + subject = crypto_cert_subject(xcert); + + certdata = certificate_data_new(hostname, port, issuer, subject, fp); + + free(subject); + free(issuer); free(fp); return certdata; @@ -590,8 +598,8 @@ void crypto_cert_print_info(X509* xcert) WLog_INFO(TAG, "\tIssuer: %s", issuer); WLog_INFO(TAG, "\tThumbprint: %s", fp); WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA."); + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA."); free(fp); out_free_issuer: free(issuer); diff --git a/libfreerdp/crypto/test/CMakeLists.txt b/libfreerdp/crypto/test/CMakeLists.txt index 86f5faf23..acaf43ed7 100644 --- a/libfreerdp/crypto/test/CMakeLists.txt +++ b/libfreerdp/crypto/test/CMakeLists.txt @@ -5,6 +5,7 @@ set(MODULE_PREFIX "TEST_FREERDP_CRYPTO") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS + TestKnownHosts.c TestBase64.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS diff --git a/libfreerdp/crypto/test/TestKnownHosts.c b/libfreerdp/crypto/test/TestKnownHosts.c new file mode 100644 index 000000000..0adf02ddf --- /dev/null +++ b/libfreerdp/crypto/test/TestKnownHosts.c @@ -0,0 +1,322 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 Armin Novak + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +static int prepare(const char* currentFileV2, const char* legacyFileV2, const char* legacyFile) +{ + char* legacy[] = { + "someurl ff:11:22:dd\r\n", + "otherurl aa:bb:cc:dd\r", + "legacyurl aa:bb:cc:dd\n" + }; + char* hosts[] = { + "someurl 3389 ff:11:22:dd subject issuer\r\n", + "otherurl\t3389\taa:bb:cc:dd\tsubject2\tissuer2\r", + }; + FILE* fl = NULL; + FILE* fc = NULL; + size_t i; + + fc = fopen(currentFileV2, "w+"); + if (!fc) + goto finish; + + fl = fopen(legacyFileV2, "w+"); + if (!fl) + goto finish; + + for (i=0; ibio = BIO_new_rdp_tls(tls->ctx, clientMode); if (BIO_get_ssl(tls->bio, &tls->ssl) < 0) @@ -761,7 +761,7 @@ int tls_connect(rdpTls* tls, BIO* underlying) #ifndef OPENSSL_NO_TLSEXT static void tls_openssl_tlsext_debug_callback(SSL *s, int client_server, - int type, unsigned char *data, int len, void *arg) + int type, unsigned char *data, int len, void *arg) { /* see code comment in tls_accept() below */ @@ -796,7 +796,7 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, const char* cert_file, const char* #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif - + /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * @@ -994,7 +994,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por */ bio = BIO_new(BIO_s_mem()); - + if (!bio) { WLog_ERR(TAG, "BIO_new() failure"); @@ -1008,19 +1008,19 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status); return -1; } - + offset = 0; length = 2048; pemCert = (BYTE*) malloc(length + 1); status = BIO_read(bio, pemCert, length); - + if (status < 0) { WLog_ERR(TAG, "failed to read certificate"); return -1; } - + offset += status; while (offset >= length) @@ -1048,17 +1048,17 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por WLog_ERR(TAG, "failed to read certificate"); return -1; } - + length = offset; pemCert[length] = '\0'; status = -1; - + if (instance->VerifyX509Certificate) { status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); } - + WLog_ERR(TAG, "(length = %d) status: %d%s", length, status, pemCert); free(pemCert); @@ -1082,7 +1082,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por certificate_status = x509_verify_certificate(cert, tls->certificate_store->path); /* verify certificate name match */ - certificate_data = crypto_get_certificate_data(cert->px509, hostname); + certificate_data = crypto_get_certificate_data(cert->px509, hostname, port); /* extra common name and alternative names */ common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length); @@ -1124,7 +1124,9 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por /* if the certificate is valid but the certificate name does not match, warn user, do not accept */ if (certificate_status && !hostname_match) - tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); + tls_print_certificate_name_mismatch_error(hostname, port, + common_name, alt_names, + alt_names_count); /* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */ @@ -1147,7 +1149,10 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por { /* no entry was found in known_hosts file, prompt user for manual verification */ if (!hostname_match) - tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); + tls_print_certificate_name_mismatch_error( + hostname, port, + common_name, alt_names, + alt_names_count); if (instance->VerifyCertificate) { @@ -1162,20 +1167,35 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por else { /* user accepted certificate, add entry in known_hosts file */ - certificate_data_print(tls->certificate_store, certificate_data); - verification_status = TRUE; /* success! */ + verification_status = certificate_data_print(tls->certificate_store, certificate_data); } } else if (match == -1) { + char* old_subject = NULL; + char* old_issuer = NULL; + char* old_fingerprint = NULL; + /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ - tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file); - + tls_print_certificate_error(hostname, port, fingerprint, + tls->certificate_store->file); + + if (!certificate_get_stored_data(tls->certificate_store, + certificate_data, &old_subject, + &old_issuer, &old_fingerprint)) + WLog_WARN(TAG, "Failed to get certificate entry for %s:hu", + hostname, port); + if (instance->VerifyChangedCertificate) { - accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, ""); + accept_certificate = instance->VerifyChangedCertificate( + instance, subject, issuer, + fingerprint, old_subject, old_issuer, + old_fingerprint); } + free(old_fingerprint); + if (!accept_certificate) { /* user did not accept, abort and do not change known_hosts file */ @@ -1184,8 +1204,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por else { /* user accepted new certificate, add replace fingerprint for this host in known_hosts file */ - certificate_data_replace(tls->certificate_store, certificate_data); - verification_status = TRUE; /* success! */ + verification_status = certificate_data_replace(tls->certificate_store, certificate_data); } } else if (match == 0) @@ -1211,14 +1230,15 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (alt_names) crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths, - alt_names); + alt_names); return (verification_status == 0) ? 0 : 1; } -void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file) +void tls_print_certificate_error(char* hostname, UINT16 port, char* fingerprint, + char *hosts_file) { - WLog_ERR(TAG, "The host key for %s has changed", hostname); + WLog_ERR(TAG, "The host key for %s:%hu has changed", hostname, port); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -1232,7 +1252,9 @@ void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_ WLog_ERR(TAG, "Host key verification failed."); } -void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count) +void tls_print_certificate_name_mismatch_error(char* hostname, UINT16 port, + char* common_name, char** alt_names, + int alt_names_count) { int index; @@ -1240,8 +1262,10 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@ WARNING: CERTIFICATE NAME MISMATCH! @"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - WLog_ERR(TAG, "The hostname used for this connection (%s) ", hostname); - WLog_ERR(TAG, "does not match %s given in the certificate:", alt_names_count < 1 ? "the name" : "any of the names"); + WLog_ERR(TAG, "The hostname used for this connection (%s:%hu) ", + hostname, port); + WLog_ERR(TAG, "does not match %s given in the certificate:", + alt_names_count < 1 ? "the name" : "any of the names"); WLog_ERR(TAG, "Common Name (CN):"); WLog_ERR(TAG, "\t%s", common_name ? common_name : "no CN found in certificate"); if (alt_names_count > 0) diff --git a/packaging/deb/freerdp-nightly/freerdp-nightly-dev.install b/packaging/deb/freerdp-nightly/freerdp-nightly-dev.install index 11d3295cf..99ce27cf4 100644 --- a/packaging/deb/freerdp-nightly/freerdp-nightly-dev.install +++ b/packaging/deb/freerdp-nightly/freerdp-nightly-dev.install @@ -1,4 +1,6 @@ +opt/freerdp-nightly/lib/*.a opt/freerdp-nightly/lib/*.so +opt/freerdp-nightly/lib/freerdp/*.a opt/freerdp-nightly/lib/pkgconfig opt/freerdp-nightly/lib/cmake opt/freerdp-nightly/include diff --git a/packaging/deb/freerdp-nightly/rules b/packaging/deb/freerdp-nightly/rules index 44ceb5671..963cbbf70 100755 --- a/packaging/deb/freerdp-nightly/rules +++ b/packaging/deb/freerdp-nightly/rules @@ -35,8 +35,6 @@ override_dh_strip: dh_strip --dbg-package=freerdp-nightly-dbg override_dh_install: - rm -f debian/tmp/opt/freerdp-nightly/lib/libwinpr-makecert-tool.a - rm -f debian/tmp/opt/freerdp-nightly/lib/freerdp/*.a mkdir -p debian/tmp/opt/freerdp-nightly/lib/cmake/ dh_install --fail-missing diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index da7d07202..70fc36ab6 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -362,9 +362,7 @@ int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem) msg->xPos = subsystem->pointerX; msg->yPos = subsystem->pointerY; - MessageQueue_Post(MsgPipe->Out, NULL, msgId, (void*) msg, NULL); - - return 1; + return MessageQueue_Post(MsgPipe->Out, NULL, msgId, (void*) msg, NULL) ? 1 : -1; } int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem) @@ -395,9 +393,7 @@ int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem) CopyMemory(msg->pixels, subsystem->cursorPixels, msg->scanline * msg->height); msg->premultiplied = TRUE; - MessageQueue_Post(MsgPipe->Out, NULL, msgId, (void*) msg, NULL); - - return 1; + return MessageQueue_Post(MsgPipe->Out, NULL, msgId, (void*) msg, NULL) ? 1 : -1; } int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage) @@ -1295,8 +1291,8 @@ int x11_shadow_subsystem_stop(x11ShadowSubsystem* subsystem) if (subsystem->thread) { - MessageQueue_PostQuit(subsystem->MsgPipe->In, 0); - WaitForSingleObject(subsystem->thread, INFINITE); + if (MessageQueue_PostQuit(subsystem->MsgPipe->In, 0)) + WaitForSingleObject(subsystem->thread, INFINITE); CloseHandle(subsystem->thread); subsystem->thread = NULL; } diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 12f52866a..e332688d9 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -251,17 +251,17 @@ BOOL shadow_client_post_connect(freerdp_peer* peer) return TRUE; } -void shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_16* areas) +BOOL shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_16* areas) { wMessage message = { 0 }; SHADOW_MSG_IN_REFRESH_OUTPUT* wParam; wMessagePipe* MsgPipe = client->subsystem->MsgPipe; - if (!areas) - return; + if (count && !areas) + return FALSE; if (!(wParam = (SHADOW_MSG_IN_REFRESH_OUTPUT*) calloc(1, sizeof(SHADOW_MSG_IN_REFRESH_OUTPUT)))) - return; + return FALSE; wParam->numRects = (UINT32) count; @@ -272,11 +272,11 @@ void shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_1 if (!wParam->rects) { free (wParam); - return; + return FALSE; } - } - CopyMemory(wParam->rects, areas, wParam->numRects * sizeof(RECTANGLE_16)); + CopyMemory(wParam->rects, areas, wParam->numRects * sizeof(RECTANGLE_16)); + } message.id = SHADOW_MSG_IN_REFRESH_OUTPUT_ID; message.wParam = (void*) wParam; @@ -284,19 +284,18 @@ void shadow_client_refresh_rect(rdpShadowClient* client, BYTE count, RECTANGLE_1 message.context = (void*) client; message.Free = shadow_client_message_free; - MessageQueue_Dispatch(MsgPipe->In, &message); + return MessageQueue_Dispatch(MsgPipe->In, &message); } -void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area) +BOOL shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area) { wMessage message = { 0 }; SHADOW_MSG_IN_SUPPRESS_OUTPUT* wParam; wMessagePipe* MsgPipe = client->subsystem->MsgPipe; wParam = (SHADOW_MSG_IN_SUPPRESS_OUTPUT*) calloc(1, sizeof(SHADOW_MSG_IN_SUPPRESS_OUTPUT)); - if (!wParam) - return; + return FALSE; wParam->allow = (UINT32) allow; @@ -309,7 +308,7 @@ void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGL message.context = (void*) client; message.Free = shadow_client_message_free; - MessageQueue_Dispatch(MsgPipe->In, &message); + return MessageQueue_Dispatch(MsgPipe->In, &message); } BOOL shadow_client_activate(freerdp_peer* peer) @@ -334,12 +333,10 @@ BOOL shadow_client_activate(freerdp_peer* peer) shadow_encoder_reset(client->encoder); - shadow_client_refresh_rect(client, 0, NULL); - - return TRUE; + return shadow_client_refresh_rect(client, 0, NULL); } -void shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId) +BOOL shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId) { SURFACE_FRAME* frame; wListDictionary* frameList; @@ -352,6 +349,7 @@ void shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 fra ListDictionary_Remove(frameList, (void*) (size_t) frameId); free(frame); } + return TRUE; } int shadow_client_send_surface_frame_marker(rdpShadowClient* client, UINT32 action, UINT32 id) @@ -445,6 +443,7 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s cmd.bpp = 32; cmd.width = surface->width; cmd.height = surface->height; + cmd.skipCompression = TRUE; if (numMessages > 0) messageRects = messages[0].rects; @@ -982,9 +981,9 @@ void* shadow_client_thread(rdpShadowClient* client) peer->Initialize(peer); - peer->update->RefreshRect = (pRefreshRect) shadow_client_refresh_rect; - peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output; - peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge) shadow_client_surface_frame_acknowledge; + peer->update->RefreshRect = (pRefreshRect)shadow_client_refresh_rect; + peer->update->SuppressOutput = (pSuppressOutput)shadow_client_suppress_output; + peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge)shadow_client_surface_frame_acknowledge; if ((!client->StopEvent) || (!client->vcm) || (!subsystem->updateEvent)) goto out; diff --git a/server/shadow/shadow_screen.c b/server/shadow/shadow_screen.c index 3182b642c..ff767b274 100644 --- a/server/shadow/shadow_screen.c +++ b/server/shadow/shadow_screen.c @@ -28,7 +28,6 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server) { int x, y; int width, height; - MONITOR_DEF* primary; rdpShadowScreen* screen; rdpShadowSubsystem* subsystem; @@ -45,12 +44,21 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server) region16_init(&(screen->invalidRegion)); - primary = &(subsystem->monitors[subsystem->selectedMonitor]); + if (server->shareSubRect) { + x = server->subRect.left; + y = server->subRect.top; + width = server->subRect.right - server->subRect.left; + height = server->subRect.bottom - server->subRect.top; + } else { + MONITOR_DEF* primary; - x = primary->left; - y = primary->top; - width = primary->right - primary->left; - height = primary->bottom - primary->top; + primary = &(subsystem->monitors[subsystem->selectedMonitor]); + + x = primary->left; + y = primary->top; + width = primary->right - primary->left; + height = primary->bottom - primary->top; + } screen->width = width; screen->height = height; diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index aaf037d2e..79568f1dd 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -346,10 +346,12 @@ void* shadow_server_thread(rdpShadowServer* server) /* Signal to the clients that server is being stopped and wait for them * to disconnect. */ - MessageQueue_PostQuit(subsystem->MsgPipe->Out, 0); - while(ArrayList_Count(server->clients) > 0) + if (MessageQueue_PostQuit(subsystem->MsgPipe->Out, 0)) { - Sleep(100); + while(ArrayList_Count(server->clients) > 0) + { + Sleep(100); + } } ExitThread(0); @@ -443,7 +445,7 @@ int shadow_server_init_config_path(rdpShadowServer* server) if (userLibraryPath) { if (!PathFileExistsA(userLibraryPath) && - !CreateDirectoryA(userLibraryPath, 0)) + !PathMakePathA(userLibraryPath, 0)) { WLog_ERR(TAG, "Failed to create directory '%s'", userLibraryPath); free(userLibraryPath); @@ -455,7 +457,7 @@ int shadow_server_init_config_path(rdpShadowServer* server) if (userApplicationSupportPath) { if (!PathFileExistsA(userApplicationSupportPath) && - !CreateDirectoryA(userApplicationSupportPath, 0)) + !PathMakePathA(userApplicationSupportPath, 0)) { WLog_ERR(TAG, "Failed to create directory '%s'", userApplicationSupportPath); free(userLibraryPath); @@ -480,7 +482,7 @@ int shadow_server_init_config_path(rdpShadowServer* server) if (configHome) { if (!PathFileExistsA(configHome) && - !CreateDirectoryA(configHome, 0)) + !PathMakePathA(configHome, 0)) { WLog_ERR(TAG, "Failed to create directory '%s'", configHome); free(configHome); @@ -514,7 +516,7 @@ int shadow_server_init_certificate(rdpShadowServer* server) int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); if (!PathFileExistsA(server->ConfigPath) && - !CreateDirectoryA(server->ConfigPath, 0)) + !PathMakePathA(server->ConfigPath, 0)) { WLog_ERR(TAG, "Failed to create directory '%s'", server->ConfigPath); return -1; @@ -524,7 +526,7 @@ int shadow_server_init_certificate(rdpShadowServer* server) return -1; if (!PathFileExistsA(filepath) && - !CreateDirectoryA(filepath, 0)) + !PathMakePathA(filepath, 0)) { WLog_ERR(TAG, "Failed to create directory '%s'", filepath); free(filepath); diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index fb478b97d..e4967888b 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -477,9 +477,9 @@ WINPR_API HANDLE MessageQueue_Event(wMessageQueue* queue); WINPR_API BOOL MessageQueue_Wait(wMessageQueue* queue); WINPR_API int MessageQueue_Size(wMessageQueue* queue); -WINPR_API void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message); -WINPR_API void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam); -WINPR_API void MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode); +WINPR_API BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message); +WINPR_API BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam); +WINPR_API BOOL MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode); WINPR_API int MessageQueue_Get(wMessageQueue* queue, wMessage* message); WINPR_API int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove); diff --git a/winpr/include/winpr/file.h b/winpr/include/winpr/file.h index 80f89507f..45ec3e698 100644 --- a/winpr/include/winpr/file.h +++ b/winpr/include/winpr/file.h @@ -291,6 +291,9 @@ WINPR_API BOOL FindClose(HANDLE hFindFile); WINPR_API BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); +WINPR_API BOOL RemoveDirectoryA(LPCSTR lpPathName); +WINPR_API BOOL RemoveDirectoryW(LPCWSTR lpPathName); + #ifdef __cplusplus } #endif @@ -302,6 +305,7 @@ WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecu #define FindFirstFileEx FindFirstFileExW #define FindNextFile FindNextFileW #define CreateDirectory CreateDirectoryW +#define RemoveDirectory RemoveDirectoryW #else #define CreateFile CreateFileA #define DeleteFile DeleteFileA @@ -309,6 +313,7 @@ WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecu #define FindFirstFileEx FindFirstFileExA #define FindNextFile FindNextFileA #define CreateDirectory CreateDirectoryA +#define RemoveDirectory RemoveDirectoryA #endif diff --git a/winpr/include/winpr/path.h b/winpr/include/winpr/path.h index 36333e9b6..eba13296a 100644 --- a/winpr/include/winpr/path.h +++ b/winpr/include/winpr/path.h @@ -285,6 +285,8 @@ WINPR_API char* GetEnvironmentPath(char* name); WINPR_API char* GetEnvironmentSubPath(char* name, const char* path); WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath); +WINPR_API BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes); + WINPR_API BOOL PathFileExistsA(LPCSTR pszPath); WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath); diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h index a90df7724..ddcaeaf46 100644 --- a/winpr/include/winpr/string.h +++ b/winpr/include/winpr/string.h @@ -186,6 +186,8 @@ WINPR_API void ByteSwapUnicode(WCHAR* wstr, int length); WINPR_API int ConvertLineEndingToLF(char* str, int size); WINPR_API char* ConvertLineEndingToCRLF(const char* str, int* size); +WINPR_API char* StrSep(char** stringp, const char* delim); + #ifdef __cplusplus } #endif diff --git a/winpr/include/winpr/sysinfo.h b/winpr/include/winpr/sysinfo.h index 120009a08..a72297ffa 100644 --- a/winpr/include/winpr/sysinfo.h +++ b/winpr/include/winpr/sysinfo.h @@ -295,6 +295,8 @@ WINPR_API ULONGLONG GetTickCount64(void); #endif +WINPR_API DWORD GetTickCountPrecise(void); + WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature); /* extended flags */ diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index b0ff505ee..5d4c7e204 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -154,8 +154,9 @@ typedef unsigned int UINT32; typedef unsigned __int64 UINT64; typedef ULONG *PULONG; -typedef ULONG HRESULT; -typedef ULONG SCODE; +typedef LONG HRESULT; +typedef LONG SCODE; +typedef SCODE *PSCODE; typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; typedef ULONG_PTR SIZE_T; diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index 776167f39..da9185f80 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -463,3 +463,22 @@ char* ConvertLineEndingToCRLF(const char* str, int* size) return newStr; } +char* StrSep(char** stringp, const char* delim) +{ + char* start = *stringp; + char* p; + + p = (start != NULL) ? strpbrk(start, delim) : NULL; + + if (!p) + *stringp = NULL; + else + { + *p = '\0'; + *stringp = p + 1; + } + + return start; +} + + diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 05fb444ba..291ee23e0 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -788,7 +788,20 @@ BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttribu BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - return TRUE; + return FALSE; +} + +BOOL RemoveDirectoryA(LPCSTR lpPathName) +{ + if (!rmdir(lpPathName)) + return TRUE; + + return FALSE; +} + +BOOL RemoveDirectoryW(LPCWSTR lpPathName) +{ + return FALSE; } #endif diff --git a/winpr/libwinpr/path/include/PathAllocCombine.c b/winpr/libwinpr/path/include/PathAllocCombine.c index 9db12126f..9aa3c2ee1 100644 --- a/winpr/libwinpr/path/include/PathAllocCombine.c +++ b/winpr/libwinpr/path/include/PathAllocCombine.c @@ -6,6 +6,18 @@ #define PATH_ALLOC_COMBINE PathAllocCombineA */ +/** + * FIXME: These implementations of the PathAllocCombine functions have + * several issues: + * - pszPathIn or pszMore may be NULL (but not both) + * - no check if pszMore is fully qualified (if so, it must be directly + * copied to the output buffer without being combined with pszPathIn. + * - if pszMore begins with a _single_ backslash it must be combined with + * only the root of the path pointed to by pszPathIn and there's no code + * to extract the root of pszPathIn. + * - the function will crash with some short string lengths of the parameters + */ + #if DEFINE_UNICODE HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags, PWSTR* ppszPathOut) @@ -18,14 +30,26 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla int pszPathInLength; int pszPathOutLength; - if (!pszPathIn) - return S_FALSE; + WLog_WARN(TAG, "%s: has known bugs and needs fixing.", __FUNCTION__); + + if (!ppszPathOut) + return E_INVALIDARG; + + if (!pszPathIn && !pszMore) + return E_INVALIDARG; if (!pszMore) - return S_FALSE; + return E_FAIL; /* valid but not implemented, see top comment */ - pszPathInLength = lstrlenW(pszPathIn); - pszMoreLength = lstrlenW(pszMore); + if (!pszPathIn) + return E_FAIL; /* valid but not implemented, see top comment */ + + pszPathInLength = lstrlenA(pszPathIn); + pszMoreLength = lstrlenA(pszMore); + + /* prevent segfaults - the complete implementation below is buggy */ + if (pszPathInLength < 3) + return E_FAIL; backslashIn = (pszPathIn[pszPathInLength - 1] == _PATH_SEPARATOR_CHR) ? TRUE : FALSE; backslashMore = (pszMore[0] == _PATH_SEPARATOR_CHR) ? TRUE : FALSE; @@ -40,6 +64,9 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla sizeOfBuffer = (pszPathOutLength + 1) * 2; pszPathOut = (PWSTR) HeapAlloc(GetProcessHeap(), 0, sizeOfBuffer * 2); + if (!pszPathOut) + return E_OUTOFMEMORY; + swprintf_s(pszPathOut, sizeOfBuffer, L"%c:%s", pszPathIn[0], pszMore); *ppszPathOut = pszPathOut; @@ -55,6 +82,8 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla sizeOfBuffer = (pszPathOutLength + 1) * 2; pszPathOut = (PWSTR) HeapAlloc(GetProcessHeap(), 0, sizeOfBuffer * 2); + if (!pszPathOut) + return E_OUTOFMEMORY; if (backslashIn) swprintf_s(pszPathOut, sizeOfBuffer, L"%s%s", pszPathIn, pszMore); @@ -67,7 +96,7 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla } #endif - return S_OK; + return E_FAIL; } #else @@ -81,15 +110,27 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags int pszPathInLength; int pszPathOutLength; - if (!pszPathIn) - return S_FALSE; + WLog_WARN(TAG, "%s: has known bugs and needs fixing.", __FUNCTION__); + + if (!ppszPathOut) + return E_INVALIDARG; + + if (!pszPathIn && !pszMore) + return E_INVALIDARG; if (!pszMore) - return S_FALSE; + return E_FAIL; /* valid but not implemented, see top comment */ + + if (!pszPathIn) + return E_FAIL; /* valid but not implemented, see top comment */ pszPathInLength = lstrlenA(pszPathIn); pszMoreLength = lstrlenA(pszMore); + /* prevent segfaults - the complete implementation below is buggy */ + if (pszPathInLength < 3) + return E_FAIL; + backslashIn = (pszPathIn[pszPathInLength - 1] == _PATH_SEPARATOR_CHR) ? TRUE : FALSE; backslashMore = (pszMore[0] == _PATH_SEPARATOR_CHR) ? TRUE : FALSE; @@ -103,6 +144,9 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags sizeOfBuffer = (pszPathOutLength + 1) * 2; pszPathOut = (PSTR) HeapAlloc(GetProcessHeap(), 0, sizeOfBuffer * 2); + if (!pszPathOut) + return E_OUTOFMEMORY; + sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore); *ppszPathOut = pszPathOut; @@ -118,6 +162,8 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags sizeOfBuffer = (pszPathOutLength + 1) * 2; pszPathOut = (PSTR) HeapAlloc(GetProcessHeap(), 0, sizeOfBuffer * 2); + if (!pszPathOut) + return E_OUTOFMEMORY; if (backslashIn) sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore); @@ -129,7 +175,7 @@ HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags return S_OK; } - return S_OK; + return E_FAIL; } #endif diff --git a/winpr/libwinpr/path/include/PathCchAddExtension.c b/winpr/libwinpr/path/include/PathCchAddExtension.c index cea665d82..b51716e3e 100644 --- a/winpr/libwinpr/path/include/PathCchAddExtension.c +++ b/winpr/libwinpr/path/include/PathCchAddExtension.c @@ -17,10 +17,10 @@ HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; if (!pszExt) - return S_FALSE; + return E_INVALIDARG; pszExtLength = lstrlenW(pszExt); pszPathLength = lstrlenW(pszPath); @@ -45,7 +45,7 @@ HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt) return S_OK; } #endif - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #else @@ -59,10 +59,10 @@ HRESULT PATH_CCH_ADD_EXTENSION(PSTR pszPath, size_t cchPath, PCSTR pszExt) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; if (!pszExt) - return S_FALSE; + return E_INVALIDARG; pszExtLength = lstrlenA(pszExt); pszPathLength = lstrlenA(pszPath); @@ -87,7 +87,7 @@ HRESULT PATH_CCH_ADD_EXTENSION(PSTR pszPath, size_t cchPath, PCSTR pszExt) return S_OK; } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #endif diff --git a/winpr/libwinpr/path/include/PathCchAddSeparator.c b/winpr/libwinpr/path/include/PathCchAddSeparator.c index fb5670606..cf2b269f7 100644 --- a/winpr/libwinpr/path/include/PathCchAddSeparator.c +++ b/winpr/libwinpr/path/include/PathCchAddSeparator.c @@ -12,7 +12,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR(PWSTR pszPath, size_t cchPath) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; pszPathLength = lstrlenW(pszPath); @@ -27,7 +27,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR(PWSTR pszPath, size_t cchPath) return S_OK; } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #else @@ -37,7 +37,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR(PSTR pszPath, size_t cchPath) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; pszPathLength = lstrlenA(pszPath); @@ -52,7 +52,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR(PSTR pszPath, size_t cchPath) return S_OK; } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #endif diff --git a/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c b/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c index 3abcc8fa4..d21ba5b21 100644 --- a/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c +++ b/winpr/libwinpr/path/include/PathCchAddSeparatorEx.c @@ -12,7 +12,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR_EX(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; pszPathLength = lstrlenW(pszPath); @@ -27,7 +27,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR_EX(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, return S_OK; } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #else @@ -37,7 +37,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR_EX(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, s size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; pszPathLength = lstrlenA(pszPath); @@ -52,7 +52,7 @@ HRESULT PATH_CCH_ADD_SEPARATOR_EX(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, s return S_OK; } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } #endif diff --git a/winpr/libwinpr/path/include/PathCchAppend.c b/winpr/libwinpr/path/include/PathCchAppend.c index e1126321f..bd371f352 100644 --- a/winpr/libwinpr/path/include/PathCchAppend.c +++ b/winpr/libwinpr/path/include/PathCchAppend.c @@ -17,10 +17,13 @@ HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; if (!pszMore) - return S_FALSE; + return E_INVALIDARG; + + if (cchPath == 0 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; pszMoreLength = lstrlenW(pszMore); pszPathLength = lstrlenW(pszPath); @@ -54,7 +57,7 @@ HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore) } #endif - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); } #else @@ -67,10 +70,13 @@ HRESULT PATH_CCH_APPEND(PSTR pszPath, size_t cchPath, PCSTR pszMore) size_t pszPathLength; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; if (!pszMore) - return S_FALSE; + return E_INVALIDARG; + + if (cchPath == 0 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; pszMoreLength = lstrlenA(pszMore); pszPathLength = lstrlenA(pszPath); @@ -103,7 +109,7 @@ HRESULT PATH_CCH_APPEND(PSTR pszPath, size_t cchPath, PCSTR pszMore) } } - return S_FALSE; + return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); } #endif diff --git a/winpr/libwinpr/path/path.c b/winpr/libwinpr/path/path.c index 45e9fb129..de7b2aaeb 100644 --- a/winpr/libwinpr/path/path.c +++ b/winpr/libwinpr/path/path.c @@ -63,6 +63,9 @@ #define SHARED_LIBRARY_EXT SHARED_LIBRARY_EXT_SO #endif +#include "../log.h" +#define TAG WINPR_TAG("path") + /* * PathCchAddBackslash */ @@ -127,12 +130,14 @@ HRESULT PathCchRemoveBackslashA(PSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchRemoveBackslashW(PWSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -195,12 +200,14 @@ HRESULT PathCchRemoveBackslashW(PWSTR pszPath, size_t cchPath) HRESULT PathCchRemoveBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, size_t* pcchRemaining) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchRemoveBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t* pcchRemaining) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -337,12 +344,14 @@ HRESULT PathCchRemoveBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, HRESULT PathCchAppendExA(PSTR pszPath, size_t cchPath, PCSTR pszMore, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchAppendExW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -351,12 +360,14 @@ HRESULT PathCchAppendExW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore, unsigned HRESULT PathCchCanonicalizeA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchCanonicalizeW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -365,12 +376,14 @@ HRESULT PathCchCanonicalizeW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPath HRESULT PathCchCanonicalizeExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchCanonicalizeExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -379,12 +392,14 @@ HRESULT PathCchCanonicalizeExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPa HRESULT PathAllocCanonicalizeA(PCSTR pszPathIn, unsigned long dwFlags, PSTR* ppszPathOut) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathAllocCanonicalizeW(PCWSTR pszPathIn, unsigned long dwFlags, PWSTR* ppszPathOut) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -393,12 +408,14 @@ HRESULT PathAllocCanonicalizeW(PCWSTR pszPathIn, unsigned long dwFlags, PWSTR* p HRESULT PathCchCombineA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchCombineW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -407,12 +424,14 @@ HRESULT PathCchCombineW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, P HRESULT PathCchCombineExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchCombineExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -493,6 +512,9 @@ HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt) { char* p = (char*) pszPath; + if (!pszPath || !cchPath || !ppszExt) + return E_INVALIDARG; + /* find end of string */ while (*p && cchPath) @@ -501,6 +523,15 @@ HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt) p++; } + if (*p) + { + /* pszPath is not null terminated within the cchPath range */ + return E_INVALIDARG; + } + + /* If no extension is found, ppszExt must point to the string's terminating null */ + *ppszExt = p; + /* search backwards for '.' */ while (p > pszPath) @@ -508,21 +539,22 @@ HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt) if (*p == '.') { *ppszExt = (PCSTR) p; - return S_OK; + break; } if ((*p == '\\') || (*p == '/') || (*p == ':')) - return S_FALSE; + break; p--; } - return S_FALSE; + return S_OK; } HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -531,12 +563,14 @@ HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt) HRESULT PathCchRenameExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchRenameExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -545,12 +579,14 @@ HRESULT PathCchRenameExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt) HRESULT PathCchRemoveExtensionA(PSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -559,12 +595,14 @@ HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath) BOOL PathCchIsRootA(PCSTR pszPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } BOOL PathCchIsRootW(PCWSTR pszPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -605,12 +643,14 @@ BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer) HRESULT PathCchSkipRootA(PCSTR pszPath, PCSTR* ppszRootEnd) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchSkipRootW(PCWSTR pszPath, PCWSTR* ppszRootEnd) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -619,12 +659,14 @@ HRESULT PathCchSkipRootW(PCWSTR pszPath, PCWSTR* ppszRootEnd) HRESULT PathCchStripToRootA(PSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchStripToRootW(PWSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /** @@ -634,27 +676,29 @@ HRESULT PathCchStripToRootW(PWSTR pszPath, size_t cchPath) HRESULT PathCchStripPrefixA(PSTR pszPath, size_t cchPath) { BOOL hasPrefix; - BOOL deviceNamespace; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; - if (cchPath < 4) - return S_FALSE; + if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; hasPrefix = ((pszPath[0] == '\\') && (pszPath[1] == '\\') && (pszPath[2] == '?') && (pszPath[3] == '\\')) ? TRUE : FALSE; if (hasPrefix) { - if (cchPath < 7) + if (cchPath < 6) return S_FALSE; - deviceNamespace = ((pszPath[5] == ':') && (pszPath[6] == '\\')) ? TRUE : FALSE; - - if (deviceNamespace) + if (IsCharAlpha(pszPath[4]) && (pszPath[5] == ':')) /* like C: */ { memmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4); + /* since the passed pszPath must not necessarily be null terminated + * and we always have enough space after the strip we can always + * ensure the null termination of the stripped result + */ + pszPath[cchPath - 4] = 0; return S_OK; } } @@ -665,27 +709,32 @@ HRESULT PathCchStripPrefixA(PSTR pszPath, size_t cchPath) HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath) { BOOL hasPrefix; - BOOL deviceNamespace; if (!pszPath) - return S_FALSE; + return E_INVALIDARG; - if (cchPath < 4) - return S_FALSE; + if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH) + return E_INVALIDARG; hasPrefix = ((pszPath[0] == '\\') && (pszPath[1] == '\\') && (pszPath[2] == '?') && (pszPath[3] == '\\')) ? TRUE : FALSE; if (hasPrefix) { - if (cchPath < 7) + if (cchPath < 6) return S_FALSE; - deviceNamespace = ((pszPath[5] == ':') && (pszPath[6] == '\\')) ? TRUE : FALSE; + if (cchPath < (lstrlenW(&pszPath[4]) + 1)) + return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - if (deviceNamespace) + if (IsCharAlpha(pszPath[4]) && (pszPath[5] == ':')) /* like C: */ { wmemmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4); + /* since the passed pszPath must not necessarily be null terminated + * and we always have enough space after the strip we can always + * ensure the null termination of the stripped result + */ + pszPath[cchPath - 4] = 0; return S_OK; } } @@ -699,12 +748,14 @@ HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath) HRESULT PathCchRemoveFileSpecA(PSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } HRESULT PathCchRemoveFileSpecW(PWSTR pszPath, size_t cchPath) { - return 0; + WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); + return E_NOTIMPL; } /* @@ -760,13 +811,13 @@ HRESULT PathCchConvertStyleA(PSTR pszPath, size_t cchPath, unsigned long dwFlags else { /* Unexpected error */ - return S_FALSE; + return E_FAIL; } } else { /* Gangnam style? */ - return S_FALSE; + return E_FAIL; } return S_OK; @@ -817,13 +868,13 @@ HRESULT PathCchConvertStyleW(PWSTR pszPath, size_t cchPath, unsigned long dwFlag else { /* Unexpected error */ - return S_FALSE; + return E_FAIL; } } else { /* Gangnam style? */ - return S_FALSE; + return E_FAIL; } return S_OK; diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 2cfa4466e..69841a1c1 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -28,11 +28,19 @@ #include #include +#include #include #include #include +#if defined(WIN32) +#include +#endif + +static char* GetPath_XDG_CONFIG_HOME(void); +static char* GetPath_XDG_RUNTIME_DIR(void); + /** * SHGetKnownFolderPath function: * http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188/ @@ -43,7 +51,7 @@ * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html */ -char* GetEnvAlloc(LPCSTR lpName) +static char* GetEnvAlloc(LPCSTR lpName) { DWORD length; char* env = NULL; @@ -62,7 +70,7 @@ char* GetEnvAlloc(LPCSTR lpName) return env; } -char* GetPath_HOME() +static char* GetPath_HOME(void) { char* path = NULL; @@ -80,7 +88,7 @@ char* GetPath_HOME() return path; } -char* GetPath_TEMP() +static char* GetPath_TEMP(void) { char* path = NULL; @@ -96,11 +104,14 @@ char* GetPath_TEMP() return path; } -char* GetPath_XDG_DATA_HOME() +static char* GetPath_XDG_DATA_HOME(void) { char* path = NULL; - char* home = NULL; +#if defined(WIN32) + path = GetPath_XDG_CONFIG_HOME(); +#else + char* home = NULL; /** * There is a single base directory relative to which user-specific data files should be written. * This directory is defined by the environment variable $XDG_DATA_HOME. @@ -127,15 +138,28 @@ char* GetPath_XDG_DATA_HOME() sprintf(path, "%s%s", home, "/.local/share"); free(home); +#endif return path; } -char* GetPath_XDG_CONFIG_HOME() +static char* GetPath_XDG_CONFIG_HOME(void) { char* path = NULL; - char* home = NULL; +#if defined(WIN32) + path = calloc(MAX_PATH, sizeof(char)); + if (!path) + return NULL; + + if (SHGetFolderPathA(0, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, path) != S_OK) + { + free(path); + return NULL; + } +#else + char* home = NULL; /** * There is a single base directory relative to which user-specific configuration files should be written. * This directory is defined by the environment variable $XDG_CONFIG_HOME. @@ -166,15 +190,27 @@ char* GetPath_XDG_CONFIG_HOME() sprintf(path, "%s%s", home, "/.config"); free(home); +#endif return path; } -char* GetPath_XDG_CACHE_HOME() +static char* GetPath_XDG_CACHE_HOME(void) { char* path = NULL; char* home = NULL; +#if defined(WIN32) + home = GetPath_XDG_RUNTIME_DIR(); + if (home) + { + path = GetCombinedPath(home, "cache"); + if (!PathFileExistsA(path)) + if (!CreateDirectoryA(path, NULL)) + path = NULL; + } + free(home); +#else /** * There is a single base directory relative to which user-specific non-essential (cached) data should be written. * This directory is defined by the environment variable $XDG_CACHE_HOME. @@ -201,14 +237,26 @@ char* GetPath_XDG_CACHE_HOME() sprintf(path, "%s%s", home, "/.cache"); free(home); +#endif return path; } -char* GetPath_XDG_RUNTIME_DIR() +char* GetPath_XDG_RUNTIME_DIR(void) { char* path = NULL; +#if defined(WIN32) + path = calloc(MAX_PATH, sizeof(char)); + if (!path) + return NULL; + if (SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, path) != S_OK) + { + free(path); + return NULL; + } +#else /** * There is a single base directory relative to which user-specific runtime files and other file objects should be placed. * This directory is defined by the environment variable $XDG_RUNTIME_DIR. @@ -237,6 +285,7 @@ char* GetPath_XDG_RUNTIME_DIR() */ path = GetEnvAlloc("XDG_RUNTIME_DIR"); +#endif if (path) return path; @@ -372,6 +421,50 @@ char* GetCombinedPath(const char* basePath, const char* subPath) return path; } +BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes) +{ + size_t length; + const char delim = PathGetSeparatorA(0); + char* cur; + char* copy_org = _strdup(path); + char* copy = copy_org; + + if (!copy_org) + return FALSE; + + length = strlen(copy_org); + + /* Find first path element that exists. */ + while (copy) + { + if (!PathFileExistsA(copy)) + { + cur = strrchr(copy, delim); + if (cur) + *cur = '\0'; + } + else + break; + } + + /* Create directories. */ + while(copy) + { + if (!PathFileExistsA(copy)) + { + if (!CreateDirectoryA(copy, NULL)) + break; + } + if (strlen(copy) < length) + copy[strlen(copy)] = delim; + else + break; + } + free (copy_org); + + return PathFileExistsA(path); +} + BOOL PathFileExistsA(LPCSTR pszPath) { struct stat stat_info; diff --git a/winpr/libwinpr/path/test/CMakeLists.txt b/winpr/libwinpr/path/test/CMakeLists.txt index 8d0bc0ac9..974907e31 100644 --- a/winpr/libwinpr/path/test/CMakeLists.txt +++ b/winpr/libwinpr/path/test/CMakeLists.txt @@ -27,7 +27,8 @@ set(${MODULE_PREFIX}_TESTS TestPathCchStripToRoot.c TestPathCchStripPrefix.c TestPathCchRemoveFileSpec.c - TestPathShell.c) + TestPathShell.c + TestPathMakePath.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c b/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c index 81f601432..cb812c48d 100644 --- a/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c +++ b/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c @@ -7,6 +7,7 @@ int TestPathAllocCanonicalize(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchAddBackslash.c b/winpr/libwinpr/path/test/TestPathCchAddBackslash.c index a4e4a6df8..42f8f74d8 100644 --- a/winpr/libwinpr/path/test/TestPathCchAddBackslash.c +++ b/winpr/libwinpr/path/test/TestPathCchAddBackslash.c @@ -13,6 +13,12 @@ int TestPathCchAddBackslash(int argc, char* argv[]) HRESULT status; TCHAR Path[PATHCCH_MAX_CCH]; + /** + * PathCchAddBackslash returns S_OK if the function was successful, + * S_FALSE if the path string already ends in a backslash, + * or an error code otherwise. + */ + _tcscpy(Path, testPathNoBackslash); /* Add a backslash to a path without a trailing backslash, expect S_OK */ @@ -21,7 +27,7 @@ int TestPathCchAddBackslash(int argc, char* argv[]) if (status != S_OK) { - _tprintf(_T("PathCchAddBackslash status: 0x%08X\n"), (int) status); + _tprintf(_T("PathCchAddBackslash status: 0x%08X\n"), (unsigned) status); return -1; } @@ -39,7 +45,7 @@ int TestPathCchAddBackslash(int argc, char* argv[]) if (status != S_FALSE) { - _tprintf(_T("PathCchAddBackslash status: 0x%08X\n"), (int) status); + _tprintf(_T("PathCchAddBackslash status: 0x%08X\n"), (unsigned) status); return -1; } @@ -49,6 +55,40 @@ int TestPathCchAddBackslash(int argc, char* argv[]) return -1; } + /* Use NULL PSTR, expect FAILED(status) */ + + status = PathCchAddBackslash(NULL, PATHCCH_MAX_CCH); + + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAddBackslash unexpectedly succeded with null buffer. Status: 0x%08X\n"), (unsigned) status); + return -1; + } + + /* Use insufficient size value, expect FAILED(status) */ + + _tcscpy(Path, _T("C:\\tmp")); + + status = PathCchAddBackslash(Path, 7); + + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAddBackslash unexpectedly succeded with insufficient buffer size. Status: 0x%08X\n"), (unsigned) status); + return -1; + } + + /* Use minimum required size value, expect S_OK */ + + _tcscpy(Path, _T("C:\\tmp")); + + status = PathCchAddBackslash(Path, 8); + + if (status != S_OK) + { + _tprintf(_T("PathCchAddBackslash failed with status: 0x%08X\n"), (unsigned) status); + return -1; + } + return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c b/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c index 9fe39be84..9fc4aaf2b 100644 --- a/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c +++ b/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c @@ -15,6 +15,12 @@ int TestPathCchAddBackslashEx(int argc, char* argv[]) size_t cchRemaining; TCHAR Path[PATHCCH_MAX_CCH]; + /** + * PathCchAddBackslashEx returns S_OK if the function was successful, + * S_FALSE if the path string already ends in a backslash, + * or an error code otherwise. + */ + _tcscpy(Path, testPathNoBackslash); /* Add a backslash to a path without a trailing backslash, expect S_OK */ @@ -51,6 +57,41 @@ int TestPathCchAddBackslashEx(int argc, char* argv[]) return -1; } + /* Use NULL PSTR, expect FAILED(status) */ + + status = PathCchAddBackslashEx(NULL, PATHCCH_MAX_CCH, NULL, NULL); + + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAddBackslashEx unexpectedly succeded with null buffer. Status: 0x%08X\n"), (unsigned) status); + return -1; + } + + /* Use insufficient size value, expect FAILED(status) */ + + _tcscpy(Path, _T("C:\\tmp")); + + status = PathCchAddBackslashEx(Path, 7, NULL, NULL); + + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAddBackslashEx unexpectedly succeded with insufficient buffer size. Status: 0x%08X\n"), (unsigned) status); + return -1; + } + + /* Use minimum required size value, expect S_OK */ + + _tcscpy(Path, _T("C:\\tmp")); + + status = PathCchAddBackslashEx(Path, 8, NULL, NULL); + + if (status != S_OK) + { + _tprintf(_T("PathCchAddBackslashEx failed with status: 0x%08X\n"), (unsigned) status); + return -1; + } + + return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchAddExtension.c b/winpr/libwinpr/path/test/TestPathCchAddExtension.c index ef766cffa..39763391b 100644 --- a/winpr/libwinpr/path/test/TestPathCchAddExtension.c +++ b/winpr/libwinpr/path/test/TestPathCchAddExtension.c @@ -14,7 +14,7 @@ int TestPathCchAddExtension(int argc, char* argv[]) { HRESULT status; TCHAR Path[PATHCCH_MAX_CCH]; - + /* Path: no extension, Extension: dot */ _tcscpy(Path, testPathNoExtension); @@ -87,6 +87,45 @@ int TestPathCchAddExtension(int argc, char* argv[]) return -1; } + /* Path: NULL */ + + status = PathCchAddExtension(NULL, PATHCCH_MAX_CCH, testExtDot); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAddExtension with null buffer returned status: 0x%08X (expected E_INVALIDARG)\n"), status); + return -1; + } + + /* Extension: NULL */ + + status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, NULL); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAddExtension with null extension returned status: 0x%08X (expected E_INVALIDARG)\n"), status); + return -1; + } + + /* Insufficient Buffer size */ + + _tcscpy(Path, _T("C:\\456789")); + status = PathCchAddExtension(Path, 9 + 4, _T(".jpg")); + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAddExtension with insufficient buffer unexpectedly succeeded with status: 0x%08X\n"), status); + return -1; + } + + /* Minimum required buffer size */ + + _tcscpy(Path, _T("C:\\456789")); + status = PathCchAddExtension(Path, 9 + 4 + 1, _T(".jpg")); + if (FAILED(status)) + { + _tprintf(_T("PathCchAddExtension with sufficient buffer unexpectedly failed with status: 0x%08X\n"), status); + return -1; + } + + return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchAppend.c b/winpr/libwinpr/path/test/TestPathCchAppend.c index 76053c38a..0f5964f48 100644 --- a/winpr/libwinpr/path/test/TestPathCchAppend.c +++ b/winpr/libwinpr/path/test/TestPathCchAppend.c @@ -15,6 +15,7 @@ int TestPathCchAppend(int argc, char* argv[]) { HRESULT status; TCHAR Path[PATHCCH_MAX_CCH]; + size_t i; /* Base Path: Backslash, More Path: No Backslash */ @@ -88,6 +89,53 @@ int TestPathCchAppend(int argc, char* argv[]) return -1; } + /* According to msdn a NULL Path is an invalid argument */ + status = PathCchAppend(NULL, PATHCCH_MAX_CCH, testMorePathNoBackslash); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAppend with NULL path unexpectedly returned status: 0x%08X\n"), status); + return -1; + } + + /* According to msdn a NULL pszMore is an invalid argument (although optional !?) */ + _tcscpy(Path, testBasePathNoBackslash); + status = PathCchAppend(Path, PATHCCH_MAX_CCH, NULL); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAppend with NULL pszMore unexpectedly returned status: 0x%08X\n"), status); + return -1; + } + + /* According to msdn cchPath must be > 0 and <= PATHCCH_MAX_CCH */ + _tcscpy(Path, testBasePathNoBackslash); + status = PathCchAppend(Path, 0, testMorePathNoBackslash); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAppend with cchPath value 0 unexpectedly returned status: 0x%08X\n"), status); + return -1; + } + _tcscpy(Path, testBasePathNoBackslash); + status = PathCchAppend(Path, PATHCCH_MAX_CCH + 1, testMorePathNoBackslash); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchAppend with cchPath value > PATHCCH_MAX_CCH unexpectedly returned status: 0x%08X\n"), status); + return -1; + } + + /* Resulting file must not exceed PATHCCH_MAX_CCH */ + + for (i = 0; i < PATHCCH_MAX_CCH - 1; i++) + Path[i] = _T('X'); + + Path[PATHCCH_MAX_CCH - 1] = 0; + + status = PathCchAppend(Path, PATHCCH_MAX_CCH, _T("\\This cannot be appended to Path")); + if (SUCCEEDED(status)) + { + _tprintf(_T("PathCchAppend unexepectedly succeeded with status: 0x%08X\n"), status); + return -1; + } + return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchAppendEx.c b/winpr/libwinpr/path/test/TestPathCchAppendEx.c index 6f040fad1..563bccba1 100644 --- a/winpr/libwinpr/path/test/TestPathCchAppendEx.c +++ b/winpr/libwinpr/path/test/TestPathCchAppendEx.c @@ -7,6 +7,7 @@ int TestPathCchAppendEx(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchCanonicalize.c b/winpr/libwinpr/path/test/TestPathCchCanonicalize.c index 7c5b868dd..a5b1ec051 100644 --- a/winpr/libwinpr/path/test/TestPathCchCanonicalize.c +++ b/winpr/libwinpr/path/test/TestPathCchCanonicalize.c @@ -7,6 +7,7 @@ int TestPathCchCanonicalize(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c b/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c index 13c4d373e..dd0ae1da0 100644 --- a/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c +++ b/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c @@ -7,6 +7,7 @@ int TestPathCchCanonicalizeEx(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchCombine.c b/winpr/libwinpr/path/test/TestPathCchCombine.c index bfe1e86c6..0d7cd4707 100644 --- a/winpr/libwinpr/path/test/TestPathCchCombine.c +++ b/winpr/libwinpr/path/test/TestPathCchCombine.c @@ -7,6 +7,7 @@ int TestPathCchCombine(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchCombineEx.c b/winpr/libwinpr/path/test/TestPathCchCombineEx.c index 5c3d0b8be..725bc8f91 100644 --- a/winpr/libwinpr/path/test/TestPathCchCombineEx.c +++ b/winpr/libwinpr/path/test/TestPathCchCombineEx.c @@ -7,6 +7,7 @@ int TestPathCchCombineEx(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchFindExtension.c b/winpr/libwinpr/path/test/TestPathCchFindExtension.c index 7a6ddbe84..640365bdf 100644 --- a/winpr/libwinpr/path/test/TestPathCchFindExtension.c +++ b/winpr/libwinpr/path/test/TestPathCchFindExtension.c @@ -10,13 +10,95 @@ static const char testPathExtension[] = "C:\\Windows\\System32\\cmd.exe"; int TestPathCchFindExtension(int argc, char* argv[]) { PCSTR pszExt; + PCSTR pszTmp; + HRESULT hr; + /* Test invalid args */ + + hr = PathCchFindExtensionA(NULL, sizeof(testPathExtension), &pszExt); + if (SUCCEEDED(hr)) + { + printf("PathCchFindExtensionA unexpectedly succeeded with pszPath = NULL. result: 0x%08X\n", (ULONG)hr); + return -1; + } + + hr = PathCchFindExtensionA(testPathExtension, 0, &pszExt); + if (SUCCEEDED(hr)) + { + printf("PathCchFindExtensionA unexpectedly succeeded with cchPath = 0. result: 0x%08X\n", (ULONG)hr); + return -1; + } + + hr = PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), NULL); + if (SUCCEEDED(hr)) + { + printf("PathCchFindExtensionA unexpectedly succeeded with ppszExt = NULL. result: 0x%08X\n", (ULONG)hr); + return -1; + } + + + /* Test missing null-termination of pszPath */ + + hr = PathCchFindExtensionA(_T("c:\\456.789"), 9, &pszExt); + if (SUCCEEDED(hr)) + { + printf("PathCchFindExtensionA unexpectedly succeeded with unterminated pszPath. result: 0x%08X\n", (ULONG)hr); + return -1; + } + + + /* Test passing of an empty terminated string (must succeed) */ + + pszExt = NULL; + pszTmp = _T(""); + hr = PathCchFindExtensionA(pszTmp, 1, &pszExt); + if (hr != S_OK) + { + printf("PathCchFindExtensionA failed with an empty terminated string. result: 0x%08X\n", (ULONG)hr); + return -1; + } + /* pszExt must point to the strings terminating 0 now */ + if (pszExt != pszTmp) + { + printf("PathCchFindExtensionA failed with an empty terminated string: pszExt pointer mismatch\n"); + return -1; + } + + + /* Test a path without file extension (must succeed) */ + + pszExt = NULL; + pszTmp = _T("c:\\4.678\\"); + hr = PathCchFindExtensionA(pszTmp, 10, &pszExt); + if (hr != S_OK) + { + printf("PathCchFindExtensionA failed with a directory path. result: 0x%08X\n", (ULONG)hr); + return -1; + } + /* The extension must not have been found and pszExt must point to the + * strings terminating NULL now */ + if (pszExt != &pszTmp[9]) + { + printf("PathCchFindExtensionA failed with a directory path: pszExt pointer mismatch\n"); + return -1; + } + + + /* Non-special tests */ + + pszExt = NULL; if (PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), &pszExt) != S_OK) { printf("PathCchFindExtensionA failure: expected S_OK\n"); return -1; } + if (!pszExt || _tcscmp(pszExt, _T(".exe"))) + { + printf("PathCchFindExtensionA failure: unexpected extension\n"); + return -1; + } + printf("Extension: %s\n", pszExt); return 0; diff --git a/winpr/libwinpr/path/test/TestPathCchIsRoot.c b/winpr/libwinpr/path/test/TestPathCchIsRoot.c index a4e48daf9..878328d11 100644 --- a/winpr/libwinpr/path/test/TestPathCchIsRoot.c +++ b/winpr/libwinpr/path/test/TestPathCchIsRoot.c @@ -7,6 +7,7 @@ int TestPathCchIsRoot(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c b/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c index a7c00ecfd..489d313cd 100644 --- a/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c +++ b/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c @@ -7,6 +7,7 @@ int TestPathCchRemoveBackslash(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c b/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c index 903341a46..eaf863f26 100644 --- a/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c +++ b/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c @@ -7,6 +7,7 @@ int TestPathCchRemoveBackslashEx(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c b/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c index f52ea8fc3..700c21758 100644 --- a/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c +++ b/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c @@ -7,6 +7,7 @@ int TestPathCchRemoveExtension(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c b/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c index 192894e0c..3754cb309 100644 --- a/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c +++ b/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c @@ -7,6 +7,7 @@ int TestPathCchRemoveFileSpec(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchRenameExtension.c b/winpr/libwinpr/path/test/TestPathCchRenameExtension.c index a1816cbcd..5b86c3651 100644 --- a/winpr/libwinpr/path/test/TestPathCchRenameExtension.c +++ b/winpr/libwinpr/path/test/TestPathCchRenameExtension.c @@ -7,6 +7,7 @@ int TestPathCchRenameExtension(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchSkipRoot.c b/winpr/libwinpr/path/test/TestPathCchSkipRoot.c index 4e83ef541..a2821e70c 100644 --- a/winpr/libwinpr/path/test/TestPathCchSkipRoot.c +++ b/winpr/libwinpr/path/test/TestPathCchSkipRoot.c @@ -7,6 +7,7 @@ int TestPathCchSkipRoot(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchStripPrefix.c b/winpr/libwinpr/path/test/TestPathCchStripPrefix.c index 7163c1346..080bf9df7 100644 --- a/winpr/libwinpr/path/test/TestPathCchStripPrefix.c +++ b/winpr/libwinpr/path/test/TestPathCchStripPrefix.c @@ -12,6 +12,8 @@ static const TCHAR testPathPrefixFileNamespace[] = _T("\\\\?\\C:\\Program Files\\"); static const TCHAR testPathNoPrefixFileNamespace[] = _T("C:\\Program Files\\"); +static const TCHAR testPathPrefixFileNamespaceMinimum[] = _T("\\\\?\\C:"); +static const TCHAR testPathNoPrefixFileNamespaceMinimum[] = _T("C:"); static const TCHAR testPathPrefixDeviceNamespace[] = _T("\\\\?\\GLOBALROOT"); @@ -19,6 +21,13 @@ int TestPathCchStripPrefix(int argc, char* argv[]) { HRESULT status; TCHAR Path[PATHCCH_MAX_CCH]; + int i; + + /** + * PathCchStripPrefix returns S_OK if the prefix was removed, S_FALSE if + * the path did not have a prefix to remove, or an HRESULT failure code. + */ + /* Path with prefix (File Namespace) */ @@ -56,6 +65,53 @@ int TestPathCchStripPrefix(int argc, char* argv[]) return -1; } + /* NULL Path */ + status = PathCchStripPrefix(NULL, PATHCCH_MAX_CCH); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchStripPrefix with null path unexpectedly succeeded with status 0x%08X\n"), status); + return -1; + } + + /* Invalid cchPath values: 0, 1, 2, 3 and > PATHCCH_MAX_CCH */ + for (i = 0; i < 5; i++) + { + _tcscpy(Path, testPathPrefixFileNamespace); + if (i == 4) + i = PATHCCH_MAX_CCH + 1; + status = PathCchStripPrefix(Path, i); + if (status != E_INVALIDARG) + { + _tprintf(_T("PathCchStripPrefix with invalid cchPath value %d unexpectedly succeeded with status 0x%08X\n"), i, status); + return -1; + } + } + + /* Minimum Path that would get successfully stripped on windows */ + _tcscpy(Path, testPathPrefixFileNamespaceMinimum); + i = sizeof(testPathPrefixFileNamespaceMinimum) / sizeof(TCHAR); + i = i - 1; /* include testing of a non-null terminated string */ + status = PathCchStripPrefix(Path, i); + if (status != S_OK) + { + _tprintf(_T("PathCchStripPrefix with minimum valid strippable path length unexpectedly returned status 0x%08X\n"), status); + return -1; + } + if (_tcscmp(Path, testPathNoPrefixFileNamespaceMinimum)) + { + _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathNoPrefixFileNamespaceMinimum); + return -1; + } + + /* Invalid drive letter symbol */ + _tcscpy(Path, _T("\\\\?\\5:")); + status = PathCchStripPrefix(Path, 6); + if (status == S_OK) + { + _tprintf(_T("PathCchStripPrefix with invalid drive letter symbol unexpectedly succeeded\n")); + return -1; + } + return 0; } diff --git a/winpr/libwinpr/path/test/TestPathCchStripToRoot.c b/winpr/libwinpr/path/test/TestPathCchStripToRoot.c index cc6e13cd9..6192549cf 100644 --- a/winpr/libwinpr/path/test/TestPathCchStripToRoot.c +++ b/winpr/libwinpr/path/test/TestPathCchStripToRoot.c @@ -7,6 +7,7 @@ int TestPathCchStripToRoot(int argc, char* argv[]) { + printf("Warning: %s is not implemented!\n", __FUNCTION__); return 0; } diff --git a/winpr/libwinpr/path/test/TestPathMakePath.c b/winpr/libwinpr/path/test/TestPathMakePath.c new file mode 100644 index 000000000..e69b396bd --- /dev/null +++ b/winpr/libwinpr/path/test/TestPathMakePath.c @@ -0,0 +1,75 @@ +#include +#include +#include + +#include +#include +#include + +int TestPathMakePath(int argc, char* argv[]) +{ + int x; + size_t baseLen; + BOOL success; + char tmp[64]; + char* path; + char* cur; + char delim = PathGetSeparatorA(0); + char* base = GetKnownPath(KNOWN_PATH_TEMP); + if (!base) + { + fprintf(stderr, "Failed to get temporary directory!\n"); + return -1; + } + + baseLen = strlen(base); + srand(time(NULL)); + for (x=0; x<5; x++) + { + sprintf(tmp, "%08X", rand()); + path = GetCombinedPath(base, tmp); + free(base); + if (!path) + { + fprintf(stderr, "GetCombinedPath failed!\n"); + return -1; + } + + base = path; + } + + printf("Creating path %s\n", path); + success = PathMakePathA(path, NULL); + if (!success) + { + fprintf(stderr, "MakePath failed!\n"); + free (path); + return -1; + } + + success = PathFileExistsA(path); + if (!success) + { + fprintf(stderr, "MakePath lied about success!\n"); + free (path); + return -1; + } + + while (strlen(path) > baseLen) + { + if (!RemoveDirectoryA(path)) + { + fprintf(stderr, "RemoveDirectoryA %s failed!\n", path); + free (path); + return -1; + } + cur = strrchr(path, delim); + if (cur) + *cur = '\0'; + } + + free (path); + printf("%s success!\n", __FUNCTION__); + return 0; +} + diff --git a/winpr/libwinpr/smartcard/smartcard_inspect.c b/winpr/libwinpr/smartcard/smartcard_inspect.c index 192a48ac1..c36fc87e5 100644 --- a/winpr/libwinpr/smartcard/smartcard_inspect.c +++ b/winpr/libwinpr/smartcard/smartcard_inspect.c @@ -1276,7 +1276,7 @@ void Inspect_InitLog() return; if (!PathFileExistsA(filepath)) - if (!CreateDirectoryA(filepath, NULL)) + if (!PathMakePathA(filepath, NULL)) return; if (!(g_Log = WLog_Get("WinSCard"))) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 08212f14c..190c28931 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "ntlm.h" #include "../sspi.h" @@ -143,6 +145,7 @@ NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE if (!pAvPair) return NULL; + assert(Value != NULL); pAvPair->AvId = AvId; pAvPair->AvLen = AvLen; CopyMemory(ntlm_av_pair_get_value_pointer(pAvPair), Value, AvLen); diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 6b6176535..0157c652b 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -37,9 +37,10 @@ #ifdef HAVE_EVENTFD_H #include -#include #endif +#include + #include "../handle/handle.h" #include "../pipe/pipe.h" @@ -219,7 +220,6 @@ BOOL SetEvent(HANDLE hEvent) status = (length == 0) ? TRUE : FALSE; #else - if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) { length = write(event->pipe_fd[1], "-", 1); @@ -243,36 +243,29 @@ BOOL ResetEvent(HANDLE hEvent) ULONG Type; PVOID Object; int length; - BOOL status; + BOOL status = TRUE; WINPR_EVENT* event; - status = FALSE; - if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) + if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) + return FALSE; + + event = (WINPR_EVENT*) Object; + + while (status && WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { - event = (WINPR_EVENT*) Object; - - while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) + do { #ifdef HAVE_EVENTFD_H eventfd_t value; - - do - { - length = eventfd_read(event->pipe_fd[0], &value); - } - while ((length < 0) && (errno == EINTR)); - - if ((length > 0) && (!status)) - status = TRUE; - + length = eventfd_read(event->pipe_fd[0], &value); #else length = read(event->pipe_fd[0], &length, 1); - - if ((length == 1) && (!status)) - status = TRUE; - #endif } + while ((length < 0) && (errno == EINTR)); + + if (length < 0) + status = FALSE; } return status; diff --git a/winpr/libwinpr/synch/test/TestSynchEvent.c b/winpr/libwinpr/synch/test/TestSynchEvent.c index 1262613e9..3f6506588 100644 --- a/winpr/libwinpr/synch/test/TestSynchEvent.c +++ b/winpr/libwinpr/synch/test/TestSynchEvent.c @@ -5,6 +5,19 @@ int TestSynchEvent(int argc, char* argv[]) { HANDLE event; + int i; + + if (ResetEvent(NULL)) + { + printf("ResetEvent(NULL) unexpectedly succeeded\n"); + return -1; + } + + if (SetEvent(NULL)) + { + printf("SetEvent(NULL) unexpectedly succeeded\n"); + return -1; + } event = CreateEvent(NULL, TRUE, TRUE, NULL); @@ -16,23 +29,62 @@ int TestSynchEvent(int argc, char* argv[]) if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) { - printf("WaitForSingleObject(event, INFINITE) failure\n"); + printf("WaitForSingleObject failure 1\n"); return -1; } - ResetEvent(event); + if (!ResetEvent(event)) + { + printf("ResetEvent failure with signaled event object\n"); + return -1; + } if (WaitForSingleObject(event, 0) != WAIT_TIMEOUT) { - printf("WaitForSingleObject(event, 0) failure\n"); + printf("WaitForSingleObject failure 2\n"); return -1; } - SetEvent(event); + if (!ResetEvent(event)) + { + /* Note: ResetEvent must also succeed if event is currently nonsignaled */ + printf("ResetEvent failure with nonsignaled event object\n"); + return -1; + } + + if (!SetEvent(event)) + { + printf("SetEvent failure with nonsignaled event object\n"); + return -1; + } if (WaitForSingleObject(event, 0) != WAIT_OBJECT_0) { - printf("WaitForSingleObject(event, 0) failure\n"); + printf("WaitForSingleObject failure 3\n"); + return -1; + } + + for (i = 0; i < 10000; i++) + { + if (!SetEvent(event)) + { + printf("SetEvent failure with signaled event object (i = %d)\n", i); + return -1; + } + } + + if (!ResetEvent(event)) + { + printf("ResetEvent failure after multiple SetEvent calls\n"); + return -1; + } + + /* Independent of the amount of the previous SetEvent calls, a single + ResetEvent must be sufficient to get into nonsignaled state */ + + if (WaitForSingleObject(event, 0) != WAIT_TIMEOUT) + { + printf("WaitForSingleObject failure 4\n"); return -1; } diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index 1aa7d87f0..8c7234b32 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -678,6 +678,21 @@ BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature) #endif //_WIN32 +DWORD GetTickCountPrecise(void) +{ +#ifdef _WIN32 + LARGE_INTEGER freq; + LARGE_INTEGER current; + + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(¤t); + + return (DWORD) (current.QuadPart * 1000LL / freq.QuadPart); +#else + return GetTickCount(); +#endif +} + BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature) { BOOL ret = FALSE; diff --git a/winpr/libwinpr/utils/collections/MessageQueue.c b/winpr/libwinpr/utils/collections/MessageQueue.c index 71482b0be..a1fc39b84 100644 --- a/winpr/libwinpr/utils/collections/MessageQueue.c +++ b/winpr/libwinpr/utils/collections/MessageQueue.c @@ -67,8 +67,9 @@ BOOL MessageQueue_Wait(wMessageQueue* queue) return status; } -void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message) +BOOL MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message) { + BOOL ret = FALSE; EnterCriticalSection(&queue->lock); if (queue->size == queue->capacity) @@ -82,7 +83,7 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message) new_arr = (wMessage*) realloc(queue->array, sizeof(wMessage) * new_capacity); if (!new_arr) - return; + goto out; queue->array = new_arr; queue->capacity = new_capacity; ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(wMessage)); @@ -104,10 +105,13 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message) if (queue->size > 0) SetEvent(queue->event); + ret = TRUE; +out: LeaveCriticalSection(&queue->lock); + return ret; } -void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam) +BOOL MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam) { wMessage message; @@ -117,12 +121,12 @@ void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* w message.lParam = lParam; message.Free = NULL; - MessageQueue_Dispatch(queue, &message); + return MessageQueue_Dispatch(queue, &message); } -void MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode) +BOOL MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode) { - MessageQueue_Post(queue, NULL, WMQ_QUIT, (void*) (size_t) nExitCode, NULL); + return MessageQueue_Post(queue, NULL, WMQ_QUIT, (void*) (size_t) nExitCode, NULL); } int MessageQueue_Get(wMessageQueue* queue, wMessage* message) @@ -187,43 +191,34 @@ wMessageQueue* MessageQueue_New(const wObject *callback) { wMessageQueue* queue = NULL; - queue = (wMessageQueue*) malloc(sizeof(wMessageQueue)); + queue = (wMessageQueue*) calloc(1, sizeof(wMessageQueue)); + if (!queue) + return NULL; - if (queue) - { - queue->head = 0; - queue->tail = 0; - queue->size = 0; + queue->capacity = 32; + queue->array = (wMessage*) calloc(queue->capacity, sizeof(wMessage)); + if (!queue->array) + goto error_array; - queue->capacity = 32; - queue->array = (wMessage*) calloc(1, sizeof(wMessage) * queue->capacity); - if (!queue->array) - { - free(queue); - return NULL; - } + if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000)) + goto error_spinlock; - if (!InitializeCriticalSectionAndSpinCount(&queue->lock, 4000)) - { - free(queue); - return NULL; - } - queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!queue->event) - { - free(queue->array); - DeleteCriticalSection(&queue->lock); - free(queue); - return NULL; - } + queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!queue->event) + goto error_event; - if (callback) - queue->object = *callback; - else - ZeroMemory(&queue->object, sizeof(queue->object)); - } + if (callback) + queue->object = *callback; return queue; + +error_event: + DeleteCriticalSection(&queue->lock); +error_spinlock: + free(queue->array); +error_array: + free(queue); + return NULL; } void MessageQueue_Free(wMessageQueue* queue) diff --git a/winpr/libwinpr/utils/test/TestImage.c b/winpr/libwinpr/utils/test/TestImage.c index ccdbb5a89..7c9833357 100644 --- a/winpr/libwinpr/utils/test/TestImage.c +++ b/winpr/libwinpr/utils/test/TestImage.c @@ -17,23 +17,38 @@ static void *read_image(const char *src, size_t *size) FILE *fsrc = fopen(src, "r"); if (!fsrc) + { + fprintf(stderr, "Failed to open file %s\n", src); goto cleanup; + } if (fseek(fsrc, 0, SEEK_END)) + { + fprintf(stderr, "Failed to seek to file end\n"); goto cleanup; + } src_size = ftell(fsrc); if (fseek(fsrc, 0, SEEK_SET)) + { + fprintf(stderr, "Failed to seek to SEEK_SET\n"); goto cleanup; + } a = malloc(src_size); if (!a) + { + fprintf(stderr, "Failed malloc %zd bytes\n", src_size); goto cleanup; + } - if (fread(a, sizeof(char), src_size, fsrc) != src_size) + if (fread(a, sizeof(char), src_size, fsrc) != src_size) + { + fprintf(stderr, "Failed read %zd bytes\n", src_size); goto cleanup; + } success = 1; *size = src_size; @@ -50,51 +65,50 @@ cleanup: return a; } - -static int compare(const char *src, const char *dst) -{ - int cmp = -1; - size_t asize, bsize; - void *a, *b; - - a = read_image(src, &asize); - b = read_image(dst, &bsize); - - if (!a || !b || (asize != bsize)) - goto cleanup; - - cmp = memcmp(a, b, asize); - -cleanup: - free(a); - free(b); - - return cmp; -} - -static int img_compare(wImage *image, wImage *image2) +static int img_compare(wImage *image, wImage *image2, BOOL ignoreType) { int rc = -1; - if (image->type != image2->type) + if ((image->type != image2->type) && !ignoreType) + { + fprintf(stderr, "Image type mismatch %d:%d\n", image->type, image2->type); goto cleanup; + } if (image->width != image2->width) + { + fprintf(stderr, "Image width mismatch %d:%d\n", image->width, image2->width); goto cleanup; + } if (image->height != image2->height) + { + fprintf(stderr, "Image height mismatch %d:%d\n", image->height, image2->height); goto cleanup; + } if (image->scanline != image2->scanline) + { + fprintf(stderr, "Image scanline mismatch %d:%d\n", image->scanline, image2->scanline); goto cleanup; + } if (image->bitsPerPixel != image2->bitsPerPixel) + { + fprintf(stderr, "Image bitsPerPixel mismatch %d:%d\n", image->bitsPerPixel, image2->bitsPerPixel); goto cleanup; + } if (image->bytesPerPixel != image2->bytesPerPixel) + { + fprintf(stderr, "Image bytesPerPixel mismatch %d:%d\n", image->bytesPerPixel, image2->bytesPerPixel); goto cleanup; + } rc = memcmp(image->data, image2->data, image->scanline * image->height); + if (rc) + fprintf(stderr, "Image data mismatch!\n"); + cleanup: return rc; } @@ -107,12 +121,16 @@ static wImage *get_image(const char *src) image = winpr_image_new(); if (!image) + { + fprintf(stderr, "Failed to create image!"); goto cleanup; + } status = winpr_image_read(image, src); if (status < 0) { + fprintf(stderr, "Failed to read image %s!", src); winpr_image_free(image, TRUE); image = NULL; } @@ -132,7 +150,10 @@ static int create_test(const char *src, const char *dst_png, const char *dst_bmp wImage* image = NULL, *image2 = NULL, *image3 = NULL, *image4 = NULL; if (!PathFileExistsA(src)) + { + fprintf(stderr, "File %s does not exist!", src); return -1; + } image = get_image(src); @@ -145,30 +166,45 @@ static int create_test(const char *src, const char *dst_png, const char *dst_bmp status = winpr_image_write(image, dst_bmp); if (status < 0) + { + fprintf(stderr, "Failed to write image %s!\n", dst_bmp); goto cleanup; + } image->type = WINPR_IMAGE_PNG; status = winpr_image_write(image, dst_png); if (status < 0) + { + fprintf(stderr, "Failed to write image %s!\n", dst_png); goto cleanup; + } /* Read image from buffer, compare. */ buffer = read_image(src, &bsize); if (!buffer) + { + fprintf(stderr, "Failed to read image %s!\n", src); goto cleanup; + } image2 = winpr_image_new(); if (!image2) + { + fprintf(stderr, "Failed to create image!\n"); goto cleanup; + } status = winpr_image_read_buffer(image2, buffer, bsize); if (status < 0) + { + fprintf(stderr, "Failed to read buffer!\n"); goto cleanup; + } - rc = img_compare(image, image2); + rc = img_compare(image, image2, TRUE); if (rc) goto cleanup; @@ -176,7 +212,7 @@ static int create_test(const char *src, const char *dst_png, const char *dst_bmp if (!image3) goto cleanup; - rc = img_compare(image, image3); + rc = img_compare(image, image3, TRUE); if (rc) goto cleanup; @@ -184,8 +220,7 @@ static int create_test(const char *src, const char *dst_png, const char *dst_bmp if (!image4) goto cleanup; - image->type = WINPR_IMAGE_BITMAP; - rc = img_compare(image, image4); + rc = img_compare(image, image4, TRUE); if (rc) goto cleanup; @@ -235,21 +270,13 @@ int test_image_png_to_bmp() if (create_test(src_bmp, dst_png2, dst_bmp2)) return -1; -#if 0 - if (compare(dst_png2, dst_png)) - return -1; - - if (compare(dst_bmp2, dst_bmp)) - return -1; -#endif - - return 1; + return 0; } int TestImage(int argc, char* argv[]) { - test_image_png_to_bmp(); + int rc = test_image_png_to_bmp(); - return 0; + return rc; } diff --git a/winpr/libwinpr/utils/test/TestMessagePipe.c b/winpr/libwinpr/utils/test/TestMessagePipe.c index 215b7a577..ec1fa34ee 100644 --- a/winpr/libwinpr/utils/test/TestMessagePipe.c +++ b/winpr/libwinpr/utils/test/TestMessagePipe.c @@ -15,7 +15,8 @@ static void* message_echo_pipe_client_thread(void* arg) while (index < 100) { - MessageQueue_Post(pipe->In, NULL, 0, (void*) (size_t) index, NULL); + if (!MessageQueue_Post(pipe->In, NULL, 0, (void*) (size_t) index, NULL)) + break; if (!MessageQueue_Wait(pipe->Out)) break; @@ -56,7 +57,8 @@ static void* message_echo_pipe_server_thread(void* arg) count = (int) (size_t) message.wParam; - MessageQueue_Dispatch(pipe->Out, &message); + if (!MessageQueue_Dispatch(pipe->Out, &message)) + break; } } diff --git a/winpr/libwinpr/utils/test/TestMessageQueue.c b/winpr/libwinpr/utils/test/TestMessageQueue.c index 37fb185eb..16da36c15 100644 --- a/winpr/libwinpr/utils/test/TestMessageQueue.c +++ b/winpr/libwinpr/utils/test/TestMessageQueue.c @@ -42,12 +42,12 @@ int TestMessageQueue(int argc, char* argv[]) return 1; } - MessageQueue_Post(queue, NULL, 123, NULL, NULL); - MessageQueue_Post(queue, NULL, 456, NULL, NULL); - MessageQueue_Post(queue, NULL, 789, NULL, NULL); - MessageQueue_PostQuit(queue, 0); - - WaitForSingleObject(thread, INFINITE); + if (!MessageQueue_Post(queue, NULL, 123, NULL, NULL) || + !MessageQueue_Post(queue, NULL, 456, NULL, NULL) || + !MessageQueue_Post(queue, NULL, 789, NULL, NULL) || + !MessageQueue_PostQuit(queue, 0) || + WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) + return -1; MessageQueue_Free(queue); CloseHandle(thread); diff --git a/winpr/libwinpr/utils/wlog/BinaryAppender.c b/winpr/libwinpr/utils/wlog/BinaryAppender.c index 6f8257274..4bc64270d 100644 --- a/winpr/libwinpr/utils/wlog/BinaryAppender.c +++ b/winpr/libwinpr/utils/wlog/BinaryAppender.c @@ -98,7 +98,7 @@ int WLog_BinaryAppender_Open(wLog* log, wLogBinaryAppender* appender) if (!PathFileExistsA(appender->FilePath)) { - if (!CreateDirectoryA(appender->FilePath, 0)) + if (!PathMakePathA(appender->FilePath, 0)) return -1; UnixChangeFileMode(appender->FilePath, 0xFFFF); } diff --git a/winpr/libwinpr/utils/wlog/FileAppender.c b/winpr/libwinpr/utils/wlog/FileAppender.c index c0d2295ae..64a9239be 100644 --- a/winpr/libwinpr/utils/wlog/FileAppender.c +++ b/winpr/libwinpr/utils/wlog/FileAppender.c @@ -95,7 +95,7 @@ int WLog_FileAppender_Open(wLog* log, wLogFileAppender* appender) if (!PathFileExistsA(appender->FilePath)) { - if (!CreateDirectoryA(appender->FilePath, 0)) + if (!PathMakePathA(appender->FilePath, 0)) return -1; UnixChangeFileMode(appender->FilePath, 0xFFFF); } diff --git a/winpr/libwinpr/utils/wlog/Message.c b/winpr/libwinpr/utils/wlog/Message.c index 303b1471d..c8567b92e 100644 --- a/winpr/libwinpr/utils/wlog/Message.c +++ b/winpr/libwinpr/utils/wlog/Message.c @@ -44,7 +44,7 @@ char* WLog_Message_GetOutputFileName(int id, const char* ext) if (!PathFileExistsA(FilePath)) { - if (!CreateDirectoryA(FilePath, NULL)) + if (!PathMakePathA(FilePath, NULL)) { free(FileName); free(FilePath); diff --git a/winpr/test/CMakeLists.txt b/winpr/test/CMakeLists.txt index d2d07c0e6..c7837a184 100644 --- a/winpr/test/CMakeLists.txt +++ b/winpr/test/CMakeLists.txt @@ -4,7 +4,7 @@ set(MODULE_PREFIX "TEST_WINPR") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) -set(${MODULE_PREFIX}_TESTS TestIntrinsics.c) +set(${MODULE_PREFIX}_TESTS TestIntrinsics.c TestTypes.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/winpr/test/TestTypes.c b/winpr/test/TestTypes.c new file mode 100644 index 000000000..cb62a715e --- /dev/null +++ b/winpr/test/TestTypes.c @@ -0,0 +1,117 @@ +/** + * CTest for winpr types and macros + * + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +BOOL TestSucceededFailedMacros(HRESULT hr, char *sym, BOOL isSuccess) +{ + BOOL rv = TRUE; + + if (SUCCEEDED(hr) && !isSuccess) + { + printf("Error: SUCCEEDED with \"%s\" must be false\n", sym); + rv = FALSE; + } + if (!SUCCEEDED(hr) && isSuccess) + { + printf("Error: SUCCEEDED with \"%s\" must be true\n", sym); + rv = FALSE; + } + if (!FAILED(hr) && !isSuccess) + { + printf("Error: FAILED with \"%s\" must be true\n", sym); + rv = FALSE; + } + if (FAILED(hr) && isSuccess) + { + printf("Error: FAILED with \"%s\" must be false\n", sym); + rv = FALSE; + } + + return rv; +} + +int TestTypes(int argc, char* argv[]) +{ + BOOL ok = TRUE; + HRESULT hr; + + if (S_OK != (HRESULT)0L) + { + printf("Error: S_OK should be 0\n"); + goto err; + } + if (S_FALSE != (HRESULT)1L) + { + printf("Error: S_FALSE should be 1\n"); + goto err; + } + + /* Test HRESULT success codes */ + ok &= TestSucceededFailedMacros(S_OK, "S_OK", TRUE); + ok &= TestSucceededFailedMacros(S_FALSE, "S_FALSE", TRUE); + + /* Test some HRESULT error codes */ + ok &= TestSucceededFailedMacros(E_NOTIMPL, "E_NOTIMPL", FALSE); + ok &= TestSucceededFailedMacros(E_OUTOFMEMORY, "E_OUTOFMEMORY", FALSE); + ok &= TestSucceededFailedMacros(E_INVALIDARG, "E_INVALIDARG", FALSE); + ok &= TestSucceededFailedMacros(E_FAIL, "E_FAIL", FALSE); + ok &= TestSucceededFailedMacros(E_ABORT, "E_ABORT", FALSE); + + /* Test some WIN32 error codes converted to HRESULT*/ + hr = HRESULT_FROM_WIN32(ERROR_SUCCESS); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_SUCCESS)", TRUE); + + hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_NOACCESS); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_NOACCESS)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_NOT_FOUND)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_TIMEOUT)", FALSE); + + hr = HRESULT_FROM_WIN32(RPC_S_ZERO_DIVIDE); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(RPC_S_ZERO_DIVIDE)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_STATIC_INIT); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_STATIC_INIT)", FALSE); + + hr = HRESULT_FROM_WIN32(ERROR_ENCRYPTION_FAILED); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(ERROR_ENCRYPTION_FAILED)", FALSE); + + hr = HRESULT_FROM_WIN32(WSAECANCELLED); + ok &= TestSucceededFailedMacros(hr, "HRESULT_FROM_WIN32(WSAECANCELLED)", FALSE); + + if (ok) { + printf("Test completed successfully\n"); + return 0; + } + +err: + printf("Error: Test failed\n"); + return -1; +}