From 0fd705c6c731fd28098ece5f7714e2aa0d7e42fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 16 Aug 2013 16:46:47 -0400 Subject: [PATCH 001/202] channels/cliprdr: start server-side implementation --- channels/cliprdr/CMakeLists.txt | 3 + channels/cliprdr/ChannelOptions.cmake | 2 +- channels/cliprdr/server/CMakeLists.txt | 35 +++++ channels/cliprdr/server/cliprdr_main.c | 184 +++++++++++++++++++++++++ channels/cliprdr/server/cliprdr_main.h | 36 +++++ channels/server/channels.c | 14 +- client/Windows/wf_interface.c | 2 +- client/X11/xf_client.c | 2 +- include/freerdp/channels/wtsvc.h | 1 + include/freerdp/client/cliprdr.h | 2 + include/freerdp/codec/rfx.h | 4 +- include/freerdp/server/cliprdr.h | 59 ++++++++ libfreerdp/codec/rfx.c | 49 +++++-- libfreerdp/gdi/gdi.c | 2 +- server/Mac/mf_peer.c | 2 +- server/Sample/sfreerdp.c | 2 +- server/Windows/wf_update.c | 2 +- server/X11/xf_peer.c | 2 +- 18 files changed, 383 insertions(+), 20 deletions(-) create mode 100644 channels/cliprdr/server/CMakeLists.txt create mode 100644 channels/cliprdr/server/cliprdr_main.c create mode 100644 channels/cliprdr/server/cliprdr_main.h create mode 100644 include/freerdp/server/cliprdr.h diff --git a/channels/cliprdr/CMakeLists.txt b/channels/cliprdr/CMakeLists.txt index b5f1cf4b3..c5cfd729e 100644 --- a/channels/cliprdr/CMakeLists.txt +++ b/channels/cliprdr/CMakeLists.txt @@ -21,3 +21,6 @@ if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() +if(WITH_SERVER_CHANNELS) + add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME}) +endif() diff --git a/channels/cliprdr/ChannelOptions.cmake b/channels/cliprdr/ChannelOptions.cmake index 9cafcd965..f175f3f6a 100644 --- a/channels/cliprdr/ChannelOptions.cmake +++ b/channels/cliprdr/ChannelOptions.cmake @@ -1,7 +1,7 @@ set(OPTION_DEFAULT OFF) set(OPTION_CLIENT_DEFAULT ON) -set(OPTION_SERVER_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT ON) define_channel_options(NAME "cliprdr" TYPE "static" DESCRIPTION "Clipboard Virtual Channel Extension" diff --git a/channels/cliprdr/server/CMakeLists.txt b/channels/cliprdr/server/CMakeLists.txt new file mode 100644 index 000000000..3e2ef0b2d --- /dev/null +++ b/channels/cliprdr/server/CMakeLists.txt @@ -0,0 +1,35 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# 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. + +define_channel_server("cliprdr") + +set(${MODULE_PREFIX}_SRCS + cliprdr_main.c + cliprdr_main.h) + +add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") + +set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-utils) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server") diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c new file mode 100644 index 000000000..732351304 --- /dev/null +++ b/channels/cliprdr/server/cliprdr_main.c @@ -0,0 +1,184 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Clipboard Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "cliprdr_main.h" + +/** + * Initialization Sequence\n + * Client Server\n + * | |\n + * |<----------------------Server Clipboard Capabilities PDU-----------------|\n + * |<-----------------------------Monitor Ready PDU--------------------------|\n + * |-----------------------Client Clipboard Capabilities PDU---------------->|\n + * |---------------------------Temporary Directory PDU---------------------->|\n + * |-------------------------------Format List PDU-------------------------->|\n + * |<--------------------------Format List Response PDU----------------------|\n + * + */ + +static int cliprdr_server_send_capabilities(CliprdrServerContext* context) +{ + return 0; +} + +static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) +{ + return 0; +} + +static int cliprdr_server_send_format_list_response(CliprdrServerContext* context) +{ + return 0; +} + +static void* cliprdr_server_thread(void* arg) +{ + wStream* s; + DWORD status; + DWORD nCount; + void* buffer; + HANDLE events[8]; + HANDLE ChannelEvent; + UINT32 BytesReturned; + CliprdrServerContext* context; + + context = (CliprdrServerContext*) arg; + + buffer = NULL; + BytesReturned = 0; + ChannelEvent = NULL; + + s = Stream_New(NULL, 4096); + + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + { + if (BytesReturned == sizeof(HANDLE)) + CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); + + WTSFreeMemory(buffer); + } + + nCount = 0; + events[nCount++] = ChannelEvent; + events[nCount++] = context->priv->StopEvent; + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) + { + if (BytesReturned == 0) + break; + + Stream_EnsureRemainingCapacity(s, (int) BytesReturned); + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) + { + break; + } + } + } + + Stream_Free(s, TRUE); + + return NULL; +} + +static int cliprdr_server_start(CliprdrServerContext* context) +{ + context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "cliprdr", 0); + + if (!context->priv->ChannelHandle) + return -1; + + context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + context->priv->Thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) cliprdr_server_thread, (void*) context, 0, NULL); + + return 0; +} + +static int cliprdr_server_stop(CliprdrServerContext* context) +{ + SetEvent(context->priv->StopEvent); + + WaitForSingleObject(context->priv->Thread, INFINITE); + CloseHandle(context->priv->Thread); + + return 0; +} + +CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm) +{ + CliprdrServerContext* context; + + context = (CliprdrServerContext*) malloc(sizeof(CliprdrServerContext)); + + if (context) + { + ZeroMemory(context, sizeof(CliprdrServerContext)); + + context->vcm = vcm; + + context->Start = cliprdr_server_start; + context->Stop = cliprdr_server_stop; + + context->SendCapabilities = cliprdr_server_send_capabilities; + context->SendMonitorReady = cliprdr_server_send_monitor_ready; + context->SendFormatListResponse = cliprdr_server_send_format_list_response; + + context->priv = (CliprdrServerPrivate*) malloc(sizeof(CliprdrServerPrivate)); + + if (context->priv) + { + ZeroMemory(context->priv, sizeof(CliprdrServerPrivate)); + } + } + + return context; +} + +void cliprdr_server_context_free(CliprdrServerContext* context) +{ + if (context) + { + if (context->priv) + { + free(context->priv); + } + + free(context); + } +} diff --git a/channels/cliprdr/server/cliprdr_main.h b/channels/cliprdr/server/cliprdr_main.h new file mode 100644 index 000000000..540c33397 --- /dev/null +++ b/channels/cliprdr/server/cliprdr_main.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Clipboard Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H +#define FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H + +#include +#include +#include + +#include + +struct _cliprdr_server_private +{ + HANDLE Thread; + HANDLE StopEvent; + void* ChannelHandle; +}; + +#endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H */ diff --git a/channels/server/channels.c b/channels/server/channels.c index eeae1dc22..2bef6414b 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -42,6 +42,7 @@ #include #include +#include void freerdp_channels_dummy() { @@ -50,6 +51,9 @@ void freerdp_channels_dummy() rdpsnd_server_context_new(NULL); rdpsnd_server_context_free(NULL); + + cliprdr_server_context_new(NULL); + cliprdr_server_context_free(NULL); } /** @@ -420,7 +424,7 @@ WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client) vcm = (WTSVirtualChannelManager*) malloc(sizeof(WTSVirtualChannelManager)); - if (vcm != NULL) + if (vcm) { ZeroMemory(vcm, sizeof(WTSVirtualChannelManager)); @@ -659,6 +663,7 @@ BOOL WTSVirtualChannelQuery( BOOL result = FALSE; rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; ZeroMemory(fds, sizeof(fds)); + switch (WtsVirtualClass) { case WTSVirtualFileHandle: @@ -677,6 +682,13 @@ BOOL WTSVirtualChannelQuery( result = TRUE; break; + case WTSVirtualEventHandle: + *ppBuffer = malloc(sizeof(HANDLE)); + CopyMemory(*ppBuffer, &(channel->receive_event), sizeof(HANDLE)); + *pBytesReturned = sizeof(void*); + result = TRUE; + break; + case WTSVirtualChannelReady: if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC) { diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 9ae2de7df..d3c76aaee 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -371,7 +371,7 @@ BOOL wf_post_connect(freerdp* instance) if (settings->RemoteFxCodec) { wfc->tile = wf_image_new(wfc, 64, 64, 32, NULL); - wfc->rfx_context = rfx_context_new(); + wfc->rfx_context = rfx_context_new(FALSE); } if (settings->NSCodec) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 5ad3f4f04..273df0691 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -893,7 +893,7 @@ BOOL xf_post_connect(freerdp* instance) if (instance->settings->RemoteFxCodec) { - rfx_context = (void*) rfx_context_new(); + rfx_context = (void*) rfx_context_new(FALSE); xfc->rfx_context = rfx_context; } diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h index 227c75fa4..1b59d8ea2 100644 --- a/include/freerdp/channels/wtsvc.h +++ b/include/freerdp/channels/wtsvc.h @@ -43,6 +43,7 @@ typedef enum _WTS_VIRTUAL_CLASS { WTSVirtualClientData, WTSVirtualFileHandle, + WTSVirtualEventHandle, WTSVirtualChannelReady } WTS_VIRTUAL_CLASS; diff --git a/include/freerdp/client/cliprdr.h b/include/freerdp/client/cliprdr.h index ea0d1cf7a..a0455dcf4 100644 --- a/include/freerdp/client/cliprdr.h +++ b/include/freerdp/client/cliprdr.h @@ -20,6 +20,8 @@ #ifndef FREERDP_CHANNEL_CLIENT_CLIPRDR_H #define FREERDP_CHANNEL_CLIENT_CLIPRDR_H +#include + /** * Client Interface */ diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index 254cadfb5..d8fa52c35 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -55,7 +55,6 @@ struct _RFX_TILE int height; BYTE* data; int scanline; - BYTE quantIdxY; BYTE quantIdxCb; BYTE quantIdxCr; @@ -117,6 +116,7 @@ struct _RFX_CONTEXT { RFX_STATE state; + BOOL encoder; UINT16 flags; UINT16 properties; UINT16 width; @@ -152,7 +152,7 @@ struct _RFX_CONTEXT }; typedef struct _RFX_CONTEXT RFX_CONTEXT; -FREERDP_API RFX_CONTEXT* rfx_context_new(void); +FREERDP_API RFX_CONTEXT* rfx_context_new(BOOL encoder); FREERDP_API void rfx_context_free(RFX_CONTEXT* context); FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format); FREERDP_API void rfx_context_reset(RFX_CONTEXT* context); diff --git a/include/freerdp/server/cliprdr.h b/include/freerdp/server/cliprdr.h new file mode 100644 index 000000000..01e612b70 --- /dev/null +++ b/include/freerdp/server/cliprdr.h @@ -0,0 +1,59 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Clipboard Virtual Channel Server Interface + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_CLIPRDR_H +#define FREERDP_CHANNEL_SERVER_CLIPRDR_H + +#include +#include +#include +#include + +/** + * Server Interface + */ + +typedef struct _cliprdr_server_context CliprdrServerContext; +typedef struct _cliprdr_server_private CliprdrServerPrivate; + +typedef int (*psCliprdrStart)(CliprdrServerContext* context); +typedef int (*psCliprdrStop)(CliprdrServerContext* context); + +typedef int (*psCliprdrSendCapabilities)(CliprdrServerContext* context); +typedef int (*psCliprdrSendMonitorReady)(CliprdrServerContext* context); +typedef int (*psCliprdrSendFormatListResponse)(CliprdrServerContext* context); + +struct _cliprdr_server_context +{ + WTSVirtualChannelManager* vcm; + + psCliprdrStart Start; + psCliprdrStop Stop; + + psCliprdrSendCapabilities SendCapabilities; + psCliprdrSendMonitorReady SendMonitorReady; + psCliprdrSendFormatListResponse SendFormatListResponse; + + CliprdrServerPrivate* priv; +}; + +FREERDP_API CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm); +FREERDP_API void cliprdr_server_context_free(CliprdrServerContext* context); + +#endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_H */ diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 5d6bbe7a1..d6e654741 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -153,7 +153,7 @@ void rfx_tile_init(RFX_TILE* tile) } } -RFX_TILE* rfx_tile_new() +RFX_TILE* rfx_decoder_tile_new() { RFX_TILE* tile = NULL; @@ -169,7 +169,7 @@ RFX_TILE* rfx_tile_new() return tile; } -void rfx_tile_free(RFX_TILE* tile) +void rfx_decoder_tile_free(RFX_TILE* tile) { if (tile) { @@ -178,7 +178,29 @@ void rfx_tile_free(RFX_TILE* tile) } } -RFX_CONTEXT* rfx_context_new(void) +RFX_TILE* rfx_encoder_tile_new() +{ + RFX_TILE* tile = NULL; + + tile = (RFX_TILE*) malloc(sizeof(RFX_TILE)); + + if (tile) + { + ZeroMemory(tile, sizeof(RFX_TILE)); + } + + return tile; +} + +void rfx_encoder_tile_free(RFX_TILE* tile) +{ + if (tile) + { + free(tile); + } +} + +RFX_CONTEXT* rfx_context_new(BOOL encoder) { HKEY hKey; LONG status; @@ -191,13 +213,24 @@ RFX_CONTEXT* rfx_context_new(void) context = (RFX_CONTEXT*) malloc(sizeof(RFX_CONTEXT)); ZeroMemory(context, sizeof(RFX_CONTEXT)); + context->encoder = encoder; + context->priv = (RFX_CONTEXT_PRIV*) malloc(sizeof(RFX_CONTEXT_PRIV)); ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV)); context->priv->TilePool = ObjectPool_New(TRUE); - ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_tile_new; ObjectPool_Object(context->priv->TilePool)->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init; - ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_tile_free; + + if (context->encoder) + { + ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new; + ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free; + } + else + { + ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new; + ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free; + } /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) @@ -1065,7 +1098,8 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, if (!context->numQuant) { context->numQuant = 1; - context->quants = (UINT32*) rfx_default_quantization_values; + context->quants = (UINT32*) malloc(sizeof(rfx_default_quantization_values)); + CopyMemory(context->quants, &rfx_default_quantization_values, sizeof(rfx_default_quantization_values)); context->quantIdxY = 0; context->quantIdxCb = 0; context->quantIdxCr = 0; @@ -1225,9 +1259,6 @@ RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, in RFX_MESSAGE* message; RFX_MESSAGE* messages; - printf("rfx_encode_messages: numRects: %d maxDataSize: %d x: %d y: %d w: %d/%d h: %d/%d\n", numRects, maxDataSize, - rects[0].x, rects[0].y, rects[0].width, width, rects[0].height, height); - message = rfx_encode_message(context, rects, numRects, data, width, height, scanline); messages = rfx_split_message(context, message, numMessages, maxDataSize); rfx_message_free(context, message); diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 95443ab57..566a12d13 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -1042,7 +1042,7 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) gdi_register_graphics(instance->context->graphics); - gdi->rfx_context = rfx_context_new(); + gdi->rfx_context = rfx_context_new(FALSE); gdi->nsc_context = nsc_context_new(); return 0; diff --git a/server/Mac/mf_peer.c b/server/Mac/mf_peer.c index 074ece076..0d059cf49 100644 --- a/server/Mac/mf_peer.c +++ b/server/Mac/mf_peer.c @@ -175,7 +175,7 @@ void mf_peer_rfx_update(freerdp_peer* client) int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context) { context->info = mf_info_get_instance(); - context->rfx_context = rfx_context_new(); + context->rfx_context = rfx_context_new(TRUE); context->rfx_context->mode = RLGR3; context->rfx_context->width = client->settings->DesktopWidth; context->rfx_context->height = client->settings->DesktopHeight; diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index e988a2e70..a88986150 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -49,7 +49,7 @@ static BOOL test_dump_rfx_realtime = TRUE; void test_peer_context_new(freerdp_peer* client, testPeerContext* context) { - context->rfx_context = rfx_context_new(); + context->rfx_context = rfx_context_new(TRUE); context->rfx_context->mode = RLGR3; context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH; context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT; diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index e6daf5c57..0332316be 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -198,7 +198,7 @@ void wf_update_encoder_reset(wfInfo* wfi) } else { - wfi->rfx_context = rfx_context_new(); + wfi->rfx_context = rfx_context_new(TRUE); wfi->rfx_context->mode = RLGR3; wfi->rfx_context->width = wfi->servscreen_width; wfi->rfx_context->height = wfi->servscreen_height; diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 7b08eff1a..fe925981a 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -295,7 +295,7 @@ xfInfo* xf_info_init() void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) { context->info = xf_info_init(); - context->rfx_context = rfx_context_new(); + context->rfx_context = rfx_context_new(TRUE); context->rfx_context->mode = RLGR3; context->rfx_context->width = context->info->width; context->rfx_context->height = context->info->height; From bca442a4774b77bd959189e5d8fc89df9d391dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 16 Aug 2013 21:17:24 -0400 Subject: [PATCH 002/202] channels/cliprdr: start exchanging messages with server-side cliprdr --- channels/cliprdr/client/CMakeLists.txt | 1 - channels/cliprdr/client/cliprdr_constants.h | 58 ----- channels/cliprdr/client/cliprdr_format.c | 1 - channels/cliprdr/client/cliprdr_main.c | 1 - channels/cliprdr/client/cliprdr_main.h | 8 - channels/cliprdr/server/cliprdr_main.c | 253 +++++++++++++++++++- channels/cliprdr/server/cliprdr_main.h | 14 ++ channels/server/channels.c | 10 +- include/freerdp/channels/wtsvc.h | 2 + include/freerdp/client/cliprdr.h | 42 ++++ 10 files changed, 316 insertions(+), 74 deletions(-) delete mode 100644 channels/cliprdr/client/cliprdr_constants.h diff --git a/channels/cliprdr/client/CMakeLists.txt b/channels/cliprdr/client/CMakeLists.txt index f1dd07440..00c5605a0 100644 --- a/channels/cliprdr/client/CMakeLists.txt +++ b/channels/cliprdr/client/CMakeLists.txt @@ -18,7 +18,6 @@ define_channel_client("cliprdr") set(${MODULE_PREFIX}_SRCS - cliprdr_constants.h cliprdr_format.c cliprdr_format.h cliprdr_main.c diff --git a/channels/cliprdr/client/cliprdr_constants.h b/channels/cliprdr/client/cliprdr_constants.h deleted file mode 100644 index e3e141986..000000000 --- a/channels/cliprdr/client/cliprdr_constants.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Clipboard Virtual Channel - * - * Copyright 2009-2011 Jay Sorg - * Copyright 2010-2011 Vic Lee - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CLIPRDR_CONSTANTS -#define __CLIPRDR_CONSTANTS - -/* CLIPRDR_HEADER.msgType */ -#define CB_MONITOR_READY 0x0001 -#define CB_FORMAT_LIST 0x0002 -#define CB_FORMAT_LIST_RESPONSE 0x0003 -#define CB_FORMAT_DATA_REQUEST 0x0004 -#define CB_FORMAT_DATA_RESPONSE 0x0005 -#define CB_TEMP_DIRECTORY 0x0006 -#define CB_CLIP_CAPS 0x0007 -#define CB_FILECONTENTS_REQUEST 0x0008 -#define CB_FILECONTENTS_RESPONSE 0x0009 -#define CB_LOCK_CLIPDATA 0x000A -#define CB_UNLOCK_CLIPDATA 0x000B - -/* CLIPRDR_HEADER.msgFlags */ -#define CB_RESPONSE_OK 0x0001 -#define CB_RESPONSE_FAIL 0x0002 -#define CB_ASCII_NAMES 0x0004 - -/* CLIPRDR_CAPS_SET.capabilitySetType */ -#define CB_CAPSTYPE_GENERAL 0x0001 - -/* CLIPRDR_GENERAL_CAPABILITY.lengthCapability */ -#define CB_CAPSTYPE_GENERAL_LEN 12 - -/* CLIPRDR_GENERAL_CAPABILITY.version */ -#define CB_CAPS_VERSION_1 0x00000001 -#define CB_CAPS_VERSION_2 0x00000002 - -/* CLIPRDR_GENERAL_CAPABILITY.generalFlags */ -#define CB_USE_LONG_FORMAT_NAMES 0x00000002 -#define CB_STREAM_FILECLIP_ENABLED 0x00000004 -#define CB_FILECLIP_NO_FILE_PATHS 0x00000008 -#define CB_CAN_LOCK_CLIPDATA 0x00000010 - -#endif /* __CLIPRDR_CONSTANTS */ diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index 426475a64..6345cadef 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -34,7 +34,6 @@ #include #include -#include "cliprdr_constants.h" #include "cliprdr_main.h" #include "cliprdr_format.h" diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index f83abba7a..0ed0d20e9 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -33,7 +33,6 @@ #include #include -#include "cliprdr_constants.h" #include "cliprdr_main.h" #include "cliprdr_format.h" diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index b2b984d31..38d361031 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -25,14 +25,6 @@ #include -struct _CLIPRDR_FORMAT_NAME -{ - UINT32 id; - char* name; - int length; -}; -typedef struct _CLIPRDR_FORMAT_NAME CLIPRDR_FORMAT_NAME; - struct cliprdr_plugin { rdpSvcPlugin plugin; diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 732351304..c8db646a1 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include "cliprdr_main.h" @@ -41,11 +42,69 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context) { + wStream* s; + BOOL status; + UINT32 generalFlags; + CLIPRDR_HEADER header; + + printf("CliprdrServerSendCapabilities\n"); + + header.msgType = CB_CLIP_CAPS; + header.msgFlags = 0; + header.dataLen = 24; + + generalFlags = 0; + + if (context->priv->UseLongFormatNames) + generalFlags |= CB_USE_LONG_FORMAT_NAMES; + + s = Stream_New(NULL, header.dataLen); + + Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */ + Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ + Stream_Write_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ + + Stream_Write_UINT16(s, 1); /* cCapabilitiesSets (2 bytes) */ + Stream_Write_UINT16(s, 0); /* pad1 (2 bytes) */ + + Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType (2 bytes) */ + Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability (2 bytes) */ + Stream_Write_UINT32(s, CB_CAPS_VERSION_2); /* version (4 bytes) */ + Stream_Write_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + return 0; } static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) { + wStream* s; + BOOL status; + CLIPRDR_HEADER header; + + printf("CliprdrServerSendMonitorReady\n"); + + header.msgType = CB_MONITOR_READY; + header.msgFlags = 0; + header.dataLen = 8; + + s = Stream_New(NULL, header.dataLen); + + Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */ + Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ + Stream_Write_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + return 0; } @@ -54,6 +113,184 @@ static int cliprdr_server_send_format_list_response(CliprdrServerContext* contex return 0; } +static int cliprdr_server_receive_capabilities(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +{ + UINT32 version; + UINT32 generalFlags; + UINT16 cCapabilitiesSets; + UINT16 capabilitySetType; + UINT16 lengthCapability; + + Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ + Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ + + Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ + Stream_Read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */ + + Stream_Read_UINT32(s, version); /* version (4 bytes) */ + Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ + + if (generalFlags & CB_USE_LONG_FORMAT_NAMES) + context->priv->UseLongFormatNames = TRUE; + + if (generalFlags & CB_STREAM_FILECLIP_ENABLED) + context->priv->StreamFileClipEnabled = TRUE; + + if (generalFlags & CB_FILECLIP_NO_FILE_PATHS) + context->priv->FileClipNoFilePaths = TRUE; + + if (generalFlags & CB_CAN_LOCK_CLIPDATA) + context->priv->CanLockClipData = TRUE; + + return 0; +} + +int cliprdr_wcslen(const WCHAR* str, const WCHAR* end) +{ + WCHAR* p = (WCHAR*) str; + + if (!p) + return -1; + + while (*p) + { + if (p == end) + return -1; + + p++; + } + + return (p - str); +} + +static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +{ + int i; + WCHAR* end; + int length; + int position; + + position = Stream_GetPosition(s); + end = (WCHAR*) &(Stream_Buffer(s)[Stream_Length(s)]); + + winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); + + context->priv->ClientFormatNameCount = 0; + + while (Stream_GetRemainingLength(s) >= 6) + { + Stream_Seek(s, 4); /* formatId (4 bytes) */ + + length = cliprdr_wcslen((WCHAR*) Stream_Pointer(s), end); + + if (length < 0) + return -1; + + Stream_Seek(s, (length + 1) * 2); /* wszFormatName */ + + context->priv->ClientFormatNameCount = 0; + } + + context->priv->ClientFormatNames = (CLIPRDR_FORMAT_NAME*) + malloc(sizeof(CLIPRDR_FORMAT_NAME) * context->priv->ClientFormatNameCount); + + Stream_SetPosition(s, position); + + for (i = 0; i < context->priv->ClientFormatNameCount; i++) + { + Stream_Read_UINT32(s, context->priv->ClientFormatNames[i].id); /* formatId (4 bytes) */ + + context->priv->ClientFormatNames[i].length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), + -1, &context->priv->ClientFormatNames[i].name, 0, NULL, NULL); + + Stream_Seek(s, (context->priv->ClientFormatNames[i].length + 1) * 2); + } + + for (i = 0; i < context->priv->ClientFormatNameCount; i++) + { + printf("Format %d: Id: 0x%04X Name: %s\n", i, + context->priv->ClientFormatNames[i].id, + context->priv->ClientFormatNames[i].name); + } + + return 0; +} + +static int cliprdr_server_receive_short_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +{ + printf("%s: unimplemented\n", __FUNCTION__); + return 0; +} + +static int cliprdr_server_receive_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +{ + int status; + + if (context->priv->UseLongFormatNames) + { + status = cliprdr_server_receive_long_format_list(context, s, header); + } + else + { + status = cliprdr_server_receive_short_format_list(context, s, header); + } + + return status; +} + +static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s) +{ + CLIPRDR_HEADER header; + + Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ + Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ + Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ + + printf("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n", + header.msgType, header.msgFlags, header.dataLen); + + switch (header.msgType) + { + case CB_CLIP_CAPS: + cliprdr_server_receive_capabilities(context, s, &header); + break; + + case CB_TEMP_DIRECTORY: + break; + + case CB_FORMAT_LIST: + cliprdr_server_receive_format_list(context, s, &header); + break; + + case CB_FORMAT_LIST_RESPONSE: + break; + + case CB_LOCK_CLIPDATA: + break; + + case CB_UNLOCK_CLIPDATA: + break; + + case CB_FORMAT_DATA_REQUEST: + break; + + case CB_FORMAT_DATA_RESPONSE: + break; + + case CB_FILECONTENTS_REQUEST: + break; + + case CB_FILECONTENTS_RESPONSE: + break; + + default: + printf("Unexpected clipboard PDU type: %d\n", header.msgType); + break; + } + + return 0; +} + static void* cliprdr_server_thread(void* arg) { wStream* s; @@ -85,6 +322,9 @@ static void* cliprdr_server_thread(void* arg) events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; + context->SendCapabilities(context); + context->SendMonitorReady(context); + while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); @@ -97,17 +337,24 @@ static void* cliprdr_server_thread(void* arg) if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { - if (BytesReturned == 0) + if (!BytesReturned) break; - Stream_EnsureRemainingCapacity(s, (int) BytesReturned); + Stream_EnsureRemainingCapacity(s, BytesReturned); if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { break; } + + Stream_Seek(s, BytesReturned); } + + Stream_SealLength(s); + Stream_SetPosition(s, 0); + + cliprdr_server_receive_pdu(context, s); } Stream_Free(s, TRUE); @@ -164,6 +411,8 @@ CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm) if (context->priv) { ZeroMemory(context->priv, sizeof(CliprdrServerPrivate)); + + context->priv->UseLongFormatNames = TRUE; } } diff --git a/channels/cliprdr/server/cliprdr_main.h b/channels/cliprdr/server/cliprdr_main.h index 540c33397..b72902b64 100644 --- a/channels/cliprdr/server/cliprdr_main.h +++ b/channels/cliprdr/server/cliprdr_main.h @@ -26,11 +26,25 @@ #include +struct _CLIPRDR_HEADER +{ + UINT16 msgType; + UINT16 msgFlags; + UINT32 dataLen; +}; +typedef struct _CLIPRDR_HEADER CLIPRDR_HEADER; + struct _cliprdr_server_private { HANDLE Thread; HANDLE StopEvent; void* ChannelHandle; + BOOL UseLongFormatNames; + BOOL StreamFileClipEnabled; + BOOL FileClipNoFilePaths; + BOOL CanLockClipData; + UINT32 ClientFormatNameCount; + CLIPRDR_FORMAT_NAME* ClientFormatNames; }; #endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H */ diff --git a/channels/server/channels.c b/channels/server/channels.c index 2bef6414b..174df7f48 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -474,8 +474,7 @@ void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) } } -void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, - void** fds, int* fds_count) +void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, void** fds, int* fds_count) { void* fd; @@ -543,6 +542,11 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm) return result; } +HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm) +{ + return vcm->send_event; +} + void* WTSVirtualChannelOpenEx( /* __in */ WTSVirtualChannelManager* vcm, /* __in */ const char* pVirtualName, @@ -786,7 +790,7 @@ BOOL WTSVirtualChannelWrite( int first; UINT32 written; - if (channel == NULL) + if (!channel) return FALSE; if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC) diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h index 1b59d8ea2..118cfdaa8 100644 --- a/include/freerdp/channels/wtsvc.h +++ b/include/freerdp/channels/wtsvc.h @@ -60,6 +60,8 @@ FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelMana void** fds, int* fds_count); FREERDP_API BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm); +FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm); + /** * Opens a static or dynamic virtual channel and return the handle. If the * operation fails, a NULL handle is returned. diff --git a/include/freerdp/client/cliprdr.h b/include/freerdp/client/cliprdr.h index a0455dcf4..6cf137eab 100644 --- a/include/freerdp/client/cliprdr.h +++ b/include/freerdp/client/cliprdr.h @@ -54,6 +54,48 @@ struct _cliprdr_client_context #define CB_FORMAT_JPEG 0xD012 #define CB_FORMAT_GIF 0xD013 +/* CLIPRDR_HEADER.msgType */ +#define CB_MONITOR_READY 0x0001 +#define CB_FORMAT_LIST 0x0002 +#define CB_FORMAT_LIST_RESPONSE 0x0003 +#define CB_FORMAT_DATA_REQUEST 0x0004 +#define CB_FORMAT_DATA_RESPONSE 0x0005 +#define CB_TEMP_DIRECTORY 0x0006 +#define CB_CLIP_CAPS 0x0007 +#define CB_FILECONTENTS_REQUEST 0x0008 +#define CB_FILECONTENTS_RESPONSE 0x0009 +#define CB_LOCK_CLIPDATA 0x000A +#define CB_UNLOCK_CLIPDATA 0x000B + +/* CLIPRDR_HEADER.msgFlags */ +#define CB_RESPONSE_OK 0x0001 +#define CB_RESPONSE_FAIL 0x0002 +#define CB_ASCII_NAMES 0x0004 + +/* CLIPRDR_CAPS_SET.capabilitySetType */ +#define CB_CAPSTYPE_GENERAL 0x0001 + +/* CLIPRDR_GENERAL_CAPABILITY.lengthCapability */ +#define CB_CAPSTYPE_GENERAL_LEN 12 + +/* CLIPRDR_GENERAL_CAPABILITY.version */ +#define CB_CAPS_VERSION_1 0x00000001 +#define CB_CAPS_VERSION_2 0x00000002 + +/* CLIPRDR_GENERAL_CAPABILITY.generalFlags */ +#define CB_USE_LONG_FORMAT_NAMES 0x00000002 +#define CB_STREAM_FILECLIP_ENABLED 0x00000004 +#define CB_FILECLIP_NO_FILE_PATHS 0x00000008 +#define CB_CAN_LOCK_CLIPDATA 0x00000010 + +struct _CLIPRDR_FORMAT_NAME +{ + UINT32 id; + char* name; + int length; +}; +typedef struct _CLIPRDR_FORMAT_NAME CLIPRDR_FORMAT_NAME; + /** * Clipboard Events */ From af93bee5d22aa784eeb22e624a1d8ad108c4c177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 18 Aug 2013 15:39:28 -0400 Subject: [PATCH 003/202] channels/cliprdr: implement initialization of server-side cliprdr --- channels/cliprdr/client/cliprdr_main.c | 10 ++ channels/cliprdr/server/cliprdr_main.c | 150 ++++++++++++++++++------- channels/cliprdr/server/cliprdr_main.h | 4 + channels/server/channels.c | 4 +- include/freerdp/server/cliprdr.h | 8 -- 5 files changed, 125 insertions(+), 51 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 0ed0d20e9..8475b5c74 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -76,6 +77,11 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) Stream_Write_UINT32(s, dataLen); Stream_SetPosition(s, pos); +#ifdef WITH_DEBUG_CLIPRDR + printf("Cliprdr Sending (%d bytes)\n", dataLen + 8); + winpr_HexDump(Stream_Buffer(s), dataLen + 8); +#endif + svc_plugin_send((rdpSvcPlugin*) cliprdr, s); } @@ -206,6 +212,10 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d", CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); +#ifdef WITH_DEBUG_CLIPRDR + winpr_HexDump(Stream_Buffer(s), dataLen + 8); +#endif + switch (msgType) { case CB_CLIP_CAPS: diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index c8db646a1..5aef92961 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -40,6 +40,28 @@ * */ +/** + * Data Transfer Sequences\n + * Shared Local\n + * Clipboard Owner Clipboard Owner\n + * | |\n + * |-------------------------------------------------------------------------|\n _ + * |-------------------------------Format List PDU-------------------------->|\n | + * |<--------------------------Format List Response PDU----------------------|\n _| Copy Sequence + * |<---------------------Lock Clipboard Data PDU (Optional)-----------------|\n + * |-------------------------------------------------------------------------|\n + * |-------------------------------------------------------------------------|\n _ + * |<--------------------------Format Data Request PDU-----------------------|\n | Paste Sequence Palette, + * |---------------------------Format Data Response PDU--------------------->|\n _| Metafile, File List Data + * |-------------------------------------------------------------------------|\n + * |-------------------------------------------------------------------------|\n _ + * |<------------------------Format Contents Request PDU---------------------|\n | Paste Sequence + * |-------------------------Format Contents Response PDU------------------->|\n _| File Stream Data + * |<---------------------Lock Clipboard Data PDU (Optional)-----------------|\n + * |-------------------------------------------------------------------------|\n + * + */ + static int cliprdr_server_send_capabilities(CliprdrServerContext* context) { wStream* s; @@ -51,14 +73,14 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context) header.msgType = CB_CLIP_CAPS; header.msgFlags = 0; - header.dataLen = 24; + header.dataLen = 16; generalFlags = 0; if (context->priv->UseLongFormatNames) generalFlags |= CB_USE_LONG_FORMAT_NAMES; - s = Stream_New(NULL, header.dataLen); + s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH); Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */ Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ @@ -91,9 +113,9 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) header.msgType = CB_MONITOR_READY; header.msgFlags = 0; - header.dataLen = 8; + header.dataLen = 0; - s = Stream_New(NULL, header.dataLen); + s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH); Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */ Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ @@ -110,6 +132,28 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) static int cliprdr_server_send_format_list_response(CliprdrServerContext* context) { + wStream* s; + BOOL status; + CLIPRDR_HEADER header; + + printf("CliprdrServerSendFormatListResponse\n"); + + header.msgType = CB_FORMAT_LIST_RESPONSE; + header.msgFlags = CB_RESPONSE_OK; + header.dataLen = 0; + + s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH); + + Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */ + Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ + Stream_Write_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + return 0; } @@ -163,6 +207,21 @@ int cliprdr_wcslen(const WCHAR* str, const WCHAR* end) return (p - str); } +static void cliprdr_free_format_list(UINT32 count, CLIPRDR_FORMAT_NAME* formatNames) +{ + int i; + + if (formatNames) + { + for (i = 0; i < count; i++) + { + free(formatNames[i].name); + } + + free(formatNames); + } +} + static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { int i; @@ -171,11 +230,13 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context int position; position = Stream_GetPosition(s); - end = (WCHAR*) &(Stream_Buffer(s)[Stream_Length(s)]); - - winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); + Stream_SetPosition(s, Stream_Length(s)); + end = (WCHAR*) Stream_Pointer(s); + Stream_SetPosition(s, position); + cliprdr_free_format_list(context->priv->ClientFormatNameCount, context->priv->ClientFormatNames); context->priv->ClientFormatNameCount = 0; + context->priv->ClientFormatNames = NULL; while (Stream_GetRemainingLength(s) >= 6) { @@ -188,7 +249,7 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context Stream_Seek(s, (length + 1) * 2); /* wszFormatName */ - context->priv->ClientFormatNameCount = 0; + context->priv->ClientFormatNameCount++; } context->priv->ClientFormatNames = (CLIPRDR_FORMAT_NAME*) @@ -235,31 +296,27 @@ static int cliprdr_server_receive_format_list(CliprdrServerContext* context, wSt status = cliprdr_server_receive_short_format_list(context, s, header); } + cliprdr_server_send_format_list_response(context); + return status; } -static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s) +static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { - CLIPRDR_HEADER header; - - Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ - Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ - Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ - printf("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n", - header.msgType, header.msgFlags, header.dataLen); + header->msgType, header->msgFlags, header->dataLen); - switch (header.msgType) + switch (header->msgType) { case CB_CLIP_CAPS: - cliprdr_server_receive_capabilities(context, s, &header); + cliprdr_server_receive_capabilities(context, s, header); break; case CB_TEMP_DIRECTORY: break; case CB_FORMAT_LIST: - cliprdr_server_receive_format_list(context, s, &header); + cliprdr_server_receive_format_list(context, s, header); break; case CB_FORMAT_LIST_RESPONSE: @@ -284,7 +341,7 @@ static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s) break; default: - printf("Unexpected clipboard PDU type: %d\n", header.msgType); + printf("Unexpected clipboard PDU type: %d\n", header->msgType); break; } @@ -297,9 +354,11 @@ static void* cliprdr_server_thread(void* arg) DWORD status; DWORD nCount; void* buffer; + int position; HANDLE events[8]; HANDLE ChannelEvent; UINT32 BytesReturned; + CLIPRDR_HEADER header; CliprdrServerContext* context; context = (CliprdrServerContext*) arg; @@ -322,8 +381,8 @@ static void* cliprdr_server_thread(void* arg) events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; - context->SendCapabilities(context); - context->SendMonitorReady(context); + cliprdr_server_send_capabilities(context); + cliprdr_server_send_monitor_ready(context); while (1) { @@ -335,26 +394,36 @@ static void* cliprdr_server_thread(void* arg) } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + { + if (BytesReturned) + Stream_Seek(s, BytesReturned); + } + else { - if (!BytesReturned) - break; - Stream_EnsureRemainingCapacity(s, BytesReturned); - - if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) - { - break; - } - - Stream_Seek(s, BytesReturned); } - Stream_SealLength(s); - Stream_SetPosition(s, 0); + if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH) + { + position = Stream_GetPosition(s); + Stream_SetPosition(s, 0); - cliprdr_server_receive_pdu(context, s); + Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ + Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ + Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ + + Stream_SetPosition(s, position); + + if (Stream_GetPosition(s) >= (header.dataLen + CLIPRDR_HEADER_LENGTH)) + { + Stream_SealLength(s); + Stream_SetPosition(s, CLIPRDR_HEADER_LENGTH); + + cliprdr_server_receive_pdu(context, s, &header); + Stream_SetPosition(s, 0); + } + } } Stream_Free(s, TRUE); @@ -402,10 +471,6 @@ CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm) context->Start = cliprdr_server_start; context->Stop = cliprdr_server_stop; - context->SendCapabilities = cliprdr_server_send_capabilities; - context->SendMonitorReady = cliprdr_server_send_monitor_ready; - context->SendFormatListResponse = cliprdr_server_send_format_list_response; - context->priv = (CliprdrServerPrivate*) malloc(sizeof(CliprdrServerPrivate)); if (context->priv) @@ -413,6 +478,9 @@ CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm) ZeroMemory(context->priv, sizeof(CliprdrServerPrivate)); context->priv->UseLongFormatNames = TRUE; + context->priv->StreamFileClipEnabled = TRUE; + context->priv->FileClipNoFilePaths = TRUE; + context->priv->CanLockClipData = TRUE; } } diff --git a/channels/cliprdr/server/cliprdr_main.h b/channels/cliprdr/server/cliprdr_main.h index b72902b64..ae6a85c24 100644 --- a/channels/cliprdr/server/cliprdr_main.h +++ b/channels/cliprdr/server/cliprdr_main.h @@ -26,6 +26,8 @@ #include +#define CLIPRDR_HEADER_LENGTH 8 + struct _CLIPRDR_HEADER { UINT16 msgType; @@ -39,10 +41,12 @@ struct _cliprdr_server_private HANDLE Thread; HANDLE StopEvent; void* ChannelHandle; + BOOL UseLongFormatNames; BOOL StreamFileClipEnabled; BOOL FileClipNoFilePaths; BOOL CanLockClipData; + UINT32 ClientFormatNameCount; CLIPRDR_FORMAT_NAME* ClientFormatNames; }; diff --git a/channels/server/channels.c b/channels/server/channels.c index 174df7f48..9ae0c08e5 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -749,7 +749,7 @@ BOOL WTSVirtualChannelRead( item = (wts_data_item*) list_peek(channel->receive_queue); - if (item == NULL) + if (!item) { ResetEvent(channel->receive_event); *pBytesRead = 0; @@ -771,7 +771,7 @@ BOOL WTSVirtualChannelRead( ReleaseMutex(channel->mutex); CopyMemory(Buffer, item->buffer, item->length); - wts_data_item_free(item) ; + wts_data_item_free(item); return TRUE; } diff --git a/include/freerdp/server/cliprdr.h b/include/freerdp/server/cliprdr.h index 01e612b70..946eb7652 100644 --- a/include/freerdp/server/cliprdr.h +++ b/include/freerdp/server/cliprdr.h @@ -35,10 +35,6 @@ typedef struct _cliprdr_server_private CliprdrServerPrivate; typedef int (*psCliprdrStart)(CliprdrServerContext* context); typedef int (*psCliprdrStop)(CliprdrServerContext* context); -typedef int (*psCliprdrSendCapabilities)(CliprdrServerContext* context); -typedef int (*psCliprdrSendMonitorReady)(CliprdrServerContext* context); -typedef int (*psCliprdrSendFormatListResponse)(CliprdrServerContext* context); - struct _cliprdr_server_context { WTSVirtualChannelManager* vcm; @@ -46,10 +42,6 @@ struct _cliprdr_server_context psCliprdrStart Start; psCliprdrStop Stop; - psCliprdrSendCapabilities SendCapabilities; - psCliprdrSendMonitorReady SendMonitorReady; - psCliprdrSendFormatListResponse SendFormatListResponse; - CliprdrServerPrivate* priv; }; From 363bd27d7670101574ca71ed198911fc81879ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 18 Aug 2013 18:09:12 -0400 Subject: [PATCH 004/202] channels/rdpdr: start server-side device redirection --- channels/rdpdr/CMakeLists.txt | 4 + channels/rdpdr/ChannelOptions.cmake | 2 +- channels/rdpdr/client/rdpdr_capabilities.c | 122 ++--- channels/rdpdr/server/CMakeLists.txt | 35 ++ channels/rdpdr/server/rdpdr_main.c | 572 +++++++++++++++++++++ channels/rdpdr/server/rdpdr_main.h | 67 +++ channels/server/channels.c | 4 + include/freerdp/server/rdpdr.h | 51 ++ 8 files changed, 795 insertions(+), 62 deletions(-) create mode 100644 channels/rdpdr/server/CMakeLists.txt create mode 100644 channels/rdpdr/server/rdpdr_main.c create mode 100644 channels/rdpdr/server/rdpdr_main.h create mode 100644 include/freerdp/server/rdpdr.h diff --git a/channels/rdpdr/CMakeLists.txt b/channels/rdpdr/CMakeLists.txt index fc4eb638a..e9b418159 100644 --- a/channels/rdpdr/CMakeLists.txt +++ b/channels/rdpdr/CMakeLists.txt @@ -20,3 +20,7 @@ define_channel("rdpdr") if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() + +if(WITH_SERVER_CHANNELS) + add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME}) +endif() diff --git a/channels/rdpdr/ChannelOptions.cmake b/channels/rdpdr/ChannelOptions.cmake index 3bc158571..9a966768c 100644 --- a/channels/rdpdr/ChannelOptions.cmake +++ b/channels/rdpdr/ChannelOptions.cmake @@ -1,7 +1,7 @@ set(OPTION_DEFAULT OFF) set(OPTION_CLIENT_DEFAULT ON) -set(OPTION_SERVER_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT ON) define_channel_options(NAME "rdpdr" TYPE "static" DESCRIPTION "Device Redirection Virtual Channel Extension" diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index 025977c92..21f90699d 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -33,132 +33,132 @@ #include "rdpdr_capabilities.h" /* Output device redirection capability set header */ -static void rdpdr_write_capset_header(wStream* data_out, UINT16 capabilityType, UINT16 capabilityLength, UINT32 version) +static void rdpdr_write_capset_header(wStream* s, UINT16 capabilityType, UINT16 capabilityLength, UINT32 version) { - Stream_Write_UINT16(data_out, capabilityType); - Stream_Write_UINT16(data_out, capabilityLength); - Stream_Write_UINT32(data_out, version); + Stream_Write_UINT16(s, capabilityType); + Stream_Write_UINT16(s, capabilityLength); + Stream_Write_UINT32(s, version); } /* Output device direction general capability set */ -static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* data_out) +static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s) { - rdpdr_write_capset_header(data_out, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02); + rdpdr_write_capset_header(s, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02); - Stream_Write_UINT32(data_out, 0); /* osType, ignored on receipt */ - Stream_Write_UINT32(data_out, 0); /* osVersion, unused and must be set to zero */ - Stream_Write_UINT16(data_out, 1); /* protocolMajorVersion, must be set to 1 */ - Stream_Write_UINT16(data_out, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */ - Stream_Write_UINT32(data_out, 0x0000FFFF); /* ioCode1 */ - Stream_Write_UINT32(data_out, 0); /* ioCode2, must be set to zero, reserved for future use */ - Stream_Write_UINT32(data_out, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */ - Stream_Write_UINT32(data_out, ENABLE_ASYNCIO); /* extraFlags1 */ - Stream_Write_UINT32(data_out, 0); /* extraFlags2, must be set to zero, reserved for future use */ - Stream_Write_UINT32(data_out, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */ + Stream_Write_UINT32(s, 0); /* osType, ignored on receipt */ + Stream_Write_UINT32(s, 0); /* osVersion, unused and must be set to zero */ + Stream_Write_UINT16(s, 1); /* protocolMajorVersion, must be set to 1 */ + Stream_Write_UINT16(s, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */ + Stream_Write_UINT32(s, 0x0000FFFF); /* ioCode1 */ + Stream_Write_UINT32(s, 0); /* ioCode2, must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */ + Stream_Write_UINT32(s, ENABLE_ASYNCIO); /* extraFlags1 */ + Stream_Write_UINT32(s, 0); /* extraFlags2, must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */ } /* Process device direction general capability set */ -static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* data_in) +static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s) { UINT16 capabilityLength; - Stream_Read_UINT16(data_in, capabilityLength); - Stream_Seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(s, capabilityLength); + Stream_Seek(s, capabilityLength - 4); } /* Output printer direction capability set */ -static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* data_out) +static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* s) { - rdpdr_write_capset_header(data_out, CAP_PRINTER_TYPE, 8, PRINT_CAPABILITY_VERSION_01); + rdpdr_write_capset_header(s, CAP_PRINTER_TYPE, 8, PRINT_CAPABILITY_VERSION_01); } /* Process printer direction capability set */ -static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* data_in) +static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s) { UINT16 capabilityLength; - Stream_Read_UINT16(data_in, capabilityLength); - Stream_Seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(s, capabilityLength); + Stream_Seek(s, capabilityLength - 4); } /* Output port redirection capability set */ -static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* data_out) +static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* s) { - rdpdr_write_capset_header(data_out, CAP_PORT_TYPE, 8, PORT_CAPABILITY_VERSION_01); + rdpdr_write_capset_header(s, CAP_PORT_TYPE, 8, PORT_CAPABILITY_VERSION_01); } /* Process port redirection capability set */ -static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* data_in) +static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s) { UINT16 capabilityLength; - Stream_Read_UINT16(data_in, capabilityLength); - Stream_Seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(s, capabilityLength); + Stream_Seek(s, capabilityLength - 4); } /* Output drive redirection capability set */ -static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* data_out) +static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* s) { - rdpdr_write_capset_header(data_out, CAP_DRIVE_TYPE, 8, DRIVE_CAPABILITY_VERSION_02); + rdpdr_write_capset_header(s, CAP_DRIVE_TYPE, 8, DRIVE_CAPABILITY_VERSION_02); } /* Process drive redirection capability set */ -static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* data_in) +static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s) { UINT16 capabilityLength; - Stream_Read_UINT16(data_in, capabilityLength); - Stream_Seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(s, capabilityLength); + Stream_Seek(s, capabilityLength - 4); } /* Output smart card redirection capability set */ -static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* data_out) +static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) { - rdpdr_write_capset_header(data_out, CAP_SMARTCARD_TYPE, 8, SMARTCARD_CAPABILITY_VERSION_01); + rdpdr_write_capset_header(s, CAP_SMARTCARD_TYPE, 8, SMARTCARD_CAPABILITY_VERSION_01); } /* Process smartcard redirection capability set */ -static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* data_in) +static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s) { UINT16 capabilityLength; - Stream_Read_UINT16(data_in, capabilityLength); - Stream_Seek(data_in, capabilityLength - 4); + Stream_Read_UINT16(s, capabilityLength); + Stream_Seek(s, capabilityLength - 4); } -void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* data_in) +void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) { UINT16 i; UINT16 numCapabilities; UINT16 capabilityType; - Stream_Read_UINT16(data_in, numCapabilities); - Stream_Seek(data_in, 2); /* pad (2 bytes) */ + Stream_Read_UINT16(s, numCapabilities); + Stream_Seek(s, 2); /* pad (2 bytes) */ - for(i = 0; i < numCapabilities; i++) + for (i = 0; i < numCapabilities; i++) { - Stream_Read_UINT16(data_in, capabilityType); + Stream_Read_UINT16(s, capabilityType); switch (capabilityType) { case CAP_GENERAL_TYPE: - rdpdr_process_general_capset(rdpdr, data_in); + rdpdr_process_general_capset(rdpdr, s); break; case CAP_PRINTER_TYPE: - rdpdr_process_printer_capset(rdpdr, data_in); + rdpdr_process_printer_capset(rdpdr, s); break; case CAP_PORT_TYPE: - rdpdr_process_port_capset(rdpdr, data_in); + rdpdr_process_port_capset(rdpdr, s); break; case CAP_DRIVE_TYPE: - rdpdr_process_drive_capset(rdpdr, data_in); + rdpdr_process_drive_capset(rdpdr, s); break; case CAP_SMARTCARD_TYPE: - rdpdr_process_smartcard_capset(rdpdr, data_in); + rdpdr_process_smartcard_capset(rdpdr, s); break; default: @@ -170,21 +170,21 @@ void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* data_in) void rdpdr_send_capability_response(rdpdrPlugin* rdpdr) { - wStream* data_out; + wStream* s; - data_out = Stream_New(NULL, 256); + s = Stream_New(NULL, 256); - Stream_Write_UINT16(data_out, RDPDR_CTYP_CORE); - Stream_Write_UINT16(data_out, PAKID_CORE_CLIENT_CAPABILITY); + Stream_Write_UINT16(s, RDPDR_CTYP_CORE); + Stream_Write_UINT16(s, PAKID_CORE_CLIENT_CAPABILITY); - Stream_Write_UINT16(data_out, 5); /* numCapabilities */ - Stream_Write_UINT16(data_out, 0); /* pad */ + Stream_Write_UINT16(s, 5); /* numCapabilities */ + Stream_Write_UINT16(s, 0); /* pad */ - rdpdr_write_general_capset(rdpdr, data_out); - rdpdr_write_printer_capset(rdpdr, data_out); - rdpdr_write_port_capset(rdpdr, data_out); - rdpdr_write_drive_capset(rdpdr, data_out); - rdpdr_write_smartcard_capset(rdpdr, data_out); + rdpdr_write_general_capset(rdpdr, s); + rdpdr_write_printer_capset(rdpdr, s); + rdpdr_write_port_capset(rdpdr, s); + rdpdr_write_drive_capset(rdpdr, s); + rdpdr_write_smartcard_capset(rdpdr, s); - svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); + svc_plugin_send((rdpSvcPlugin*)rdpdr, s); } diff --git a/channels/rdpdr/server/CMakeLists.txt b/channels/rdpdr/server/CMakeLists.txt new file mode 100644 index 000000000..a7dd06c03 --- /dev/null +++ b/channels/rdpdr/server/CMakeLists.txt @@ -0,0 +1,35 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# 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. + +define_channel_server("rdpdr") + +set(${MODULE_PREFIX}_SRCS + rdpdr_main.c + rdpdr_main.h) + +add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") + +set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-utils) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server") diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c new file mode 100644 index 000000000..141a38c3c --- /dev/null +++ b/channels/rdpdr/server/rdpdr_main.c @@ -0,0 +1,572 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Device Redirection Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "rdpdr_main.h" + +static UINT32 g_ClientId = 0; + +static int cliprdr_server_send_announce_request(RdpdrServerContext* context) +{ + wStream* s; + BOOL status; + RDPDR_HEADER header; + + printf("RdpdrServerSendAnnounceRequest\n"); + + header.Component = RDPDR_CTYP_CORE; + header.PacketId = PAKID_CORE_SERVER_ANNOUNCE; + + s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8); + + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ + Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ + + Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */ + Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */ + Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + + return 0; +} + +static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +{ + UINT32 ClientId; + UINT16 VersionMajor; + UINT16 VersionMinor; + + Stream_Read_UINT16(s, VersionMajor); /* VersionMajor (2 bytes) */ + Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */ + Stream_Read_UINT32(s, ClientId); /* ClientId (4 bytes) */ + + printf("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n", + VersionMajor, VersionMinor, ClientId); + + return 0; +} + +static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +{ + UINT32 UnicodeFlag; + UINT32 ComputerNameLen; + + Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */ + Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */ + Stream_Read_UINT32(s, ComputerNameLen); /* ComputerNameLen (4 bytes) */ + + /** + * Caution: ComputerNameLen is given *bytes*, + * not in characters, including the NULL terminator! + */ + + if (UnicodeFlag) + { + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), + -1, &(context->priv->ClientComputerName), 0, NULL, NULL); + } + else + { + context->priv->ClientComputerName = _strdup((char*) Stream_Pointer(s)); + } + + Stream_Seek(s, ComputerNameLen); + + printf("ClientComputerName: %s\n", context->priv->ClientComputerName); + + return 0; +} + +static int rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + Stream_Read_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */ + Stream_Read_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */ + Stream_Read_UINT32(s, header->Version); /* Version (4 bytes) */ + return 0; +} + +static int rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + Stream_Write_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */ + Stream_Write_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */ + Stream_Write_UINT32(s, header->Version); /* Version (4 bytes) */ + return 0; +} + +static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + UINT32 ioCode1; + UINT32 extraFlags1; + UINT32 extendedPdu; + UINT16 VersionMajor; + UINT16 VersionMinor; + UINT32 SpecialTypeDeviceCap; + + Stream_Seek_UINT32(s); /* osType (4 bytes), ignored on receipt */ + Stream_Seek_UINT32(s); /* osVersion (4 bytes), unused and must be set to zero */ + Stream_Read_UINT16(s, VersionMajor); /* protocolMajorVersion (2 bytes) */ + Stream_Read_UINT16(s, VersionMinor); /* protocolMinorVersion (2 bytes) */ + Stream_Read_UINT32(s, ioCode1); /* ioCode1 (4 bytes) */ + Stream_Seek_UINT32(s); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Read_UINT32(s, extendedPdu); /* extendedPdu (4 bytes) */ + Stream_Read_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */ + Stream_Seek_UINT32(s); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ + + return 0; +} + +static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context, wStream* s) +{ + UINT32 ioCode1; + UINT32 extendedPdu; + UINT32 extraFlags1; + UINT32 SpecialTypeDeviceCap; + RDPDR_CAPABILITY_HEADER header; + + header.CapabilityType = CAP_GENERAL_TYPE; + header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH + 36; + header.Version = GENERAL_CAPABILITY_VERSION_02; + + ioCode1 = 0; + ioCode1 |= RDPDR_IRP_MJ_CREATE; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_CLEANUP; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_CLOSE; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_READ; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_WRITE; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_FLUSH_BUFFERS; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_SHUTDOWN; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_DEVICE_CONTROL; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_QUERY_VOLUME_INFORMATION; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_SET_VOLUME_INFORMATION; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_QUERY_INFORMATION; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_SET_INFORMATION; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_DIRECTORY_CONTROL; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_LOCK_CONTROL; /* always set */ + ioCode1 |= RDPDR_IRP_MJ_QUERY_SECURITY; /* optional */ + ioCode1 |= RDPDR_IRP_MJ_SET_SECURITY; /* optional */ + + extendedPdu = 0; + extendedPdu |= RDPDR_CLIENT_DISPLAY_NAME_PDU; /* always set */ + extendedPdu |= RDPDR_DEVICE_REMOVE_PDUS; /* optional */ + extendedPdu |= RDPDR_USER_LOGGEDON_PDU; /* optional */ + + extraFlags1 = 0; + extraFlags1 |= ENABLE_ASYNCIO; /* optional */ + + SpecialTypeDeviceCap = 0; + + Stream_EnsureRemainingCapacity(s, header.CapabilityLength); + rdpdr_server_write_capability_set_header(s, &header); + + Stream_Write_UINT32(s, 0); /* osType (4 bytes), ignored on receipt */ + Stream_Write_UINT32(s, 0); /* osVersion (4 bytes), unused and must be set to zero */ + Stream_Write_UINT16(s, context->priv->VersionMajor); /* protocolMajorVersion (2 bytes) */ + Stream_Write_UINT16(s, context->priv->VersionMinor); /* protocolMinorVersion (2 bytes) */ + Stream_Write_UINT32(s, ioCode1); /* ioCode1 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, extendedPdu); /* extendedPdu (4 bytes) */ + Stream_Write_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */ + Stream_Write_UINT32(s, 0); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ + + return 0; +} + +static int rdpdr_server_read_printer_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + return 0; +} + +static int rdpdr_server_write_printer_capability_set(RdpdrServerContext* context, wStream* s) +{ + RDPDR_CAPABILITY_HEADER header; + + header.CapabilityType = CAP_PRINTER_TYPE; + header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; + header.Version = PRINT_CAPABILITY_VERSION_01; + + Stream_EnsureRemainingCapacity(s, header.CapabilityLength); + rdpdr_server_write_capability_set_header(s, &header); + + return 0; +} + +static int rdpdr_server_read_port_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + return 0; +} + +static int rdpdr_server_write_port_capability_set(RdpdrServerContext* context, wStream* s) +{ + RDPDR_CAPABILITY_HEADER header; + + header.CapabilityType = CAP_PORT_TYPE; + header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; + header.Version = PORT_CAPABILITY_VERSION_01; + + Stream_EnsureRemainingCapacity(s, header.CapabilityLength); + rdpdr_server_write_capability_set_header(s, &header); + + return 0; +} + +static int rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + return 0; +} + +static int rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, wStream* s) +{ + RDPDR_CAPABILITY_HEADER header; + + header.CapabilityType = CAP_DRIVE_TYPE; + header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; + header.Version = DRIVE_CAPABILITY_VERSION_02; + + Stream_EnsureRemainingCapacity(s, header.CapabilityLength); + rdpdr_server_write_capability_set_header(s, &header); + + return 0; +} + +static int rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +{ + return 0; +} + +static int rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* context, wStream* s) +{ + RDPDR_CAPABILITY_HEADER header; + + header.CapabilityType = CAP_SMARTCARD_TYPE; + header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; + header.Version = SMARTCARD_CAPABILITY_VERSION_01; + + Stream_EnsureRemainingCapacity(s, header.CapabilityLength); + rdpdr_server_write_capability_set_header(s, &header); + + return 0; +} + +static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context) +{ + wStream* s; + BOOL status; + RDPDR_HEADER header; + UINT16 numCapabilities; + + printf("RdpdrServerSendCoreCapabilityRequest\n"); + + header.Component = RDPDR_CTYP_CORE; + header.PacketId = PAKID_CORE_SERVER_CAPABILITY; + + numCapabilities = 5; + + s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 512); + + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ + Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ + + Stream_Write_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */ + Stream_Write_UINT16(s, 0); /* Padding (2 bytes) */ + + rdpdr_server_write_general_capability_set(context, s); + rdpdr_server_write_printer_capability_set(context, s); + rdpdr_server_write_port_capability_set(context, s); + rdpdr_server_write_drive_capability_set(context, s); + rdpdr_server_write_smartcard_capability_set(context, s); + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + + return 0; +} + +static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +{ + int i; + UINT16 numCapabilities; + RDPDR_CAPABILITY_HEADER capabilityHeader; + + Stream_Read_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */ + Stream_Seek_UINT16(s); /* Padding (2 bytes) */ + + for (i = 0; i < numCapabilities; i++) + { + rdpdr_server_read_capability_set_header(s, &capabilityHeader); + + switch (capabilityHeader.CapabilityType) + { + case CAP_GENERAL_TYPE: + rdpdr_server_read_general_capability_set(context, s, &capabilityHeader); + break; + + case CAP_PRINTER_TYPE: + rdpdr_server_read_printer_capability_set(context, s, &capabilityHeader); + break; + + case CAP_PORT_TYPE: + rdpdr_server_read_port_capability_set(context, s, &capabilityHeader); + break; + + case CAP_DRIVE_TYPE: + rdpdr_server_read_drive_capability_set(context, s, &capabilityHeader); + break; + + case CAP_SMARTCARD_TYPE: + rdpdr_server_read_smartcard_capability_set(context, s, &capabilityHeader); + break; + + default: + printf("Unknown capabilityType %d\n", capabilityHeader.CapabilityType); + Stream_Seek(s, capabilityHeader.CapabilityLength - RDPDR_CAPABILITY_HEADER_LENGTH); + break; + } + } + + return 0; +} + +static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +{ + printf("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n", + header->Component, header->PacketId); + + winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); + + if (header->Component == RDPDR_CTYP_CORE) + { + switch (header->PacketId) + { + case PAKID_CORE_CLIENTID_CONFIRM: + rdpdr_server_receive_announce_response(context, s, header); + break; + + case PAKID_CORE_CLIENT_NAME: + rdpdr_server_receive_client_name_request(context, s, header); + rdpdr_server_send_core_capability_request(context); + break; + + case PAKID_CORE_CLIENT_CAPABILITY: + rdpdr_server_receive_core_capability_response(context, s, header); + break; + + case PAKID_CORE_DEVICELIST_ANNOUNCE: + break; + + case PAKID_CORE_DEVICE_REPLY: + break; + + case PAKID_CORE_DEVICE_IOREQUEST: + break; + + case PAKID_CORE_DEVICE_IOCOMPLETION: + break; + + case PAKID_CORE_DEVICELIST_REMOVE: + break; + + default: + break; + } + } + else if (header->Component == RDPDR_CTYP_PRN) + { + switch (header->PacketId) + { + case PAKID_PRN_CACHE_DATA: + break; + + case PAKID_PRN_USING_XPS: + break; + + default: + break; + } + } + else + { + printf("Unknown RDPDR_HEADER.Component: 0x%04X\n", header->Component); + return -1; + } + + return 0; +} + +static void* rdpdr_server_thread(void* arg) +{ + wStream* s; + DWORD status; + DWORD nCount; + void* buffer; + int position; + HANDLE events[8]; + RDPDR_HEADER header; + HANDLE ChannelEvent; + UINT32 BytesReturned; + RdpdrServerContext* context; + + context = (RdpdrServerContext*) arg; + + buffer = NULL; + BytesReturned = 0; + ChannelEvent = NULL; + + s = Stream_New(NULL, 4096); + + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + { + if (BytesReturned == sizeof(HANDLE)) + CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); + + WTSFreeMemory(buffer); + } + + nCount = 0; + events[nCount++] = ChannelEvent; + events[nCount++] = context->priv->StopEvent; + + cliprdr_server_send_announce_request(context); + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + { + if (BytesReturned) + Stream_Seek(s, BytesReturned); + } + else + { + Stream_EnsureRemainingCapacity(s, BytesReturned); + } + + if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH) + { + position = Stream_GetPosition(s); + Stream_SetPosition(s, 0); + + Stream_Read_UINT16(s, header.Component); /* Component (2 bytes) */ + Stream_Read_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ + + Stream_SetPosition(s, position); + + Stream_SealLength(s); + Stream_SetPosition(s, RDPDR_HEADER_LENGTH); + + rdpdr_server_receive_pdu(context, s, &header); + Stream_SetPosition(s, 0); + } + } + + Stream_Free(s, TRUE); + + return NULL; +} + +static int rdpdr_server_start(RdpdrServerContext* context) +{ + context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpdr", 0); + + if (!context->priv->ChannelHandle) + return -1; + + context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + context->priv->Thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL); + + return 0; +} + +static int rdpdr_server_stop(RdpdrServerContext* context) +{ + SetEvent(context->priv->StopEvent); + + WaitForSingleObject(context->priv->Thread, INFINITE); + CloseHandle(context->priv->Thread); + + return 0; +} + +RdpdrServerContext* rdpdr_server_context_new(WTSVirtualChannelManager* vcm) +{ + RdpdrServerContext* context; + + context = (RdpdrServerContext*) malloc(sizeof(RdpdrServerContext)); + + if (context) + { + ZeroMemory(context, sizeof(RdpdrServerContext)); + + context->vcm = vcm; + + context->Start = rdpdr_server_start; + context->Stop = rdpdr_server_stop; + + context->priv = (RdpdrServerPrivate*) malloc(sizeof(RdpdrServerPrivate)); + + if (context->priv) + { + ZeroMemory(context->priv, sizeof(RdpdrServerPrivate)); + + context->priv->VersionMajor = RDPDR_VERSION_MAJOR; + context->priv->VersionMinor = RDPDR_VERSION_MINOR_RDP6X; + context->priv->ClientId = g_ClientId++; + } + } + + return context; +} + +void rdpdr_server_context_free(RdpdrServerContext* context) +{ + if (context) + { + if (context->priv) + { + free(context->priv); + } + + free(context); + } +} diff --git a/channels/rdpdr/server/rdpdr_main.h b/channels/rdpdr/server/rdpdr_main.h new file mode 100644 index 000000000..ea2504fda --- /dev/null +++ b/channels/rdpdr/server/rdpdr_main.h @@ -0,0 +1,67 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Device Redirection Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H +#define FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H + +#include +#include +#include + +#include + +struct _rdpdr_server_private +{ + HANDLE Thread; + HANDLE StopEvent; + void* ChannelHandle; + + UINT32 ClientId; + UINT16 VersionMajor; + UINT16 VersionMinor; + char* ClientComputerName; +}; + +#define RDPDR_HEADER_LENGTH 4 + +struct _RDPDR_HEADER +{ + UINT16 Component; + UINT16 PacketId; +}; +typedef struct _RDPDR_HEADER RDPDR_HEADER; + +#define RDPDR_VERSION_MAJOR 0x0001 + +#define RDPDR_VERSION_MINOR_RDP50 0x0002 +#define RDPDR_VERSION_MINOR_RDP51 0x0005 +#define RDPDR_VERSION_MINOR_RDP52 0x000A +#define RDPDR_VERSION_MINOR_RDP6X 0x000C + +#define RDPDR_CAPABILITY_HEADER_LENGTH 8 + +struct _RDPDR_CAPABILITY_HEADER +{ + UINT16 CapabilityType; + UINT16 CapabilityLength; + UINT32 Version; +}; +typedef struct _RDPDR_CAPABILITY_HEADER RDPDR_CAPABILITY_HEADER; + +#endif /* FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H */ diff --git a/channels/server/channels.c b/channels/server/channels.c index 9ae0c08e5..12935146a 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -43,6 +43,7 @@ #include #include #include +#include void freerdp_channels_dummy() { @@ -54,6 +55,9 @@ void freerdp_channels_dummy() cliprdr_server_context_new(NULL); cliprdr_server_context_free(NULL); + + rdpdr_server_context_new(NULL); + rdpdr_server_context_free(NULL); } /** diff --git a/include/freerdp/server/rdpdr.h b/include/freerdp/server/rdpdr.h new file mode 100644 index 000000000..d24be3fcd --- /dev/null +++ b/include/freerdp/server/rdpdr.h @@ -0,0 +1,51 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Device Redirection Virtual Channel Server Interface + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_RDPDR_H +#define FREERDP_CHANNEL_SERVER_RDPDR_H + +#include +#include +#include +#include + +/** + * Server Interface + */ + +typedef struct _rdpdr_server_context RdpdrServerContext; +typedef struct _rdpdr_server_private RdpdrServerPrivate; + +typedef int (*psRdpdrStart)(RdpdrServerContext* context); +typedef int (*psRdpdrStop)(RdpdrServerContext* context); + +struct _rdpdr_server_context +{ + WTSVirtualChannelManager* vcm; + + psRdpdrStart Start; + psRdpdrStop Stop; + + RdpdrServerPrivate* priv; +}; + +FREERDP_API RdpdrServerContext* rdpdr_server_context_new(WTSVirtualChannelManager* vcm); +FREERDP_API void rdpdr_server_context_free(RdpdrServerContext* context); + +#endif /* FREERDP_CHANNEL_SERVER_RDPDR_H */ From 3d0d65e917b9263cffca843c04b115d630b62f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 18 Aug 2013 20:27:50 -0400 Subject: [PATCH 005/202] channels/rdpdr: server-side device list and user logged on pdu --- channels/cliprdr/server/cliprdr_main.c | 21 +++++ channels/cliprdr/server/cliprdr_main.h | 2 + channels/rdpdr/server/rdpdr_main.c | 125 ++++++++++++++++++++++++- channels/rdpdr/server/rdpdr_main.h | 3 + 4 files changed, 148 insertions(+), 3 deletions(-) diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 5aef92961..0171209d5 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -189,6 +189,26 @@ static int cliprdr_server_receive_capabilities(CliprdrServerContext* context, wS return 0; } +static int cliprdr_server_receive_temporary_directory(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +{ + WCHAR* wszTempDir; + + if (Stream_GetRemainingLength(s) < 520) + return -1; + + wszTempDir = (WCHAR*) Stream_Pointer(s); + + if (wszTempDir[260] != 0) + return -1; + + ConvertFromUnicode(CP_UTF8, 0, wszTempDir, -1, + &(context->priv->ClientTemporaryDirectory), 0, NULL, NULL); + + printf("ClientTemporaryDirectory: %s\n", context->priv->ClientTemporaryDirectory); + + return 0; +} + int cliprdr_wcslen(const WCHAR* str, const WCHAR* end) { WCHAR* p = (WCHAR*) str; @@ -313,6 +333,7 @@ static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, break; case CB_TEMP_DIRECTORY: + cliprdr_server_receive_temporary_directory(context, s, header); break; case CB_FORMAT_LIST: diff --git a/channels/cliprdr/server/cliprdr_main.h b/channels/cliprdr/server/cliprdr_main.h index ae6a85c24..3e201eeb3 100644 --- a/channels/cliprdr/server/cliprdr_main.h +++ b/channels/cliprdr/server/cliprdr_main.h @@ -49,6 +49,8 @@ struct _cliprdr_server_private UINT32 ClientFormatNameCount; CLIPRDR_FORMAT_NAME* ClientFormatNames; + + char* ClientTemporaryDirectory; }; #endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_MAIN_H */ diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 141a38c3c..77c0cd7d2 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -29,7 +29,7 @@ static UINT32 g_ClientId = 0; -static int cliprdr_server_send_announce_request(RdpdrServerContext* context) +static int rdpdr_server_send_announce_request(RdpdrServerContext* context) { wStream* s; BOOL status; @@ -71,6 +71,8 @@ static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, w printf("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n", VersionMajor, VersionMinor, ClientId); + context->priv->ClientId = ClientId; + return 0; } @@ -141,6 +143,8 @@ static int rdpdr_server_read_general_capability_set(RdpdrServerContext* context, Stream_Seek_UINT32(s); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ + context->priv->UserLoggedOnPdu = (extendedPdu & RDPDR_USER_LOGGEDON_PDU) ? TRUE : FALSE; + return 0; } @@ -177,7 +181,9 @@ static int rdpdr_server_write_general_capability_set(RdpdrServerContext* context extendedPdu = 0; extendedPdu |= RDPDR_CLIENT_DISPLAY_NAME_PDU; /* always set */ extendedPdu |= RDPDR_DEVICE_REMOVE_PDUS; /* optional */ - extendedPdu |= RDPDR_USER_LOGGEDON_PDU; /* optional */ + + if (context->priv->UserLoggedOnPdu) + extendedPdu |= RDPDR_USER_LOGGEDON_PDU; /* optional */ extraFlags1 = 0; extraFlags1 |= ENABLE_ASYNCIO; /* optional */ @@ -359,6 +365,112 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con return 0; } +static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context) +{ + wStream* s; + BOOL status; + RDPDR_HEADER header; + + printf("RdpdrServerSendClientIdConfirm\n"); + + header.Component = RDPDR_CTYP_CORE; + header.PacketId = PAKID_CORE_CLIENTID_CONFIRM; + + s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8); + + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ + Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ + + Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */ + Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */ + Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + + return 0; +} + +static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +{ + int i; + UINT32 DeviceCount; + UINT32 DeviceType; + UINT32 DeviceId; + char PreferredDosName[9]; + UINT32 DeviceDataLength; + + PreferredDosName[8] = 0; + + Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ + + printf("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount); + + for (i = 0; i < DeviceCount; i++) + { + Stream_Read_UINT32(s, DeviceType); /* DeviceType (4 bytes) */ + Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ + Stream_Read(s, PreferredDosName, 8); /* PreferredDosName (8 bytes) */ + Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */ + + printf("Device %d Name: %s Id: 0x%04X DataLength: %d\n", + i, PreferredDosName, DeviceId, DeviceDataLength); + + switch (DeviceId) + { + case RDPDR_DTYP_FILESYSTEM: + break; + + case RDPDR_DTYP_PRINT: + break; + + case RDPDR_DTYP_SERIAL: + break; + + case RDPDR_DTYP_PARALLEL: + break; + + case RDPDR_DTYP_SMARTCARD: + break; + + default: + break; + } + + Stream_Seek(s, DeviceDataLength); + } + + return 0; +} + +static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context) +{ + wStream* s; + BOOL status; + RDPDR_HEADER header; + + printf("%s\n", __FUNCTION__); + + header.Component = RDPDR_CTYP_CORE; + header.PacketId = PAKID_CORE_USER_LOGGEDON; + + s = Stream_New(NULL, RDPDR_HEADER_LENGTH); + + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ + Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ + + Stream_SealLength(s); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + + Stream_Free(s, TRUE); + + return 0; +} + static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) { printf("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n", @@ -381,9 +493,14 @@ static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDP case PAKID_CORE_CLIENT_CAPABILITY: rdpdr_server_receive_core_capability_response(context, s, header); + rdpdr_server_send_client_id_confirm(context); + + if (context->priv->UserLoggedOnPdu) + rdpdr_server_send_user_logged_on(context); break; case PAKID_CORE_DEVICELIST_ANNOUNCE: + rdpdr_server_receive_device_list_announce_request(context, s, header); break; case PAKID_CORE_DEVICE_REPLY: @@ -458,7 +575,7 @@ static void* rdpdr_server_thread(void* arg) events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; - cliprdr_server_send_announce_request(context); + rdpdr_server_send_announce_request(context); while (1) { @@ -552,6 +669,8 @@ RdpdrServerContext* rdpdr_server_context_new(WTSVirtualChannelManager* vcm) context->priv->VersionMajor = RDPDR_VERSION_MAJOR; context->priv->VersionMinor = RDPDR_VERSION_MINOR_RDP6X; context->priv->ClientId = g_ClientId++; + + context->priv->UserLoggedOnPdu = TRUE; } } diff --git a/channels/rdpdr/server/rdpdr_main.h b/channels/rdpdr/server/rdpdr_main.h index ea2504fda..9472f44da 100644 --- a/channels/rdpdr/server/rdpdr_main.h +++ b/channels/rdpdr/server/rdpdr_main.h @@ -24,6 +24,7 @@ #include #include +#include #include struct _rdpdr_server_private @@ -36,6 +37,8 @@ struct _rdpdr_server_private UINT16 VersionMajor; UINT16 VersionMinor; char* ClientComputerName; + + BOOL UserLoggedOnPdu; }; #define RDPDR_HEADER_LENGTH 4 From 23a8354656a9048bf25116abd98a05c45b2133c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 18 Aug 2013 21:52:55 -0400 Subject: [PATCH 006/202] channels: rdpsnd refactoring, drdynvc initial server-side code --- channels/drdynvc/CMakeLists.txt | 3 + channels/drdynvc/ChannelOptions.cmake | 2 +- channels/drdynvc/server/CMakeLists.txt | 35 ++ channels/drdynvc/server/drdynvc_main.c | 149 +++++++ channels/drdynvc/server/drdynvc_main.h | 37 ++ channels/rdpsnd/server/CMakeLists.txt | 3 +- channels/rdpsnd/server/rdpsnd.c | 560 ------------------------ channels/rdpsnd/server/rdpsnd_main.c | 572 +++++++++++++++++++++++++ channels/rdpsnd/server/rdpsnd_main.h | 48 +++ channels/server/channels.c | 4 + include/freerdp/server/drdynvc.h | 50 +++ include/freerdp/server/rdpsnd.h | 26 +- server/Mac/mf_interface.h | 2 +- server/Mac/mf_rdpsnd.c | 2 +- server/Mac/mf_rdpsnd.h | 2 +- server/Sample/sf_rdpsnd.c | 2 +- server/Sample/sfreerdp.h | 2 +- server/Windows/wf_directsound.c | 2 +- server/Windows/wf_directsound.h | 2 +- server/Windows/wf_interface.h | 2 +- server/Windows/wf_rdpsnd.c | 2 +- server/Windows/wf_wasapi.c | 2 +- server/Windows/wf_wasapi.h | 2 +- 23 files changed, 930 insertions(+), 581 deletions(-) create mode 100644 channels/drdynvc/server/CMakeLists.txt create mode 100644 channels/drdynvc/server/drdynvc_main.c create mode 100644 channels/drdynvc/server/drdynvc_main.h delete mode 100644 channels/rdpsnd/server/rdpsnd.c create mode 100644 channels/rdpsnd/server/rdpsnd_main.c create mode 100644 channels/rdpsnd/server/rdpsnd_main.h create mode 100644 include/freerdp/server/drdynvc.h diff --git a/channels/drdynvc/CMakeLists.txt b/channels/drdynvc/CMakeLists.txt index 8fc41cb90..9a6ee1ff6 100644 --- a/channels/drdynvc/CMakeLists.txt +++ b/channels/drdynvc/CMakeLists.txt @@ -21,3 +21,6 @@ if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() +if(WITH_SERVER_CHANNELS) + add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME}) +endif() diff --git a/channels/drdynvc/ChannelOptions.cmake b/channels/drdynvc/ChannelOptions.cmake index 1b226e64d..76376b6bf 100644 --- a/channels/drdynvc/ChannelOptions.cmake +++ b/channels/drdynvc/ChannelOptions.cmake @@ -1,7 +1,7 @@ set(OPTION_DEFAULT OFF) set(OPTION_CLIENT_DEFAULT ON) -set(OPTION_SERVER_DEFAULT OFF) +set(OPTION_SERVER_DEFAULT ON) define_channel_options(NAME "drdynvc" TYPE "static" DESCRIPTION "Dynamic Virtual Channel Extension" diff --git a/channels/drdynvc/server/CMakeLists.txt b/channels/drdynvc/server/CMakeLists.txt new file mode 100644 index 000000000..8b7c27d25 --- /dev/null +++ b/channels/drdynvc/server/CMakeLists.txt @@ -0,0 +1,35 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# 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. + +define_channel_server("drdynvc") + +set(${MODULE_PREFIX}_SRCS + drdynvc_main.c + drdynvc_main.h) + +add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") + +set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-utils) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server") diff --git a/channels/drdynvc/server/drdynvc_main.c b/channels/drdynvc/server/drdynvc_main.c new file mode 100644 index 000000000..2897023d4 --- /dev/null +++ b/channels/drdynvc/server/drdynvc_main.c @@ -0,0 +1,149 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Dynamic Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "drdynvc_main.h" + +static void* drdynvc_server_thread(void* arg) +{ + wStream* s; + DWORD status; + DWORD nCount; + void* buffer; + HANDLE events[8]; + HANDLE ChannelEvent; + UINT32 BytesReturned; + DrdynvcServerContext* context; + + context = (DrdynvcServerContext*) arg; + + buffer = NULL; + BytesReturned = 0; + ChannelEvent = NULL; + + s = Stream_New(NULL, 4096); + + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + { + if (BytesReturned == sizeof(HANDLE)) + CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); + + WTSFreeMemory(buffer); + } + + nCount = 0; + events[nCount++] = ChannelEvent; + events[nCount++] = context->priv->StopEvent; + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + { + if (BytesReturned) + Stream_Seek(s, BytesReturned); + } + else + { + Stream_EnsureRemainingCapacity(s, BytesReturned); + } + } + + Stream_Free(s, TRUE); + + return NULL; +} + +static int drdynvc_server_start(DrdynvcServerContext* context) +{ + context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpdr", 0); + + if (!context->priv->ChannelHandle) + return -1; + + context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + context->priv->Thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) drdynvc_server_thread, (void*) context, 0, NULL); + + return 0; +} + +static int drdynvc_server_stop(DrdynvcServerContext* context) +{ + SetEvent(context->priv->StopEvent); + + WaitForSingleObject(context->priv->Thread, INFINITE); + CloseHandle(context->priv->Thread); + + return 0; +} + +DrdynvcServerContext* drdynvc_server_context_new(WTSVirtualChannelManager* vcm) +{ + DrdynvcServerContext* context; + + context = (DrdynvcServerContext*) malloc(sizeof(DrdynvcServerContext)); + + if (context) + { + ZeroMemory(context, sizeof(DrdynvcServerContext)); + + context->vcm = vcm; + + context->Start = drdynvc_server_start; + context->Stop = drdynvc_server_stop; + + context->priv = (DrdynvcServerPrivate*) malloc(sizeof(DrdynvcServerPrivate)); + + if (context->priv) + { + ZeroMemory(context->priv, sizeof(DrdynvcServerPrivate)); + } + } + + return context; +} + +void drdynvc_server_context_free(DrdynvcServerContext* context) +{ + if (context) + { + if (context->priv) + { + free(context->priv); + } + + free(context); + } +} diff --git a/channels/drdynvc/server/drdynvc_main.h b/channels/drdynvc/server/drdynvc_main.h new file mode 100644 index 000000000..aa69b5706 --- /dev/null +++ b/channels/drdynvc/server/drdynvc_main.h @@ -0,0 +1,37 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Dynamic Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_DRDYNVC_MAIN_H +#define FREERDP_CHANNEL_SERVER_DRDYNVC_MAIN_H + +#include +#include +#include + +#include +#include + +struct _drdynvc_server_private +{ + HANDLE Thread; + HANDLE StopEvent; + void* ChannelHandle; +}; + +#endif /* FREERDP_CHANNEL_SERVER_DRDYNVC_MAIN_H */ diff --git a/channels/rdpsnd/server/CMakeLists.txt b/channels/rdpsnd/server/CMakeLists.txt index b6d0c0901..c98816d68 100644 --- a/channels/rdpsnd/server/CMakeLists.txt +++ b/channels/rdpsnd/server/CMakeLists.txt @@ -18,7 +18,8 @@ define_channel_server("rdpsnd") set(${MODULE_PREFIX}_SRCS - rdpsnd.c) + rdpsnd_main.c + rdpsnd_main.h) add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") diff --git a/channels/rdpsnd/server/rdpsnd.c b/channels/rdpsnd/server/rdpsnd.c deleted file mode 100644 index 57a9593a2..000000000 --- a/channels/rdpsnd/server/rdpsnd.c +++ /dev/null @@ -1,560 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Server Audio Virtual Channel - * - * Copyright 2012 Vic Lee - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -typedef struct _rdpsnd_server -{ - rdpsnd_server_context context; - - HANDLE thread; - HANDLE StopEvent; - void* rdpsnd_channel; - wStream* rdpsnd_pdu; - - FREERDP_DSP_CONTEXT* dsp_context; - BYTE* out_buffer; - int out_buffer_size; - int out_frames; - int out_pending_frames; - - UINT32 src_bytes_per_sample; - UINT32 src_bytes_per_frame; -} rdpsnd_server; - - -static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, wStream* s) -{ - int pos; - UINT16 i; - BOOL status; - - Stream_Write_UINT8(s, SNDC_FORMATS); - Stream_Write_UINT8(s, 0); - Stream_Seek_UINT16(s); - - Stream_Write_UINT32(s, 0); /* dwFlags */ - Stream_Write_UINT32(s, 0); /* dwVolume */ - Stream_Write_UINT32(s, 0); /* dwPitch */ - Stream_Write_UINT16(s, 0); /* wDGramPort */ - Stream_Write_UINT16(s, rdpsnd->context.num_server_formats); /* wNumberOfFormats */ - Stream_Write_UINT8(s, rdpsnd->context.block_no); /* cLastBlockConfirmed */ - Stream_Write_UINT16(s, 0x06); /* wVersion */ - Stream_Write_UINT8(s, 0); /* bPad */ - - for (i = 0; i < rdpsnd->context.num_server_formats; i++) - { - Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ - Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].nChannels); /* nChannels */ - Stream_Write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ - - Stream_Write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec * - rdpsnd->context.server_formats[i].nChannels * - rdpsnd->context.server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ - - Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].nBlockAlign); /* nBlockAlign */ - Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].wBitsPerSample); /* wBitsPerSample */ - Stream_Write_UINT16(s, rdpsnd->context.server_formats[i].cbSize); /* cbSize */ - - if (rdpsnd->context.server_formats[i].cbSize > 0) - { - Stream_Write(s, rdpsnd->context.server_formats[i].data, rdpsnd->context.server_formats[i].cbSize); - } - } - - pos = Stream_GetPosition(s); - Stream_SetPosition(s, 2); - Stream_Write_UINT16(s, pos - 4); - Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); - Stream_SetPosition(s, 0); - - return status; -} - -static void rdpsnd_server_recv_waveconfirm(rdpsnd_server* rdpsnd, wStream* s) -{ - //unhandled for now - - UINT16 timestamp = 0; - BYTE confirmBlockNum = 0; - Stream_Read_UINT16(s, timestamp); - Stream_Read_UINT8(s, confirmBlockNum); - Stream_Seek_UINT8(s); // padding -} - -static void rdpsnd_server_recv_quality_mode(rdpsnd_server* rdpsnd, wStream* s) -{ - //unhandled for now - UINT16 quality; - - Stream_Read_UINT16(s, quality); - Stream_Seek_UINT16(s); // reserved - - fprintf(stderr, "Client requested sound quality: %#0X\n", quality); -} - -static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, wStream* s) -{ - int i, num_known_format = 0; - UINT32 flags, vol, pitch; - UINT16 udpPort, version; - BYTE lastblock; - - - Stream_Read_UINT32(s, flags); /* dwFlags */ - Stream_Read_UINT32(s, vol); /* dwVolume */ - Stream_Read_UINT32(s, pitch); /* dwPitch */ - Stream_Read_UINT16(s, udpPort); /* wDGramPort */ - Stream_Read_UINT16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */ - Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */ - Stream_Read_UINT16(s, version); /* wVersion */ - Stream_Seek_UINT8(s); /* bPad */ - - if (rdpsnd->context.num_client_formats > 0) - { - rdpsnd->context.client_formats = (AUDIO_FORMAT*) malloc(rdpsnd->context.num_client_formats * sizeof(AUDIO_FORMAT)); - ZeroMemory(rdpsnd->context.client_formats, sizeof(AUDIO_FORMAT)); - - for (i = 0; i < rdpsnd->context.num_client_formats; i++) - { - Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].wFormatTag); - Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].nChannels); - Stream_Read_UINT32(s, rdpsnd->context.client_formats[i].nSamplesPerSec); - Stream_Read_UINT32(s, rdpsnd->context.client_formats[i].nAvgBytesPerSec); - Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].nBlockAlign); - Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].wBitsPerSample); - Stream_Read_UINT16(s, rdpsnd->context.client_formats[i].cbSize); - - if (rdpsnd->context.client_formats[i].cbSize > 0) - { - Stream_Seek(s, rdpsnd->context.client_formats[i].cbSize); - } - - if (rdpsnd->context.client_formats[i].wFormatTag != 0) - { - //lets call this a known format - //TODO: actually look through our own list of known formats - num_known_format++; - } - } - } - - if (num_known_format == 0) - { - fprintf(stderr, "Client doesnt support any known formats!\n"); - return FALSE; - } - - return TRUE; -} - -static void* rdpsnd_server_thread_func(void* arg) -{ - void* fd; - wStream* s; - void* buffer; - DWORD status; - BYTE msgType; - UINT16 BodySize; - HANDLE events[2]; - UINT32 bytes_returned = 0; - rdpsnd_server* rdpsnd = (rdpsnd_server*) arg; - - events[0] = rdpsnd->StopEvent; - - if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) - { - fd = *((void**) buffer); - WTSFreeMemory(buffer); - - events[1] = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd); - } - - s = Stream_New(NULL, 4096); - - rdpsnd_server_send_formats(rdpsnd, s); - - while (1) - { - status = WaitForMultipleObjects(2, events, FALSE, INFINITE); - - if (WaitForSingleObject(rdpsnd->StopEvent, 0) == WAIT_OBJECT_0) - { - break; - } - - Stream_SetPosition(s, 0); - - if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) - { - if (bytes_returned == 0) - break; - - Stream_EnsureRemainingCapacity(s, (int) bytes_returned); - - if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) - break; - } - - Stream_Read_UINT8(s, msgType); - Stream_Seek_UINT8(s); /* bPad */ - Stream_Read_UINT16(s, BodySize); - - switch (msgType) - { - case SNDC_WAVECONFIRM: - rdpsnd_server_recv_waveconfirm(rdpsnd, s); - break; - - case SNDC_QUALITYMODE: - rdpsnd_server_recv_quality_mode(rdpsnd, s); - break; - case SNDC_FORMATS: - if (rdpsnd_server_recv_formats(rdpsnd, s)) - { - IFCALL(rdpsnd->context.Activated, &rdpsnd->context); - } - break; - default: - fprintf(stderr, "UNKOWN MESSAGE TYPE!! (%#0X)\n\n", msgType); - break; - } - } - - Stream_Free(s, TRUE); - - return NULL; -} - -static BOOL rdpsnd_server_initialize(rdpsnd_server_context* context) -{ - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - - rdpsnd->rdpsnd_channel = WTSVirtualChannelOpenEx(context->vcm, "rdpsnd", 0); - - if (rdpsnd->rdpsnd_channel != NULL) - { - rdpsnd->rdpsnd_pdu = Stream_New(NULL, 4096); - - rdpsnd->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - rdpsnd->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_server_thread_func, (void*) rdpsnd, 0, NULL); - - return TRUE; - } - else - { - return FALSE; - } -} - -static void rdpsnd_server_select_format(rdpsnd_server_context* context, int client_format_index) -{ - int bs; - int out_buffer_size; - AUDIO_FORMAT *format; - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - - if (client_format_index < 0 || client_format_index >= context->num_client_formats) - { - fprintf(stderr, "rdpsnd_server_select_format: index %d is not correct.\n", client_format_index); - return; - } - - rdpsnd->src_bytes_per_sample = context->src_format.wBitsPerSample / 8; - rdpsnd->src_bytes_per_frame = rdpsnd->src_bytes_per_sample * context->src_format.nChannels; - - context->selected_client_format = client_format_index; - format = &context->client_formats[client_format_index]; - - if (format->nSamplesPerSec == 0) - { - fprintf(stderr, "Invalid Client Sound Format!!\n\n"); - return; - } - - if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) - { - bs = (format->nBlockAlign - 4 * format->nChannels) * 4; - rdpsnd->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2); - } - else if (format->wFormatTag == WAVE_FORMAT_ADPCM) - { - bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2; - rdpsnd->out_frames = bs * 4; - } - else - { - rdpsnd->out_frames = 0x4000 / rdpsnd->src_bytes_per_frame; - } - - if (format->nSamplesPerSec != context->src_format.nSamplesPerSec) - { - rdpsnd->out_frames = (rdpsnd->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec; - } - rdpsnd->out_pending_frames = 0; - - out_buffer_size = rdpsnd->out_frames * rdpsnd->src_bytes_per_frame; - - if (rdpsnd->out_buffer_size < out_buffer_size) - { - rdpsnd->out_buffer = (BYTE*) realloc(rdpsnd->out_buffer, out_buffer_size); - rdpsnd->out_buffer_size = out_buffer_size; - } - - freerdp_dsp_context_reset_adpcm(rdpsnd->dsp_context); -} - -static BOOL rdpsnd_server_send_audio_pdu(rdpsnd_server* rdpsnd) -{ - int size; - BYTE* src; - int frames; - int fill_size; - BOOL status; - AUDIO_FORMAT* format; - int tbytes_per_frame; - wStream* s = rdpsnd->rdpsnd_pdu; - - format = &rdpsnd->context.client_formats[rdpsnd->context.selected_client_format]; - tbytes_per_frame = format->nChannels * rdpsnd->src_bytes_per_sample; - - if ((format->nSamplesPerSec == rdpsnd->context.src_format.nSamplesPerSec) && - (format->nChannels == rdpsnd->context.src_format.nChannels)) - { - src = rdpsnd->out_buffer; - frames = rdpsnd->out_pending_frames; - } - else - { - rdpsnd->dsp_context->resample(rdpsnd->dsp_context, rdpsnd->out_buffer, rdpsnd->src_bytes_per_sample, - rdpsnd->context.src_format.nChannels, rdpsnd->context.src_format.nSamplesPerSec, rdpsnd->out_pending_frames, - format->nChannels, format->nSamplesPerSec); - frames = rdpsnd->dsp_context->resampled_frames; - src = rdpsnd->dsp_context->resampled_buffer; - } - size = frames * tbytes_per_frame; - - if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) - { - rdpsnd->dsp_context->encode_ima_adpcm(rdpsnd->dsp_context, - src, size, format->nChannels, format->nBlockAlign); - src = rdpsnd->dsp_context->adpcm_buffer; - size = rdpsnd->dsp_context->adpcm_size; - } - else if (format->wFormatTag == WAVE_FORMAT_ADPCM) - { - rdpsnd->dsp_context->encode_ms_adpcm(rdpsnd->dsp_context, - src, size, format->nChannels, format->nBlockAlign); - src = rdpsnd->dsp_context->adpcm_buffer; - size = rdpsnd->dsp_context->adpcm_size; - } - - rdpsnd->context.block_no = (rdpsnd->context.block_no + 1) % 256; - - /* Fill to nBlockAlign for the last audio packet */ - - fill_size = 0; - - if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM || format->wFormatTag == WAVE_FORMAT_ADPCM) && - (rdpsnd->out_pending_frames < rdpsnd->out_frames) && ((size % format->nBlockAlign) != 0)) - { - fill_size = format->nBlockAlign - (size % format->nBlockAlign); - } - - /* WaveInfo PDU */ - Stream_SetPosition(s, 0); - Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */ - Stream_Write_UINT8(s, 0); /* bPad */ - Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */ - - Stream_Write_UINT16(s, 0); /* wTimeStamp */ - Stream_Write_UINT16(s, rdpsnd->context.selected_client_format); /* wFormatNo */ - Stream_Write_UINT8(s, rdpsnd->context.block_no); /* cBlockNo */ - Stream_Seek(s, 3); /* bPad */ - Stream_Write(s, src, 4); - - WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); - Stream_SetPosition(s, 0); - - /* Wave PDU */ - Stream_EnsureRemainingCapacity(s, size + fill_size); - Stream_Write_UINT32(s, 0); /* bPad */ - Stream_Write(s, src + 4, size - 4); - - if (fill_size > 0) - Stream_Zero(s, fill_size); - - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); - Stream_SetPosition(s, 0); - - rdpsnd->out_pending_frames = 0; - - return status; -} - -static BOOL rdpsnd_server_send_samples(rdpsnd_server_context* context, const void* buf, int nframes) -{ - int cframes; - int cframesize; - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - - if (rdpsnd->context.selected_client_format < 0) - return FALSE; - - while (nframes > 0) - { - cframes = MIN(nframes, rdpsnd->out_frames - rdpsnd->out_pending_frames); - cframesize = cframes * rdpsnd->src_bytes_per_frame; - - CopyMemory(rdpsnd->out_buffer + (rdpsnd->out_pending_frames * rdpsnd->src_bytes_per_frame), buf, cframesize); - buf = (BYTE*) buf + cframesize; - nframes -= cframes; - rdpsnd->out_pending_frames += cframes; - - if (rdpsnd->out_pending_frames >= rdpsnd->out_frames) - { - if (!rdpsnd_server_send_audio_pdu(rdpsnd)) - return FALSE; - } - } - - return TRUE; -} - -static BOOL rdpsnd_server_set_volume(rdpsnd_server_context* context, int left, int right) -{ - int pos; - BOOL status; - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - wStream* s = rdpsnd->rdpsnd_pdu; - - Stream_Write_UINT8(s, SNDC_SETVOLUME); - Stream_Write_UINT8(s, 0); - Stream_Seek_UINT16(s); - - Stream_Write_UINT16(s, left); - Stream_Write_UINT16(s, right); - - pos = Stream_GetPosition(s); - Stream_SetPosition(s, 2); - Stream_Write_UINT16(s, pos - 4); - Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); - Stream_SetPosition(s, 0); - - return status; -} - -static BOOL rdpsnd_server_close(rdpsnd_server_context* context) -{ - int pos; - BOOL status; - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - wStream* s = rdpsnd->rdpsnd_pdu; - - if (rdpsnd->context.selected_client_format < 0) - return FALSE; - - if (rdpsnd->out_pending_frames > 0) - { - if (!rdpsnd_server_send_audio_pdu(rdpsnd)) - return FALSE; - } - - rdpsnd->context.selected_client_format = -1; - - Stream_Write_UINT8(s, SNDC_CLOSE); - Stream_Write_UINT8(s, 0); - Stream_Seek_UINT16(s); - - pos = Stream_GetPosition(s); - Stream_SetPosition(s, 2); - Stream_Write_UINT16(s, pos - 4); - Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(rdpsnd->rdpsnd_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); - Stream_SetPosition(s, 0); - - return status; -} - -rdpsnd_server_context* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm) -{ - rdpsnd_server* rdpsnd; - - rdpsnd = (rdpsnd_server*) malloc(sizeof(rdpsnd_server)); - ZeroMemory(rdpsnd, sizeof(rdpsnd_server)); - - rdpsnd->context.vcm = vcm; - rdpsnd->context.selected_client_format = -1; - rdpsnd->context.Initialize = rdpsnd_server_initialize; - rdpsnd->context.SelectFormat = rdpsnd_server_select_format; - rdpsnd->context.SendSamples = rdpsnd_server_send_samples; - rdpsnd->context.SetVolume = rdpsnd_server_set_volume; - rdpsnd->context.Close = rdpsnd_server_close; - - rdpsnd->dsp_context = freerdp_dsp_context_new(); - - return (rdpsnd_server_context*) rdpsnd; -} - -void rdpsnd_server_context_free(rdpsnd_server_context* context) -{ - rdpsnd_server* rdpsnd = (rdpsnd_server*) context; - - SetEvent(rdpsnd->StopEvent); - WaitForSingleObject(rdpsnd->thread, INFINITE); - - if (rdpsnd->rdpsnd_channel) - WTSVirtualChannelClose(rdpsnd->rdpsnd_channel); - - if (rdpsnd->rdpsnd_pdu) - Stream_Free(rdpsnd->rdpsnd_pdu, TRUE); - - if (rdpsnd->out_buffer) - free(rdpsnd->out_buffer); - - if (rdpsnd->dsp_context) - freerdp_dsp_context_free(rdpsnd->dsp_context); - - if (rdpsnd->context.client_formats) - free(rdpsnd->context.client_formats); - - free(rdpsnd); -} diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c new file mode 100644 index 000000000..d56de7fee --- /dev/null +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -0,0 +1,572 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Server Audio Virtual Channel + * + * Copyright 2012 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include + +#include "rdpsnd_main.h" + +static BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) +{ + int pos; + UINT16 i; + BOOL status; + + Stream_Write_UINT8(s, SNDC_FORMATS); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); + + Stream_Write_UINT32(s, 0); /* dwFlags */ + Stream_Write_UINT32(s, 0); /* dwVolume */ + Stream_Write_UINT32(s, 0); /* dwPitch */ + Stream_Write_UINT16(s, 0); /* wDGramPort */ + Stream_Write_UINT16(s, context->num_server_formats); /* wNumberOfFormats */ + Stream_Write_UINT8(s, context->block_no); /* cLastBlockConfirmed */ + Stream_Write_UINT16(s, 0x06); /* wVersion */ + Stream_Write_UINT8(s, 0); /* bPad */ + + for (i = 0; i < context->num_server_formats; i++) + { + Stream_Write_UINT16(s, context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ + Stream_Write_UINT16(s, context->server_formats[i].nChannels); /* nChannels */ + Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ + + Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec * + context->server_formats[i].nChannels * + context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ + + Stream_Write_UINT16(s, context->server_formats[i].nBlockAlign); /* nBlockAlign */ + Stream_Write_UINT16(s, context->server_formats[i].wBitsPerSample); /* wBitsPerSample */ + Stream_Write_UINT16(s, context->server_formats[i].cbSize); /* cbSize */ + + if (context->server_formats[i].cbSize > 0) + { + Stream_Write(s, context->server_formats[i].data, context->server_formats[i].cbSize); + } + } + + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); + + return status; +} + +static void rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream* s) +{ + UINT16 timestamp = 0; + BYTE confirmBlockNum = 0; + Stream_Read_UINT16(s, timestamp); + Stream_Read_UINT8(s, confirmBlockNum); + Stream_Seek_UINT8(s); +} + +static void rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStream* s) +{ + UINT16 quality; + + Stream_Read_UINT16(s, quality); + Stream_Seek_UINT16(s); // reserved + + fprintf(stderr, "Client requested sound quality: %#0X\n", quality); +} + +static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) +{ + int i, num_known_format = 0; + UINT32 flags, vol, pitch; + UINT16 udpPort, version; + BYTE lastblock; + + Stream_Read_UINT32(s, flags); /* dwFlags */ + Stream_Read_UINT32(s, vol); /* dwVolume */ + Stream_Read_UINT32(s, pitch); /* dwPitch */ + Stream_Read_UINT16(s, udpPort); /* wDGramPort */ + Stream_Read_UINT16(s, context->num_client_formats); /* wNumberOfFormats */ + Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */ + Stream_Read_UINT16(s, version); /* wVersion */ + Stream_Seek_UINT8(s); /* bPad */ + + if (context->num_client_formats > 0) + { + context->client_formats = (AUDIO_FORMAT*) malloc(context->num_client_formats * sizeof(AUDIO_FORMAT)); + ZeroMemory(context->client_formats, sizeof(AUDIO_FORMAT)); + + for (i = 0; i < context->num_client_formats; i++) + { + Stream_Read_UINT16(s, context->client_formats[i].wFormatTag); + Stream_Read_UINT16(s, context->client_formats[i].nChannels); + Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec); + Stream_Read_UINT32(s, context->client_formats[i].nAvgBytesPerSec); + Stream_Read_UINT16(s, context->client_formats[i].nBlockAlign); + Stream_Read_UINT16(s, context->client_formats[i].wBitsPerSample); + Stream_Read_UINT16(s, context->client_formats[i].cbSize); + + if (context->client_formats[i].cbSize > 0) + { + Stream_Seek(s, context->client_formats[i].cbSize); + } + + if (context->client_formats[i].wFormatTag != 0) + { + //lets call this a known format + //TODO: actually look through our own list of known formats + num_known_format++; + } + } + } + + if (num_known_format == 0) + { + fprintf(stderr, "Client doesn't support any known formats!\n"); + return FALSE; + } + + return TRUE; +} + +static void* rdpsnd_server_thread(void* arg) +{ + wStream* s; + DWORD status; + DWORD nCount; + void* buffer; + BYTE msgType; + UINT16 BodySize; + HANDLE events[8]; + HANDLE ChannelEvent; + UINT32 BytesReturned; + RdpsndServerContext* context; + + context = (RdpsndServerContext*) arg; + + buffer = NULL; + BytesReturned = 0; + ChannelEvent = NULL; + + s = Stream_New(NULL, 4096); + + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + { + if (BytesReturned == sizeof(HANDLE)) + CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); + + WTSFreeMemory(buffer); + } + + nCount = 0; + events[nCount++] = ChannelEvent; + events[nCount++] = context->priv->StopEvent; + + s = Stream_New(NULL, 4096); + rdpsnd_server_send_formats(context, s); + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + Stream_SetPosition(s, 0); + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + { + if (BytesReturned) + Stream_Seek(s, BytesReturned); + } + else + { + if (!BytesReturned) + break; + + Stream_EnsureRemainingCapacity(s, BytesReturned); + + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, + Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) + { + break; + } + } + + Stream_Read_UINT8(s, msgType); + Stream_Seek_UINT8(s); /* bPad */ + Stream_Read_UINT16(s, BodySize); + + switch (msgType) + { + case SNDC_WAVECONFIRM: + rdpsnd_server_recv_waveconfirm(context, s); + break; + + case SNDC_QUALITYMODE: + rdpsnd_server_recv_quality_mode(context, s); + break; + + case SNDC_FORMATS: + if (rdpsnd_server_recv_formats(context, s)) + { + IFCALL(context->Activated, context); + } + break; + + default: + fprintf(stderr, "UNKOWN MESSAGE TYPE!! (%#0X)\n\n", msgType); + break; + } + } + + Stream_Free(s, TRUE); + + return NULL; +} + +static BOOL rdpsnd_server_initialize(RdpsndServerContext* context) +{ + context->Start(context); + return TRUE; +} + +static void rdpsnd_server_select_format(RdpsndServerContext* context, int client_format_index) +{ + int bs; + int out_buffer_size; + AUDIO_FORMAT *format; + + if (client_format_index < 0 || client_format_index >= context->num_client_formats) + { + fprintf(stderr, "rdpsnd_server_select_format: index %d is not correct.\n", client_format_index); + return; + } + + context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8; + context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->src_format.nChannels; + + context->selected_client_format = client_format_index; + format = &context->client_formats[client_format_index]; + + if (format->nSamplesPerSec == 0) + { + fprintf(stderr, "Invalid Client Sound Format!!\n\n"); + return; + } + + if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) + { + bs = (format->nBlockAlign - 4 * format->nChannels) * 4; + context->priv->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2); + } + else if (format->wFormatTag == WAVE_FORMAT_ADPCM) + { + bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2; + context->priv->out_frames = bs * 4; + } + else + { + context->priv->out_frames = 0x4000 / context->priv->src_bytes_per_frame; + } + + if (format->nSamplesPerSec != context->src_format.nSamplesPerSec) + { + context->priv->out_frames = (context->priv->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec; + } + context->priv->out_pending_frames = 0; + + out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame; + + if (context->priv->out_buffer_size < out_buffer_size) + { + context->priv->out_buffer = (BYTE*) realloc(context->priv->out_buffer, out_buffer_size); + context->priv->out_buffer_size = out_buffer_size; + } + + freerdp_dsp_context_reset_adpcm(context->priv->dsp_context); +} + +static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context) +{ + int size; + BYTE* src; + int frames; + int fill_size; + BOOL status; + AUDIO_FORMAT* format; + int tbytes_per_frame; + wStream* s = context->priv->rdpsnd_pdu; + + format = &context->client_formats[context->selected_client_format]; + tbytes_per_frame = format->nChannels * context->priv->src_bytes_per_sample; + + if ((format->nSamplesPerSec == context->src_format.nSamplesPerSec) && + (format->nChannels == context->src_format.nChannels)) + { + src = context->priv->out_buffer; + frames = context->priv->out_pending_frames; + } + else + { + context->priv->dsp_context->resample(context->priv->dsp_context, context->priv->out_buffer, + context->priv->src_bytes_per_sample, context->src_format.nChannels, + context->src_format.nSamplesPerSec, context->priv->out_pending_frames, + format->nChannels, format->nSamplesPerSec); + frames = context->priv->dsp_context->resampled_frames; + src = context->priv->dsp_context->resampled_buffer; + } + size = frames * tbytes_per_frame; + + if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) + { + context->priv->dsp_context->encode_ima_adpcm(context->priv->dsp_context, + src, size, format->nChannels, format->nBlockAlign); + src = context->priv->dsp_context->adpcm_buffer; + size = context->priv->dsp_context->adpcm_size; + } + else if (format->wFormatTag == WAVE_FORMAT_ADPCM) + { + context->priv->dsp_context->encode_ms_adpcm(context->priv->dsp_context, + src, size, format->nChannels, format->nBlockAlign); + src = context->priv->dsp_context->adpcm_buffer; + size = context->priv->dsp_context->adpcm_size; + } + + context->block_no = (context->block_no + 1) % 256; + + /* Fill to nBlockAlign for the last audio packet */ + + fill_size = 0; + + if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM || format->wFormatTag == WAVE_FORMAT_ADPCM) && + (context->priv->out_pending_frames < context->priv->out_frames) && ((size % format->nBlockAlign) != 0)) + { + fill_size = format->nBlockAlign - (size % format->nBlockAlign); + } + + /* WaveInfo PDU */ + Stream_SetPosition(s, 0); + Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */ + Stream_Write_UINT8(s, 0); /* bPad */ + Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */ + + Stream_Write_UINT16(s, 0); /* wTimeStamp */ + Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */ + Stream_Write_UINT8(s, context->block_no); /* cBlockNo */ + Stream_Seek(s, 3); /* bPad */ + Stream_Write(s, src, 4); + + WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); + + /* Wave PDU */ + Stream_EnsureRemainingCapacity(s, size + fill_size); + Stream_Write_UINT32(s, 0); /* bPad */ + Stream_Write(s, src + 4, size - 4); + + if (fill_size > 0) + Stream_Zero(s, fill_size); + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); + + context->priv->out_pending_frames = 0; + + return status; +} + +static BOOL rdpsnd_server_send_samples(RdpsndServerContext* context, const void* buf, int nframes) +{ + int cframes; + int cframesize; + + if (context->selected_client_format < 0) + return FALSE; + + while (nframes > 0) + { + cframes = MIN(nframes, context->priv->out_frames - context->priv->out_pending_frames); + cframesize = cframes * context->priv->src_bytes_per_frame; + + CopyMemory(context->priv->out_buffer + + (context->priv->out_pending_frames * context->priv->src_bytes_per_frame), buf, cframesize); + buf = (BYTE*) buf + cframesize; + nframes -= cframes; + context->priv->out_pending_frames += cframes; + + if (context->priv->out_pending_frames >= context->priv->out_frames) + { + if (!rdpsnd_server_send_audio_pdu(context)) + return FALSE; + } + } + + return TRUE; +} + +static BOOL rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int right) +{ + int pos; + BOOL status; + wStream* s = context->priv->rdpsnd_pdu; + + Stream_Write_UINT8(s, SNDC_SETVOLUME); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); + + Stream_Write_UINT16(s, left); + Stream_Write_UINT16(s, right); + + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); + + return status; +} + +static BOOL rdpsnd_server_close(RdpsndServerContext* context) +{ + int pos; + BOOL status; + wStream* s = context->priv->rdpsnd_pdu; + + if (context->selected_client_format < 0) + return FALSE; + + if (context->priv->out_pending_frames > 0) + { + if (!rdpsnd_server_send_audio_pdu(context)) + return FALSE; + } + + context->selected_client_format = -1; + + Stream_Write_UINT8(s, SNDC_CLOSE); + Stream_Write_UINT8(s, 0); + Stream_Seek_UINT16(s); + + pos = Stream_GetPosition(s); + Stream_SetPosition(s, 2); + Stream_Write_UINT16(s, pos - 4); + Stream_SetPosition(s, pos); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + Stream_SetPosition(s, 0); + + return status; +} + +static int rdpsnd_server_start(RdpsndServerContext* context) +{ + context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpsnd", 0); + + if (!context->priv->ChannelHandle) + return -1; + + context->priv->rdpsnd_pdu = Stream_New(NULL, 4096); + + context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + context->priv->Thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL); + + return 0; +} + +static int rdpsnd_server_stop(RdpsndServerContext* context) +{ + SetEvent(context->priv->StopEvent); + + WaitForSingleObject(context->priv->Thread, INFINITE); + CloseHandle(context->priv->Thread); + + return 0; +} + +RdpsndServerContext* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm) +{ + RdpsndServerContext* context; + + context = (RdpsndServerContext*) malloc(sizeof(RdpsndServerContext)); + + if (context) + { + ZeroMemory(context, sizeof(RdpsndServerContext)); + + context->vcm = vcm; + + context->Start = rdpsnd_server_start; + context->Stop = rdpsnd_server_stop; + + context->selected_client_format = -1; + context->Initialize = rdpsnd_server_initialize; + context->SelectFormat = rdpsnd_server_select_format; + context->SendSamples = rdpsnd_server_send_samples; + context->SetVolume = rdpsnd_server_set_volume; + context->Close = rdpsnd_server_close; + + context->priv = (RdpsndServerPrivate*) malloc(sizeof(RdpsndServerPrivate)); + + if (context->priv) + { + ZeroMemory(context->priv, sizeof(RdpsndServerPrivate)); + + context->priv->dsp_context = freerdp_dsp_context_new(); + } + } + + return context; +} + +void rdpsnd_server_context_free(RdpsndServerContext* context) +{ + SetEvent(context->priv->StopEvent); + WaitForSingleObject(context->priv->Thread, INFINITE); + + if (context->priv->ChannelHandle) + WTSVirtualChannelClose(context->priv->ChannelHandle); + + if (context->priv->rdpsnd_pdu) + Stream_Free(context->priv->rdpsnd_pdu, TRUE); + + if (context->priv->out_buffer) + free(context->priv->out_buffer); + + if (context->priv->dsp_context) + freerdp_dsp_context_free(context->priv->dsp_context); + + if (context->client_formats) + free(context->client_formats); + + free(context); +} diff --git a/channels/rdpsnd/server/rdpsnd_main.h b/channels/rdpsnd/server/rdpsnd_main.h new file mode 100644 index 000000000..6322cee4a --- /dev/null +++ b/channels/rdpsnd/server/rdpsnd_main.h @@ -0,0 +1,48 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Server Audio Virtual Channel + * + * Copyright 2012 Vic Lee + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_RDPSND_MAIN_H +#define FREERDP_CHANNEL_SERVER_RDPSND_MAIN_H + +#include +#include +#include + +#include +#include +#include + +struct _rdpsnd_server_private +{ + HANDLE Thread; + HANDLE StopEvent; + void* ChannelHandle; + + wStream* rdpsnd_pdu; + BYTE* out_buffer; + int out_buffer_size; + int out_frames; + int out_pending_frames; + UINT32 src_bytes_per_sample; + UINT32 src_bytes_per_frame; + FREERDP_DSP_CONTEXT* dsp_context; +}; + +#endif /* FREERDP_CHANNEL_SERVER_RDPSND_MAIN_H */ diff --git a/channels/server/channels.c b/channels/server/channels.c index 12935146a..a4c9bdc0b 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -44,6 +44,7 @@ #include #include #include +#include void freerdp_channels_dummy() { @@ -58,6 +59,9 @@ void freerdp_channels_dummy() rdpdr_server_context_new(NULL); rdpdr_server_context_free(NULL); + + drdynvc_server_context_new(NULL); + drdynvc_server_context_free(NULL); } /** diff --git a/include/freerdp/server/drdynvc.h b/include/freerdp/server/drdynvc.h new file mode 100644 index 000000000..31eb4ece6 --- /dev/null +++ b/include/freerdp/server/drdynvc.h @@ -0,0 +1,50 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Dynamic Virtual Channel Extension + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SERVER_DRDYNVC_H +#define FREERDP_CHANNEL_SERVER_DRDYNVC_H + +#include +#include +#include + +/** + * Server Interface + */ + +typedef struct _drdynvc_client_context DrdynvcServerContext; +typedef struct _drdynvc_server_private DrdynvcServerPrivate; + +typedef int (*psDrdynvcStart)(DrdynvcServerContext* context); +typedef int (*psDrdynvcStop)(DrdynvcServerContext* context); + +struct _drdynvc_client_context +{ + WTSVirtualChannelManager* vcm; + + psDrdynvcStart Start; + psDrdynvcStop Stop; + + DrdynvcServerPrivate* priv; +}; + +FREERDP_API DrdynvcServerContext* drdynvc_server_context_new(WTSVirtualChannelManager* vcm); +FREERDP_API void drdynvc_server_context_free(DrdynvcServerContext* context); + +#endif /* FREERDP_CHANNEL_SERVER_DRDYNVC_H */ diff --git a/include/freerdp/server/rdpsnd.h b/include/freerdp/server/rdpsnd.h index 8b0c163c2..5b65cd8ff 100644 --- a/include/freerdp/server/rdpsnd.h +++ b/include/freerdp/server/rdpsnd.h @@ -23,20 +23,30 @@ #include #include +typedef struct _rdpsnd_server_context RdpsndServerContext; typedef struct _rdpsnd_server_context rdpsnd_server_context; +typedef struct _rdpsnd_server_private RdpsndServerPrivate; -typedef BOOL (*psRdpsndServerInitialize)(rdpsnd_server_context* context); -typedef void (*psRdpsndServerSelectFormat)(rdpsnd_server_context* context, int client_format_index); -typedef BOOL (*psRdpsndServerSendSamples)(rdpsnd_server_context* context, const void* buf, int nframes); -typedef BOOL (*psRdpsndServerSetVolume)(rdpsnd_server_context* context, int left, int right); -typedef BOOL (*psRdpsndServerClose)(rdpsnd_server_context* context); +typedef int (*psRdpsndStart)(RdpsndServerContext* context); +typedef int (*psRdpsndStop)(RdpsndServerContext* context); -typedef void (*psRdpsndServerActivated)(rdpsnd_server_context* context); +typedef BOOL (*psRdpsndServerInitialize)(RdpsndServerContext* context); +typedef void (*psRdpsndServerSelectFormat)(RdpsndServerContext* context, int client_format_index); +typedef BOOL (*psRdpsndServerSendSamples)(RdpsndServerContext* context, const void* buf, int nframes); +typedef BOOL (*psRdpsndServerSetVolume)(RdpsndServerContext* context, int left, int right); +typedef BOOL (*psRdpsndServerClose)(RdpsndServerContext* context); + +typedef void (*psRdpsndServerActivated)(RdpsndServerContext* context); struct _rdpsnd_server_context { WTSVirtualChannelManager* vcm; + psRdpsndStart Start; + psRdpsndStop Stop; + + RdpsndServerPrivate* priv; + /* Server self-defined pointer. */ void* data; @@ -95,8 +105,8 @@ struct _rdpsnd_server_context extern "C" { #endif -FREERDP_API rdpsnd_server_context* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm); -FREERDP_API void rdpsnd_server_context_free(rdpsnd_server_context* context); +FREERDP_API RdpsndServerContext* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm); +FREERDP_API void rdpsnd_server_context_free(RdpsndServerContext* context); #ifdef __cplusplus } diff --git a/server/Mac/mf_interface.h b/server/Mac/mf_interface.h index cf383ad89..a59951f4f 100644 --- a/server/Mac/mf_interface.h +++ b/server/Mac/mf_interface.h @@ -66,7 +66,7 @@ struct mf_peer_context //#endif //#ifdef CHANNEL_RDPSND_SERVER - rdpsnd_server_context* rdpsnd; + RdpsndServerContext* rdpsnd; //#endif }; diff --git a/server/Mac/mf_rdpsnd.c b/server/Mac/mf_rdpsnd.c index 2e273ded3..0f66f7e3c 100644 --- a/server/Mac/mf_rdpsnd.c +++ b/server/Mac/mf_rdpsnd.c @@ -34,7 +34,7 @@ static const AUDIO_FORMAT supported_audio_formats[] = { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, NULL } }; -static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context) +static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) { OSStatus status; int i, j; diff --git a/server/Mac/mf_rdpsnd.h b/server/Mac/mf_rdpsnd.h index e635be7d7..2c3c6de2d 100644 --- a/server/Mac/mf_rdpsnd.h +++ b/server/Mac/mf_rdpsnd.h @@ -53,7 +53,7 @@ struct _AQRecorderState UInt32 bufferByteSize; SInt64 currentPacket; bool isRunning; - rdpsnd_server_context* snd_context; + RdpsndServerContext* snd_context; }; diff --git a/server/Sample/sf_rdpsnd.c b/server/Sample/sf_rdpsnd.c index 568db3bb5..9a1b70bcb 100644 --- a/server/Sample/sf_rdpsnd.c +++ b/server/Sample/sf_rdpsnd.c @@ -31,7 +31,7 @@ static const AUDIO_FORMAT test_audio_formats[] = { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL } }; -static void sf_peer_rdpsnd_activated(rdpsnd_server_context* context) +static void sf_peer_rdpsnd_activated(RdpsndServerContext* context) { printf("RDPSND Activated\n"); } diff --git a/server/Sample/sfreerdp.h b/server/Sample/sfreerdp.h index b5a05a4cb..b54af158d 100644 --- a/server/Sample/sfreerdp.h +++ b/server/Sample/sfreerdp.h @@ -54,7 +54,7 @@ struct test_peer_context audin_server_context* audin; BOOL audin_open; UINT32 frame_id; - rdpsnd_server_context* rdpsnd; + RdpsndServerContext* rdpsnd; }; typedef struct test_peer_context testPeerContext; diff --git a/server/Windows/wf_directsound.c b/server/Windows/wf_directsound.c index cc0518073..f0ee7cb82 100644 --- a/server/Windows/wf_directsound.c +++ b/server/Windows/wf_directsound.c @@ -26,7 +26,7 @@ int wf_rdpsnd_set_latest_peer(wfPeerContext* peer) return 0; } -int wf_directsound_activate(rdpsnd_server_context* context) +int wf_directsound_activate(RdpsndServerContext* context) { HRESULT hr; wfInfo* wfi; diff --git a/server/Windows/wf_directsound.h b/server/Windows/wf_directsound.h index f88e7dfb0..9e51b27d2 100644 --- a/server/Windows/wf_directsound.h +++ b/server/Windows/wf_directsound.h @@ -6,7 +6,7 @@ int wf_rdpsnd_set_latest_peer(wfPeerContext* peer); -int wf_directsound_activate(rdpsnd_server_context* context); +int wf_directsound_activate(RdpsndServerContext* context); DWORD WINAPI wf_rdpsnd_directsound_thread(LPVOID lpParam); diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 6352c5e2d..4108448b9 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -100,7 +100,7 @@ struct wf_peer_context HANDLE socketSemaphore; WTSVirtualChannelManager* vcm; - rdpsnd_server_context* rdpsnd; + RdpsndServerContext* rdpsnd; }; struct wf_server diff --git a/server/Windows/wf_rdpsnd.c b/server/Windows/wf_rdpsnd.c index 6b6847b7d..0a4362d43 100644 --- a/server/Windows/wf_rdpsnd.c +++ b/server/Windows/wf_rdpsnd.c @@ -46,7 +46,7 @@ static const AUDIO_FORMAT supported_audio_formats[] = { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL } }; -static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context) +static void wf_peer_rdpsnd_activated(RdpsndServerContext* context) { wfInfo* wfi; int i, j; diff --git a/server/Windows/wf_wasapi.c b/server/Windows/wf_wasapi.c index c24d495ea..7530ca76e 100644 --- a/server/Windows/wf_wasapi.c +++ b/server/Windows/wf_wasapi.c @@ -34,7 +34,7 @@ int wf_rdpsnd_set_latest_peer(wfPeerContext* peer) } -int wf_wasapi_activate(rdpsnd_server_context* context) +int wf_wasapi_activate(RdpsndServerContext* context) { wchar_t * pattern = L"Stereo Mix"; diff --git a/server/Windows/wf_wasapi.h b/server/Windows/wf_wasapi.h index 78cd0cbf6..7461f2a0d 100644 --- a/server/Windows/wf_wasapi.h +++ b/server/Windows/wf_wasapi.h @@ -6,7 +6,7 @@ int wf_rdpsnd_set_latest_peer(wfPeerContext* peer); -int wf_wasapi_activate(rdpsnd_server_context* context); +int wf_wasapi_activate(RdpsndServerContext* context); int wf_wasapi_get_device_string(LPWSTR pattern, LPWSTR * deviceStr); From 73c02a76372640bc25b0c9e8c692de18a7b56b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 12:21:40 -0400 Subject: [PATCH 007/202] channels/cliprdr: fix unicode conversion --- channels/cliprdr/server/cliprdr_main.c | 24 +++++++++++++++++++----- channels/rdpdr/server/rdpdr_main.c | 12 ++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 0171209d5..6744748c5 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -249,6 +249,8 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context int length; int position; + printf("%s\n", __FUNCTION__); + position = Stream_GetPosition(s); Stream_SetPosition(s, Stream_Length(s)); end = (WCHAR*) Stream_Pointer(s); @@ -281,17 +283,29 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context { Stream_Read_UINT32(s, context->priv->ClientFormatNames[i].id); /* formatId (4 bytes) */ - context->priv->ClientFormatNames[i].length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), - -1, &context->priv->ClientFormatNames[i].name, 0, NULL, NULL); + length = cliprdr_wcslen((WCHAR*) Stream_Pointer(s), end); - Stream_Seek(s, (context->priv->ClientFormatNames[i].length + 1) * 2); + context->priv->ClientFormatNames[i].name = NULL; + + if (length) + { + context->priv->ClientFormatNames[i].length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), + -1, &(context->priv->ClientFormatNames[i].name), 0, NULL, NULL) - 1; + } + else + { + context->priv->ClientFormatNames[i].length = 0; + } + + Stream_Seek(s, (length + 1) * 2); /* wszFormatName */ } for (i = 0; i < context->priv->ClientFormatNameCount; i++) { - printf("Format %d: Id: 0x%04X Name: %s\n", i, + printf("Format %d: Id: 0x%04X Name: %s Length: %d\n", i, context->priv->ClientFormatNames[i].id, - context->priv->ClientFormatNames[i].name); + context->priv->ClientFormatNames[i].name, + context->priv->ClientFormatNames[i].length); } return 0; diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 77c0cd7d2..c55b6ec1b 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -90,6 +90,12 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context, * not in characters, including the NULL terminator! */ + if (context->priv->ClientComputerName) + { + free(context->priv->ClientComputerName); + context->priv->ClientComputerName = NULL; + } + if (UnicodeFlag) { ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), @@ -579,6 +585,8 @@ static void* rdpdr_server_thread(void* arg) while (1) { + BytesReturned = 0; + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0) @@ -586,8 +594,8 @@ static void* rdpdr_server_thread(void* arg) break; } - if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, Stream_Pointer(s), + Stream_Capacity(s) - Stream_GetPosition(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); From 317ffb2ca33000eb2ace1d4bce66138de669ab30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 17:14:24 -0400 Subject: [PATCH 008/202] libwinpr-utils: backport fixed-size buffer pool inside variable size buffer pool --- winpr/include/winpr/collections.h | 6 +- winpr/libwinpr/utils/collections/BufferPool.c | 298 ++++++++++++------ 2 files changed, 204 insertions(+), 100 deletions(-) diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 2730ffeca..9b00b992d 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -321,11 +321,15 @@ typedef struct _wBufferPoolItem wBufferPoolItem; struct _wBufferPool { - int defaultSize; + int fixedSize; DWORD alignment; BOOL synchronized; CRITICAL_SECTION lock; + int size; + int capacity; + void** array; + int aSize; int aCapacity; wBufferPoolItem* aArray; diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index e5b39114f..4a4cb06b9 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -85,7 +85,16 @@ int BufferPool_GetPoolSize(wBufferPool* pool) if (pool->synchronized) EnterCriticalSection(&pool->lock); - size = pool->uSize; + if (pool->fixedSize) + { + /* fixed size buffers */ + size = pool->size; + } + else + { + /* variable size buffers */ + size = pool->uSize; + } if (pool->synchronized) LeaveCriticalSection(&pool->lock); @@ -106,13 +115,24 @@ int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer) if (pool->synchronized) EnterCriticalSection(&pool->lock); - for (index = 0; index < pool->uSize; index++) + if (pool->fixedSize) { - if (pool->uArray[index].buffer == buffer) + /* fixed size buffers */ + size = pool->fixedSize; + found = TRUE; + } + else + { + /* variable size buffers */ + + for (index = 0; index < pool->uSize; index++) { - size = pool->uArray[index].size; - found = TRUE; - break; + if (pool->uArray[index].buffer == buffer) + { + size = pool->uArray[index].size; + found = TRUE; + break; + } } } @@ -138,65 +158,85 @@ void* BufferPool_Take(wBufferPool* pool, int size) if (pool->synchronized) EnterCriticalSection(&pool->lock); - maxSize = 0; - maxIndex = 0; - - if (size < 1) - size = pool->defaultSize; - - for (index = 0; index < pool->aSize; index++) + if (pool->fixedSize) { - if (pool->aArray[index].size > maxSize) + /* fixed size buffers */ + + if (pool->size > 0) + buffer = pool->array[--(pool->size)]; + + if (!buffer) { - maxIndex = index; - maxSize = pool->aArray[index].size; + if (pool->alignment) + buffer = _aligned_malloc(pool->fixedSize, pool->alignment); + else + buffer = malloc(pool->fixedSize); } - - if (pool->aArray[index].size >= size) - { - foundIndex = index; - found = TRUE; - break; - } - } - - if (!found && maxSize) - { - foundIndex = maxIndex; - found = TRUE; - } - - if (!found) - { - if (pool->alignment) - buffer = _aligned_malloc(size, pool->alignment); - else - buffer = malloc(size); } else { - buffer = pool->aArray[index].buffer; + /* variable size buffers */ - if (maxSize < size) + maxSize = 0; + maxIndex = 0; + + if (size < 1) + size = pool->fixedSize; + + for (index = 0; index < pool->aSize; index++) { - if (pool->alignment) - buffer = _aligned_realloc(buffer, size, pool->alignment); - else - buffer = realloc(buffer, size); + if (pool->aArray[index].size > maxSize) + { + maxIndex = index; + maxSize = pool->aArray[index].size; + } + + if (pool->aArray[index].size >= size) + { + foundIndex = index; + found = TRUE; + break; + } } - BufferPool_ShiftAvailable(pool, foundIndex, -1); - } + if (!found && maxSize) + { + foundIndex = maxIndex; + found = TRUE; + } - if (pool->uSize + 1 > pool->uCapacity) - { - pool->uCapacity *= 2; - pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity); - } + if (!found) + { + if (pool->alignment) + buffer = _aligned_malloc(size, pool->alignment); + else + buffer = malloc(size); + } + else + { + buffer = pool->aArray[index].buffer; - pool->uArray[pool->uSize].buffer = buffer; - pool->uArray[pool->uSize].size = size; - (pool->uSize)++; + if (maxSize < size) + { + if (pool->alignment) + buffer = _aligned_realloc(buffer, size, pool->alignment); + else + buffer = realloc(buffer, size); + } + + BufferPool_ShiftAvailable(pool, foundIndex, -1); + } + + if (pool->uSize + 1 > pool->uCapacity) + { + pool->uCapacity *= 2; + pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity); + } + + pool->uArray[pool->uSize].buffer = buffer; + pool->uArray[pool->uSize].size = size; + (pool->uSize)++; + } if (pool->synchronized) LeaveCriticalSection(&pool->lock); @@ -217,32 +257,49 @@ void BufferPool_Return(wBufferPool* pool, void* buffer) if (pool->synchronized) EnterCriticalSection(&pool->lock); - for (index = 0; index < pool->uSize; index++) + if (pool->fixedSize) { - if (pool->uArray[index].buffer == buffer) - { - found = TRUE; - break; - } - } + /* fixed size buffers */ - if (found) - { - size = pool->uArray[index].size; - BufferPool_ShiftUsed(pool, index, -1); - } - - if (size) - { - if ((pool->aSize + 1) >= pool->aCapacity) + if ((pool->size + 1) >= pool->capacity) { - pool->aCapacity *= 2; - pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity); + pool->capacity *= 2; + pool->array = (void**) realloc(pool->array, sizeof(void*) * pool->capacity); } - pool->aArray[pool->aSize].buffer = buffer; - pool->aArray[pool->aSize].size = size; - (pool->aSize)++; + pool->array[(pool->size)++] = buffer; + } + else + { + /* variable size buffers */ + + for (index = 0; index < pool->uSize; index++) + { + if (pool->uArray[index].buffer == buffer) + { + found = TRUE; + break; + } + } + + if (found) + { + size = pool->uArray[index].size; + BufferPool_ShiftUsed(pool, index, -1); + } + + if (size) + { + if ((pool->aSize + 1) >= pool->aCapacity) + { + pool->aCapacity *= 2; + pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity); + } + + pool->aArray[pool->aSize].buffer = buffer; + pool->aArray[pool->aSize].size = size; + (pool->aSize)++; + } } if (pool->synchronized) @@ -258,24 +315,43 @@ void BufferPool_Clear(wBufferPool* pool) if (pool->synchronized) EnterCriticalSection(&pool->lock); - while (pool->aSize > 0) + if (pool->fixedSize) { - (pool->aSize)--; + /* fixed size buffers */ - if (pool->alignment) - _aligned_free(pool->aArray[pool->aSize].buffer); - else - free(pool->aArray[pool->aSize].buffer); + while (pool->size > 0) + { + (pool->size)--; + + if (pool->alignment) + _aligned_free(pool->array[pool->size]); + else + free(pool->array[pool->size]); + } } - - while (pool->uSize > 0) + else { - (pool->uSize)--; + /* variable size buffers */ - if (pool->alignment) - _aligned_free(pool->uArray[pool->uSize].buffer); - else - free(pool->uArray[pool->uSize].buffer); + while (pool->aSize > 0) + { + (pool->aSize)--; + + if (pool->alignment) + _aligned_free(pool->aArray[pool->aSize].buffer); + else + free(pool->aArray[pool->aSize].buffer); + } + + while (pool->uSize > 0) + { + (pool->uSize)--; + + if (pool->alignment) + _aligned_free(pool->uArray[pool->uSize].buffer); + else + free(pool->uArray[pool->uSize].buffer); + } } if (pool->synchronized) @@ -286,7 +362,7 @@ void BufferPool_Clear(wBufferPool* pool) * Construction, Destruction */ -wBufferPool* BufferPool_New(BOOL synchronized, int defaultSize, DWORD alignment) +wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment) { wBufferPool* pool = NULL; @@ -294,10 +370,10 @@ wBufferPool* BufferPool_New(BOOL synchronized, int defaultSize, DWORD alignment) if (pool) { - pool->defaultSize = defaultSize; + pool->fixedSize = fixedSize; - if (pool->defaultSize < 0) - pool->defaultSize = 0; + if (pool->fixedSize < 0) + pool->fixedSize = 0; pool->alignment = alignment; pool->synchronized = synchronized; @@ -305,13 +381,26 @@ wBufferPool* BufferPool_New(BOOL synchronized, int defaultSize, DWORD alignment) if (pool->synchronized) InitializeCriticalSectionAndSpinCount(&pool->lock, 4000); - pool->aSize = 0; - pool->aCapacity = 32; - pool->aArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->aCapacity); + if (pool->fixedSize) + { + /* fixed size buffers */ - pool->uSize = 0; - pool->uCapacity = 32; - pool->uArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->uCapacity); + pool->size = 0; + pool->capacity = 32; + pool->array = (void**) malloc(sizeof(void*) * pool->capacity); + } + else + { + /* variable size buffers */ + + pool->aSize = 0; + pool->aCapacity = 32; + pool->aArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->aCapacity); + + pool->uSize = 0; + pool->uCapacity = 32; + pool->uArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->uCapacity); + } } return pool; @@ -326,8 +415,19 @@ void BufferPool_Free(wBufferPool* pool) if (pool->synchronized) DeleteCriticalSection(&pool->lock); - free(pool->aArray); - free(pool->uArray); + if (pool->fixedSize) + { + /* fixed size buffers */ + + free(pool->array); + } + else + { + /* variable size buffers */ + + free(pool->aArray); + free(pool->uArray); + } free(pool); } From d7656ada482269598afad4aa0ee77a9774f80b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 18:21:34 -0400 Subject: [PATCH 009/202] libfreerdp-codec: fix NSCodec encoding and buffer pool usage --- include/freerdp/codec/nsc.h | 1 + libfreerdp/codec/nsc_encode.c | 21 ++++++++++--------- winpr/libwinpr/utils/collections/BufferPool.c | 9 ++++++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/freerdp/codec/nsc.h b/include/freerdp/codec/nsc.h index 9601fb8c2..a5832352e 100644 --- a/include/freerdp/codec/nsc.h +++ b/include/freerdp/codec/nsc.h @@ -50,6 +50,7 @@ struct _NSC_MESSAGE UINT32 height; BYTE* data; int scanline; + BYTE* PlaneBuffer; UINT32 MaxPlaneSize; BYTE* PlaneBuffers[5]; UINT32 OrgByteCount[4]; diff --git a/libfreerdp/codec/nsc_encode.c b/libfreerdp/codec/nsc_encode.c index 627d032f4..9f0dc4c04 100644 --- a/libfreerdp/codec/nsc_encode.c +++ b/libfreerdp/codec/nsc_encode.c @@ -390,6 +390,7 @@ NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y, UINT32 MaxPlaneSize; UINT32 MaxMessageSize; NSC_MESSAGE* messages; + UINT32 PaddedMaxPlaneSize; k = 0; MaxRegionWidth = 64 * 4; @@ -430,11 +431,15 @@ NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y, for (i = 0; i < *numMessages; i++) { - messages[i].PlaneBuffers[0] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize); - messages[i].PlaneBuffers[1] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize); - messages[i].PlaneBuffers[2] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize); - messages[i].PlaneBuffers[3] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize); - messages[i].PlaneBuffers[4] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize); + PaddedMaxPlaneSize = messages[i].MaxPlaneSize + 32; + + messages[i].PlaneBuffer = (BYTE*) BufferPool_Take(context->priv->PlanePool, PaddedMaxPlaneSize * 5); + + messages[i].PlaneBuffers[0] = (BYTE*) &(messages[i].PlaneBuffer[(PaddedMaxPlaneSize * 0) + 16]); + messages[i].PlaneBuffers[1] = (BYTE*) &(messages[i].PlaneBuffer[(PaddedMaxPlaneSize * 1) + 16]); + messages[i].PlaneBuffers[2] = (BYTE*) &(messages[i].PlaneBuffer[(PaddedMaxPlaneSize * 2) + 16]); + messages[i].PlaneBuffers[3] = (BYTE*) &(messages[i].PlaneBuffer[(PaddedMaxPlaneSize * 3) + 16]); + messages[i].PlaneBuffers[4] = (BYTE*) &(messages[i].PlaneBuffer[(PaddedMaxPlaneSize * 4) + 16]); } for (i = 0; i < *numMessages; i++) @@ -504,11 +509,7 @@ int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message) int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message) { - BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[0]); - BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[1]); - BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[2]); - BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[3]); - BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[4]); + BufferPool_Return(context->priv->PlanePool, message->PlaneBuffer); return 0; } diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index 4a4cb06b9..7dfae8e32 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -214,14 +214,19 @@ void* BufferPool_Take(wBufferPool* pool, int size) } else { - buffer = pool->aArray[index].buffer; + buffer = pool->aArray[foundIndex].buffer; if (maxSize < size) { if (pool->alignment) - buffer = _aligned_realloc(buffer, size, pool->alignment); + { + _aligned_free(buffer); + buffer = _aligned_malloc(size, pool->alignment); + } else + { buffer = realloc(buffer, size); + } } BufferPool_ShiftAvailable(pool, foundIndex, -1); From f69f4285b1d4b54fd16834aa1cee4da8517c357a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 18:39:19 -0400 Subject: [PATCH 010/202] libfreerdp-codec: use partitioned buffers for RemoteFX encoding/decoding --- include/freerdp/codec/rfx.h | 1 + libfreerdp/codec/rfx.c | 26 ++++++++++++++------------ libfreerdp/codec/rfx_decode.c | 12 ++++++------ libfreerdp/codec/rfx_encode.c | 12 ++++++------ 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index d8fa52c35..645a0d0b3 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -66,6 +66,7 @@ struct _RFX_TILE BYTE* YData; BYTE* CbData; BYTE* CrData; + BYTE* YCbCrData; }; typedef struct _RFX_TILE RFX_TILE; diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index d6e654741..1ed1b59e6 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -242,9 +242,11 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) * in order to allow optimized functions (SEE, NEON) to read from positions * that are actually in front/beyond the buffer. Offset calculations are * performed at the BufferPool_Take function calls in rfx_encode/decode.c. + * + * We then multiply by 3 to use a single, partioned buffer for all 3 channels. */ - context->priv->BufferPool = BufferPool_New(TRUE, 8192 + 32, 16); + context->priv->BufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); #ifdef _WIN32 { @@ -934,14 +936,11 @@ void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) { tile = message->tiles[i]; - if (tile->YData) - BufferPool_Return(context->priv->BufferPool, tile->YData); - - if (tile->CbData) - BufferPool_Return(context->priv->BufferPool, tile->CbData); - - if (tile->CrData) - BufferPool_Return(context->priv->BufferPool, tile->CrData); + if (tile->YCbCrData) + { + BufferPool_Return(context->priv->BufferPool, tile->YCbCrData); + tile->YCbCrData = NULL; + } ObjectPool_Return(context->priv->TilePool, (void*) tile); } @@ -1154,9 +1153,12 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, tile->YLen = 0; tile->CbLen = 0; tile->CrLen = 0; - tile->YData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); - tile->CbData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); - tile->CrData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + + tile->YCbCrData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + + tile->YData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 0) + 16]); + tile->CbData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 1) + 16]); + tile->CrData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 2) + 16]); if (context->priv->UseThreads) { diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index 2a642f9da..d91cfc52f 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -128,6 +128,7 @@ static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantizatio /* stride is bytes between rows in the output buffer. */ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int stride) { + BYTE* pBuffer; INT16* pSrcDst[3]; UINT32 *y_quants, *cb_quants, *cr_quants; static const prim_size_t roi_64x64 = { 64, 64 }; @@ -139,9 +140,10 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int cb_quants = context->quants + (tile->quantIdxCb * 10); cr_quants = context->quants + (tile->quantIdxCr * 10); - pSrcDst[0] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* y_r_buffer */ - pSrcDst[1] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cb_g_buffer */ - pSrcDst[2] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cr_b_buffer */ + pBuffer = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* y_r_buffer */ + pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* cb_g_buffer */ + pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */ rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */ @@ -161,9 +163,7 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int PROFILER_EXIT(context->priv->prof_rfx_decode_rgb); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[0] - 16); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[1] - 16); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[2] - 16); + BufferPool_Return(context->priv->BufferPool, pBuffer); return TRUE; } diff --git a/libfreerdp/codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c index f484e58fd..ab106e291 100644 --- a/libfreerdp/codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -219,6 +219,7 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile) { + BYTE* pBuffer; INT16* pSrcDst[3]; int YLen, CbLen, CrLen; UINT32 *YQuant, *CbQuant, *CrQuant; @@ -230,9 +231,10 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile) CbQuant = context->quants + (tile->quantIdxCb * 10); CrQuant = context->quants + (tile->quantIdxCr * 10); - pSrcDst[0] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* y_r_buffer */ - pSrcDst[1] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cb_g_buffer */ - pSrcDst[2] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cr_b_buffer */ + pBuffer = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* y_r_buffer */ + pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* cb_g_buffer */ + pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */ PROFILER_ENTER(context->priv->prof_rfx_encode_rgb); @@ -265,7 +267,5 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile) PROFILER_EXIT(context->priv->prof_rfx_encode_rgb); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[0] - 16); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[1] - 16); - BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[2] - 16); + BufferPool_Return(context->priv->BufferPool, pBuffer); } From 1068a1f3cc57ed5f3b2936118ae147b000b5cec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 19:06:47 -0400 Subject: [PATCH 011/202] libwinpr-com: create empty module --- winpr/libwinpr/com/CMakeLists.txt | 49 +++++++++ winpr/libwinpr/com/ModuleOptions.cmake | 9 ++ winpr/libwinpr/com/com.c | 115 +++++++++++++++++++++ winpr/libwinpr/com/module.def | 2 + winpr/libwinpr/com/test/.gitignore | 3 + winpr/libwinpr/com/test/CMakeLists.txt | 31 ++++++ winpr/libwinpr/com/test/TestComReference.c | 8 ++ 7 files changed, 217 insertions(+) create mode 100644 winpr/libwinpr/com/CMakeLists.txt create mode 100644 winpr/libwinpr/com/ModuleOptions.cmake create mode 100644 winpr/libwinpr/com/com.c create mode 100644 winpr/libwinpr/com/module.def create mode 100644 winpr/libwinpr/com/test/.gitignore create mode 100644 winpr/libwinpr/com/test/CMakeLists.txt create mode 100644 winpr/libwinpr/com/test/TestComReference.c diff --git a/winpr/libwinpr/com/CMakeLists.txt b/winpr/libwinpr/com/CMakeLists.txt new file mode 100644 index 000000000..826c678f3 --- /dev/null +++ b/winpr/libwinpr/com/CMakeLists.txt @@ -0,0 +1,49 @@ +# WinPR: Windows Portable Runtime +# libwinpr-com cmake build script +# +# Copyright 2013 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-com") +set(MODULE_PREFIX "WINPR_COM") + +set(${MODULE_PREFIX}_SRCS + com.c) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +if(WIN32) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} credui) +endif() + +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/com/ModuleOptions.cmake b/winpr/libwinpr/com/ModuleOptions.cmake new file mode 100644 index 000000000..37c3b962a --- /dev/null +++ b/winpr/libwinpr/com/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "1") +set(MINWIN_GROUP "core") +set(MINWIN_MAJOR_VERSION "1") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "com") +set(MINWIN_LONG_NAME "Component Object Model (COM)") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") + diff --git a/winpr/libwinpr/com/com.c b/winpr/libwinpr/com/com.c new file mode 100644 index 000000000..97332a070 --- /dev/null +++ b/winpr/libwinpr/com/com.c @@ -0,0 +1,115 @@ +/** + * WinPR: Windows Portable Runtime + * Component Object Model (COM) + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/** + * api-ms-win-core-com-l1-1-0.dll: + * + * CLSIDFromProgID + * CLSIDFromString + * CoAddRefServerProcess + * CoAllowUnmarshalerCLSID + * CoCancelCall + * CoCopyProxy + * CoCreateFreeThreadedMarshaler + * CoCreateGuid + * CoCreateInstance + * CoCreateInstanceEx + * CoCreateInstanceFromApp + * CoDecodeProxy + * CoDecrementMTAUsage + * CoDisableCallCancellation + * CoDisconnectContext + * CoDisconnectObject + * CoEnableCallCancellation + * CoFreeUnusedLibraries + * CoFreeUnusedLibrariesEx + * CoGetApartmentType + * CoGetCallContext + * CoGetCallerTID + * CoGetCancelObject + * CoGetClassObject + * CoGetContextToken + * CoGetCurrentLogicalThreadId + * CoGetCurrentProcess + * CoGetDefaultContext + * CoGetInterfaceAndReleaseStream + * CoGetMalloc + * CoGetMarshalSizeMax + * CoGetObjectContext + * CoGetPSClsid + * CoGetStandardMarshal + * CoGetStdMarshalEx + * CoGetTreatAsClass + * CoImpersonateClient + * CoIncrementMTAUsage + * CoInitializeEx + * CoInitializeSecurity + * CoInvalidateRemoteMachineBindings + * CoIsHandlerConnected + * CoLockObjectExternal + * CoMarshalHresult + * CoMarshalInterface + * CoMarshalInterThreadInterfaceInStream + * CoQueryAuthenticationServices + * CoQueryClientBlanket + * CoQueryProxyBlanket + * CoRegisterClassObject + * CoRegisterPSClsid + * CoRegisterSurrogate + * CoReleaseMarshalData + * CoReleaseServerProcess + * CoResumeClassObjects + * CoRevertToSelf + * CoRevokeClassObject + * CoSetCancelObject + * CoSetProxyBlanket + * CoSuspendClassObjects + * CoSwitchCallContext + * CoTaskMemAlloc + * CoTaskMemFree + * CoTaskMemRealloc + * CoTestCancel + * CoUninitialize + * CoUnmarshalHresult + * CoUnmarshalInterface + * CoWaitForMultipleHandles + * CoWaitForMultipleObjects + * CreateStreamOnHGlobal + * FreePropVariantArray + * GetHGlobalFromStream + * IIDFromString + * ProgIDFromCLSID + * PropVariantClear + * PropVariantCopy + * StringFromCLSID + * StringFromGUID2 + * StringFromIID + */ + +#ifndef _WIN32 + + + +#endif diff --git a/winpr/libwinpr/com/module.def b/winpr/libwinpr/com/module.def new file mode 100644 index 000000000..4467b6c7b --- /dev/null +++ b/winpr/libwinpr/com/module.def @@ -0,0 +1,2 @@ +LIBRARY "libwinpr-com" +EXPORTS diff --git a/winpr/libwinpr/com/test/.gitignore b/winpr/libwinpr/com/test/.gitignore new file mode 100644 index 000000000..4a027eed9 --- /dev/null +++ b/winpr/libwinpr/com/test/.gitignore @@ -0,0 +1,3 @@ +TestCom +TestCom.c + diff --git a/winpr/libwinpr/com/test/CMakeLists.txt b/winpr/libwinpr/com/test/CMakeLists.txt new file mode 100644 index 000000000..94e42c352 --- /dev/null +++ b/winpr/libwinpr/com/test/CMakeLists.txt @@ -0,0 +1,31 @@ + +set(MODULE_NAME "TestCom") +set(MODULE_PREFIX "TEST_COM") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestComReference.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-com) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/com/test/TestComReference.c b/winpr/libwinpr/com/test/TestComReference.c new file mode 100644 index 000000000..4b26f3da3 --- /dev/null +++ b/winpr/libwinpr/com/test/TestComReference.c @@ -0,0 +1,8 @@ + +#include + +int TestComReference(int argc, char* argv[]) +{ + return 0; +} + From 0ca78c877e811e021b0dbaffa6d7e8c4d236f4a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 19:18:31 -0400 Subject: [PATCH 012/202] libwinpr-wtsapi: added empty module --- winpr/include/winpr/wtsapi.h | 41 ++++++++++++++++ winpr/libwinpr/wtsapi/CMakeLists.txt | 49 +++++++++++++++++++ winpr/libwinpr/wtsapi/ModuleOptions.cmake | 9 ++++ winpr/libwinpr/wtsapi/module.def | 2 + winpr/libwinpr/wtsapi/test/.gitignore | 3 ++ winpr/libwinpr/wtsapi/test/CMakeLists.txt | 31 ++++++++++++ .../wtsapi/test/TestWtsApiEnumerate.c | 8 +++ winpr/libwinpr/wtsapi/wtsapi.c | 32 ++++++++++++ 8 files changed, 175 insertions(+) create mode 100644 winpr/include/winpr/wtsapi.h create mode 100644 winpr/libwinpr/wtsapi/CMakeLists.txt create mode 100644 winpr/libwinpr/wtsapi/ModuleOptions.cmake create mode 100644 winpr/libwinpr/wtsapi/module.def create mode 100644 winpr/libwinpr/wtsapi/test/.gitignore create mode 100644 winpr/libwinpr/wtsapi/test/CMakeLists.txt create mode 100644 winpr/libwinpr/wtsapi/test/TestWtsApiEnumerate.c create mode 100644 winpr/libwinpr/wtsapi/wtsapi.c diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h new file mode 100644 index 000000000..f225c04ac --- /dev/null +++ b/winpr/include/winpr/wtsapi.h @@ -0,0 +1,41 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Terminal Services API + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_WTSAPI_H +#define WINPR_WTSAPI_H + +#include +#include + +#ifndef _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* WINPR_WTSAPI_H */ + diff --git a/winpr/libwinpr/wtsapi/CMakeLists.txt b/winpr/libwinpr/wtsapi/CMakeLists.txt new file mode 100644 index 000000000..929f7b6e8 --- /dev/null +++ b/winpr/libwinpr/wtsapi/CMakeLists.txt @@ -0,0 +1,49 @@ +# WinPR: Windows Portable Runtime +# libwinpr-wtsapi cmake build script +# +# Copyright 2013 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-wtsapi") +set(MODULE_PREFIX "WINPR_WTSAPI") + +set(${MODULE_PREFIX}_SRCS + wtsapi.c) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +if(WIN32) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} credui) +endif() + +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/wtsapi/ModuleOptions.cmake b/winpr/libwinpr/wtsapi/ModuleOptions.cmake new file mode 100644 index 000000000..0575367f2 --- /dev/null +++ b/winpr/libwinpr/wtsapi/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "0") +set(MINWIN_GROUP "none") +set(MINWIN_MAJOR_VERSION "0") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "wtsapi") +set(MINWIN_LONG_NAME "Windows Terminal Services API") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") + diff --git a/winpr/libwinpr/wtsapi/module.def b/winpr/libwinpr/wtsapi/module.def new file mode 100644 index 000000000..b5adf3c6e --- /dev/null +++ b/winpr/libwinpr/wtsapi/module.def @@ -0,0 +1,2 @@ +LIBRARY "libwinpr-wtsapi" +EXPORTS diff --git a/winpr/libwinpr/wtsapi/test/.gitignore b/winpr/libwinpr/wtsapi/test/.gitignore new file mode 100644 index 000000000..8ac76a2e4 --- /dev/null +++ b/winpr/libwinpr/wtsapi/test/.gitignore @@ -0,0 +1,3 @@ +TestWtsApi +TestWtsApi.c + diff --git a/winpr/libwinpr/wtsapi/test/CMakeLists.txt b/winpr/libwinpr/wtsapi/test/CMakeLists.txt new file mode 100644 index 000000000..fa473d9c2 --- /dev/null +++ b/winpr/libwinpr/wtsapi/test/CMakeLists.txt @@ -0,0 +1,31 @@ + +set(MODULE_NAME "TestWtsApi") +set(MODULE_PREFIX "TEST_WTSAPI") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestWtsApiEnumerate.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-wtsapi) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerate.c b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerate.c new file mode 100644 index 000000000..2f46520b5 --- /dev/null +++ b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerate.c @@ -0,0 +1,8 @@ + +#include + +int TestWtsApiEnumerate(int argc, char* argv[]) +{ + return 0; +} + diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c new file mode 100644 index 000000000..c52fb3c7b --- /dev/null +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -0,0 +1,32 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Terminal Services API + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#ifndef _WIN32 + + + +#endif From 7a88e7cb35a5b99b9c5774fef00c353e0fdf43b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 20:38:43 -0400 Subject: [PATCH 013/202] libwinpr-wtsapi: initial stubs --- winpr/include/winpr/credui.h | 3 - winpr/include/winpr/wtsapi.h | 774 +++++++++++++++++++++++++++++++++ winpr/include/winpr/wtypes.h | 2 + winpr/libwinpr/wtsapi/wtsapi.c | 319 ++++++++++++++ 4 files changed, 1095 insertions(+), 3 deletions(-) diff --git a/winpr/include/winpr/credui.h b/winpr/include/winpr/credui.h index 3fac9f77b..b4277906e 100644 --- a/winpr/include/winpr/credui.h +++ b/winpr/include/winpr/credui.h @@ -67,9 +67,6 @@ #define CREDUIWIN_SECURE_PROMPT 0x00001000 #define CREDUIWIN_PACK_32_WOW 0x10000000 -typedef HANDLE HWND; -typedef HANDLE HBITMAP; - typedef struct _CREDUI_INFOA { DWORD cbSize; diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index f225c04ac..735e5fd50 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -23,12 +23,786 @@ #include #include +#include + #ifndef _WIN32 +#define WTS_CURRENT_SERVER ((HANDLE)NULL) +#define WTS_CURRENT_SERVER_HANDLE ((HANDLE)NULL) +#define WTS_CURRENT_SERVER_NAME (NULL) + +#define WTS_CURRENT_SESSION ((DWORD)-1) + +#define WTS_ANY_SESSION ((DWORD)-2) + +#define IDTIMEOUT 32000 +#define IDASYNC 32001 + +#define USERNAME_LENGTH 20 +#define CLIENTNAME_LENGTH 20 +#define CLIENTADDRESS_LENGTH 30 + +#define WTS_WSD_LOGOFF 0x00000001 +#define WTS_WSD_SHUTDOWN 0x00000002 +#define WTS_WSD_REBOOT 0x00000004 +#define WTS_WSD_POWEROFF 0x00000008 +#define WTS_WSD_FASTREBOOT 0x00000010 + +#define MAX_ELAPSED_TIME_LENGTH 15 +#define MAX_DATE_TIME_LENGTH 56 +#define WINSTATIONNAME_LENGTH 32 +#define DOMAIN_LENGTH 17 + +#define WTS_DRIVE_LENGTH 3 +#define WTS_LISTENER_NAME_LENGTH 32 +#define WTS_COMMENT_LENGTH 60 + +#define WTS_LISTENER_CREATE 0x00000001 +#define WTS_LISTENER_UPDATE 0x00000010 + +#define WTS_SECURITY_QUERY_INFORMATION 0x00000001 +#define WTS_SECURITY_SET_INFORMATION 0x00000002 +#define WTS_SECURITY_RESET 0x00000004 +#define WTS_SECURITY_VIRTUAL_CHANNELS 0x00000008 +#define WTS_SECURITY_REMOTE_CONTROL 0x00000010 +#define WTS_SECURITY_LOGON 0x00000020 +#define WTS_SECURITY_LOGOFF 0x00000040 +#define WTS_SECURITY_MESSAGE 0x00000080 +#define WTS_SECURITY_CONNECT 0x00000100 +#define WTS_SECURITY_DISCONNECT 0x00000200 + +#define WTS_SECURITY_GUEST_ACCESS (WTS_SECURITY_LOGON) + +#define WTS_SECURITY_CURRENT_GUEST_ACCESS (WTS_SECURITY_VIRTUAL_CHANNELS | WTS_SECURITY_LOGOFF) + +#define WTS_SECURITY_USER_ACCESS (WTS_SECURITY_CURRENT_GUEST_ACCESS | WTS_SECURITY_QUERY_INFORMATION | WTS_SECURITY_CONNECT) + +#define WTS_SECURITY_CURRENT_USER_ACCESS (WTS_SECURITY_SET_INFORMATION | WTS_SECURITY_RESET \ + WTS_SECURITY_VIRTUAL_CHANNELS | WTS_SECURITY_LOGOFF \ + WTS_SECURITY_DISCONNECT) + +#define WTS_SECURITY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | WTS_SECURITY_QUERY_INFORMATION | \ + WTS_SECURITY_SET_INFORMATION | WTS_SECURITY_RESET | \ + WTS_SECURITY_VIRTUAL_CHANNELS | WTS_SECURITY_REMOTE_CONTROL | \ + WTS_SECURITY_LOGON | WTS_SECURITY_MESSAGE | \ + WTS_SECURITY_CONNECT | WTS_SECURITY_DISCONNECT) + +typedef enum _WTS_CONNECTSTATE_CLASS +{ + WTSActive, + WTSConnected, + WTSConnectQuery, + WTSShadow, + WTSDisconnected, + WTSIdle, + WTSListen, + WTSReset, + WTSDown, + WTSInit, +} WTS_CONNECTSTATE_CLASS; + +typedef struct _WTS_SERVER_INFOW +{ + LPWSTR pServerName; +} WTS_SERVER_INFOW, *PWTS_SERVER_INFOW; + +typedef struct _WTS_SERVER_INFOA +{ + LPSTR pServerName; +} WTS_SERVER_INFOA, *PWTS_SERVER_INFOA; + +typedef struct _WTS_SESSION_INFOW +{ + DWORD SessionId; + LPWSTR pWinStationName; + WTS_CONNECTSTATE_CLASS State; +} WTS_SESSION_INFOW, *PWTS_SESSION_INFOW; + +typedef struct _WTS_SESSION_INFOA +{ + DWORD SessionId; + LPSTR pWinStationName; + WTS_CONNECTSTATE_CLASS State; +} WTS_SESSION_INFOA, *PWTS_SESSION_INFOA; + +typedef struct _WTS_SESSION_INFO_1W +{ + DWORD ExecEnvId; + WTS_CONNECTSTATE_CLASS State; + DWORD SessionId; + LPWSTR pSessionName; + LPWSTR pHostName; + LPWSTR pUserName; + LPWSTR pDomainName; + LPWSTR pFarmName; +} WTS_SESSION_INFO_1W, *PWTS_SESSION_INFO_1W; + +typedef struct _WTS_SESSION_INFO_1A +{ + DWORD ExecEnvId; + WTS_CONNECTSTATE_CLASS State; + DWORD SessionId; + LPSTR pSessionName; + LPSTR pHostName; + LPSTR pUserName; + LPSTR pDomainName; + LPSTR pFarmName; +} WTS_SESSION_INFO_1A, *PWTS_SESSION_INFO_1A; + +typedef struct _WTS_PROCESS_INFOW +{ + DWORD SessionId; + DWORD ProcessId; + LPWSTR pProcessName; + PSID pUserSid; +} WTS_PROCESS_INFOW, *PWTS_PROCESS_INFOW; + +typedef struct _WTS_PROCESS_INFOA +{ + DWORD SessionId; + DWORD ProcessId; + LPSTR pProcessName; + PSID pUserSid; +} WTS_PROCESS_INFOA, *PWTS_PROCESS_INFOA; + +#define WTS_PROTOCOL_TYPE_CONSOLE 0 +#define WTS_PROTOCOL_TYPE_ICA 1 +#define WTS_PROTOCOL_TYPE_RDP 2 + +typedef enum _WTS_INFO_CLASS +{ + WTSInitialProgram, + WTSApplicationName, + WTSWorkingDirectory, + WTSOEMId, + WTSSessionId, + WTSUserName, + WTSWinStationName, + WTSDomainName, + WTSConnectState, + WTSClientBuildNumber, + WTSClientName, + WTSClientDirectory, + WTSClientProductId, + WTSClientHardwareId, + WTSClientAddress, + WTSClientDisplay, + WTSClientProtocolType, + WTSIdleTime, + WTSLogonTime, + WTSIncomingBytes, + WTSOutgoingBytes, + WTSIncomingFrames, + WTSOutgoingFrames, + WTSClientInfo, + WTSSessionInfo, + WTSSessionInfoEx, + WTSConfigInfo, + WTSValidationInfo, + WTSSessionAddressV4, + WTSIsRemoteSession +} WTS_INFO_CLASS; + +typedef struct _WTSCONFIGINFOW +{ + ULONG version; + ULONG fConnectClientDrivesAtLogon; + ULONG fConnectPrinterAtLogon; + ULONG fDisablePrinterRedirection; + ULONG fDisableDefaultMainClientPrinter; + ULONG ShadowSettings; + WCHAR LogonUserName[USERNAME_LENGTH + 1]; + WCHAR LogonDomain[DOMAIN_LENGTH + 1]; + WCHAR WorkDirectory[MAX_PATH + 1]; + WCHAR InitialProgram[MAX_PATH + 1]; + WCHAR ApplicationName[MAX_PATH + 1]; +} WTSCONFIGINFOW, *PWTSCONFIGINFOW; + +typedef struct _WTSCONFIGINFOA +{ + ULONG version; + ULONG fConnectClientDrivesAtLogon; + ULONG fConnectPrinterAtLogon; + ULONG fDisablePrinterRedirection; + ULONG fDisableDefaultMainClientPrinter; + ULONG ShadowSettings; + CHAR LogonUserName[USERNAME_LENGTH + 1]; + CHAR LogonDomain[DOMAIN_LENGTH + 1]; + CHAR WorkDirectory[MAX_PATH + 1]; + CHAR InitialProgram[MAX_PATH + 1]; + CHAR ApplicationName[MAX_PATH + 1]; +} WTSCONFIGINFOA, *PWTSCONFIGINFOA; + +typedef struct _WTSINFOW +{ + WTS_CONNECTSTATE_CLASS State; + DWORD SessionId; + DWORD IncomingBytes; + DWORD OutgoingBytes; + DWORD IncomingFrames; + DWORD OutgoingFrames; + DWORD IncomingCompressedBytes; + DWORD OutgoingCompressedBytes; + WCHAR WinStationName[WINSTATIONNAME_LENGTH]; + WCHAR Domain[DOMAIN_LENGTH]; + WCHAR UserName[USERNAME_LENGTH+1]; + LARGE_INTEGER ConnectTime; + LARGE_INTEGER DisconnectTime; + LARGE_INTEGER LastInputTime; + LARGE_INTEGER LogonTime; + LARGE_INTEGER CurrentTime; +} WTSINFOW, *PWTSINFOW; + +typedef struct _WTSINFOA +{ + WTS_CONNECTSTATE_CLASS State; + DWORD SessionId; + DWORD IncomingBytes; + DWORD OutgoingBytes; + DWORD IncomingFrames; + DWORD OutgoingFrames; + DWORD IncomingCompressedBytes; + DWORD OutgoingCompressedBy; + CHAR WinStationName[WINSTATIONNAME_LENGTH]; + CHAR Domain[DOMAIN_LENGTH]; + CHAR UserName[USERNAME_LENGTH+1]; + LARGE_INTEGER ConnectTime; + LARGE_INTEGER DisconnectTime; + LARGE_INTEGER LastInputTime; + LARGE_INTEGER LogonTime; + LARGE_INTEGER CurrentTime; +} WTSINFOA, *PWTSINFOA; + +#define WTS_SESSIONSTATE_UNKNOWN 0xFFFFFFFF +#define WTS_SESSIONSTATE_LOCK 0x00000000 +#define WTS_SESSIONSTATE_UNLOCK 0x00000001 + +typedef struct _WTSINFOEX_LEVEL1_W +{ + ULONG SessionId; + WTS_CONNECTSTATE_CLASS SessionState; + LONG SessionFlags; + WCHAR WinStationName[WINSTATIONNAME_LENGTH + 1]; + WCHAR UserName[USERNAME_LENGTH + 1]; + WCHAR DomainName[DOMAIN_LENGTH + 1]; + LARGE_INTEGER LogonTime; + LARGE_INTEGER ConnectTime; + LARGE_INTEGER DisconnectTime; + LARGE_INTEGER LastInputTime; + LARGE_INTEGER CurrentTime; + DWORD IncomingBytes; + DWORD OutgoingBytes; + DWORD IncomingFrames; + DWORD OutgoingFrames; + DWORD IncomingCompressedBytes; + DWORD OutgoingCompressedBytes; +} WTSINFOEX_LEVEL1_W, *PWTSINFOEX_LEVEL1_W; + +typedef struct _WTSINFOEX_LEVEL1_A +{ + ULONG SessionId; + WTS_CONNECTSTATE_CLASS SessionState; + LONG SessionFlags; + CHAR WinStationName[WINSTATIONNAME_LENGTH + 1]; + CHAR UserName[USERNAME_LENGTH + 1]; + CHAR DomainName[DOMAIN_LENGTH + 1]; + LARGE_INTEGER LogonTime; + LARGE_INTEGER ConnectTime; + LARGE_INTEGER DisconnectTime; + LARGE_INTEGER LastInputTime; + LARGE_INTEGER CurrentTime; + DWORD IncomingBytes; + DWORD OutgoingBytes; + DWORD IncomingFrames; + DWORD OutgoingFrames; + DWORD IncomingCompressedBytes; + DWORD OutgoingCompressedBytes; +} WTSINFOEX_LEVEL1_A, *PWTSINFOEX_LEVEL1_A; + +typedef union _WTSINFOEX_LEVEL_W +{ + WTSINFOEX_LEVEL1_W WTSInfoExLevel1; +} WTSINFOEX_LEVEL_W, *PWTSINFOEX_LEVEL_W; + +typedef union _WTSINFOEX_LEVEL_A +{ + WTSINFOEX_LEVEL1_A WTSInfoExLevel1; +} WTSINFOEX_LEVEL_A, *PWTSINFOEX_LEVEL_A; + +typedef struct _WTSINFOEXW +{ + DWORD Level; + WTSINFOEX_LEVEL_W Data; +} WTSINFOEXW, *PWTSINFOEXW; + +typedef struct _WTSINFOEXA +{ + DWORD Level; + WTSINFOEX_LEVEL_A Data; +} WTSINFOEXA, *PWTSINFOEXA; + +typedef struct _WTSCLIENTW +{ + WCHAR ClientName[CLIENTNAME_LENGTH + 1]; + WCHAR Domain[DOMAIN_LENGTH + 1]; + WCHAR UserName[USERNAME_LENGTH + 1]; + WCHAR WorkDirectory[MAX_PATH + 1]; + WCHAR InitialProgram[MAX_PATH + 1]; + BYTE EncryptionLevel; + ULONG ClientAddressFamily; + USHORT ClientAddress[CLIENTADDRESS_LENGTH + 1]; + USHORT HRes; + USHORT VRes; + USHORT ColorDepth; + WCHAR ClientDirectory[MAX_PATH + 1]; + ULONG ClientBuildNumber; + ULONG ClientHardwareId; + USHORT ClientProductId; + USHORT OutBufCountHost; + USHORT OutBufCountClient; + USHORT OutBufLength; + WCHAR DeviceId[MAX_PATH + 1]; +} WTSCLIENTW, *PWTSCLIENTW; + +typedef struct _WTSCLIENTA +{ + CHAR ClientName[CLIENTNAME_LENGTH + 1]; + CHAR Domain[DOMAIN_LENGTH + 1]; + CHAR UserName[USERNAME_LENGTH + 1]; + CHAR WorkDirectory[MAX_PATH + 1]; + CHAR InitialProgram[MAX_PATH + 1]; + BYTE EncryptionLevel; + ULONG ClientAddressFamily; + USHORT ClientAddress[CLIENTADDRESS_LENGTH + 1]; + USHORT HRes; + USHORT VRes; + USHORT ColorDepth; + CHAR ClientDirectory[MAX_PATH + 1]; + ULONG ClientBuildNumber; + ULONG ClientHardwareId; + USHORT ClientProductId; + USHORT OutBufCountHost; + USHORT OutBufCountClient; + USHORT OutBufLength; + CHAR DeviceId[MAX_PATH + 1]; +} WTSCLIENTA, *PWTSCLIENTA; + +#define PRODUCTINFO_COMPANYNAME_LENGTH 256 +#define PRODUCTINFO_PRODUCTID_LENGTH 4 + +typedef struct _WTS_PRODUCT_INFOA +{ + CHAR CompanyName[PRODUCTINFO_COMPANYNAME_LENGTH]; + CHAR ProductID[PRODUCTINFO_PRODUCTID_LENGTH]; +} PRODUCT_INFOA; + +typedef struct _WTS_PRODUCT_INFOW +{ + WCHAR CompanyName[PRODUCTINFO_COMPANYNAME_LENGTH]; + WCHAR ProductID[PRODUCTINFO_PRODUCTID_LENGTH]; +} PRODUCT_INFOW; + +#define VALIDATIONINFORMATION_LICENSE_LENGTH 16384 +#define VALIDATIONINFORMATION_HARDWAREID_LENGTH 20 + +typedef struct _WTS_VALIDATION_INFORMATIONA +{ + PRODUCT_INFOA ProductInfo; + BYTE License[VALIDATIONINFORMATION_LICENSE_LENGTH]; + DWORD LicenseLength; + BYTE HardwareID[VALIDATIONINFORMATION_HARDWAREID_LENGTH]; + DWORD HardwareIDLength; +} WTS_VALIDATION_INFORMATIONA, *PWTS_VALIDATION_INFORMATIONA; + +typedef struct _WTS_VALIDATION_INFORMATIONW +{ + PRODUCT_INFOW ProductInfo; + BYTE License[VALIDATIONINFORMATION_LICENSE_LENGTH]; + DWORD LicenseLength; + BYTE HardwareID[VALIDATIONINFORMATION_HARDWAREID_LENGTH]; + DWORD HardwareIDLength; +} WTS_VALIDATION_INFORMATIONW, *PWTS_VALIDATION_INFORMATIONW; + +typedef struct _WTS_CLIENT_ADDRESS +{ + DWORD AddressFamily; + BYTE Address[20]; +} WTS_CLIENT_ADDRESS, *PWTS_CLIENT_ADDRESS; + +typedef struct _WTS_CLIENT_DISPLAY +{ + DWORD HorizontalResolution; + DWORD VerticalResolution; + DWORD ColorDepth; +} WTS_CLIENT_DISPLAY, *PWTS_CLIENT_DISPLAY; + +typedef enum _WTS_CONFIG_CLASS +{ + WTSUserConfigInitialProgram, + WTSUserConfigWorkingDirectory, + WTSUserConfigfInheritInitialProgram, + WTSUserConfigfAllowLogonTerminalServer, + WTSUserConfigTimeoutSettingsConnections, + WTSUserConfigTimeoutSettingsDisconnections, + WTSUserConfigTimeoutSettingsIdle, + WTSUserConfigfDeviceClientDrives, + WTSUserConfigfDeviceClientPrinters, + WTSUserConfigfDeviceClientDefaultPrinter, + WTSUserConfigBrokenTimeoutSettings, + WTSUserConfigReconnectSettings, + WTSUserConfigModemCallbackSettings, + WTSUserConfigModemCallbackPhoneNumber, + WTSUserConfigShadowingSettings, + WTSUserConfigTerminalServerProfilePath, + WTSUserConfigTerminalServerHomeDir, + WTSUserConfigTerminalServerHomeDirDrive, + WTSUserConfigfTerminalServerRemoteHomeDir, + WTSUserConfigUser, +} WTS_CONFIG_CLASS; + +typedef enum _WTS_CONFIG_SOURCE +{ + WTSUserConfigSourceSAM +} WTS_CONFIG_SOURCE; + +typedef struct _WTSUSERCONFIGA +{ + DWORD Source; + DWORD InheritInitialProgram; + DWORD AllowLogonTerminalServer; + DWORD TimeoutSettingsConnections; + DWORD TimeoutSettingsDisconnections; + DWORD TimeoutSettingsIdle; + DWORD DeviceClientDrives; + DWORD DeviceClientPrinters; + DWORD ClientDefaultPrinter; + DWORD BrokenTimeoutSettings; + DWORD ReconnectSettings; + DWORD ShadowingSettings; + DWORD TerminalServerRemoteHomeDir; + CHAR InitialProgram[MAX_PATH + 1]; + CHAR WorkDirectory[MAX_PATH + 1]; + CHAR TerminalServerProfilePath[MAX_PATH + 1]; + CHAR TerminalServerHomeDir[MAX_PATH + 1]; + CHAR TerminalServerHomeDirDrive[WTS_DRIVE_LENGTH + 1]; +} WTSUSERCONFIGA, *PWTSUSERCONFIGA; + +typedef struct _WTSUSERCONFIGW +{ + DWORD Source; + DWORD InheritInitialProgram; + DWORD AllowLogonTerminalServer; + DWORD TimeoutSettingsConnections; + DWORD TimeoutSettingsDisconnections; + DWORD TimeoutSettingsIdle; + DWORD DeviceClientDrives; + DWORD DeviceClientPrinters; + DWORD ClientDefaultPrinter; + DWORD BrokenTimeoutSettings; + DWORD ReconnectSettings; + DWORD ShadowingSettings; + DWORD TerminalServerRemoteHomeDir; + WCHAR InitialProgram[MAX_PATH + 1]; + WCHAR WorkDirectory[MAX_PATH + 1]; + WCHAR TerminalServerProfilePath[MAX_PATH + 1]; + WCHAR TerminalServerHomeDir[MAX_PATH + 1]; + WCHAR TerminalServerHomeDirDrive[WTS_DRIVE_LENGTH + 1]; +} WTSUSERCONFIGW, *PWTSUSERCONFIGW; + +#define WTS_EVENT_NONE 0x00000000 +#define WTS_EVENT_CREATE 0x00000001 +#define WTS_EVENT_DELETE 0x00000002 +#define WTS_EVENT_RENAME 0x00000004 +#define WTS_EVENT_CONNECT 0x00000008 +#define WTS_EVENT_DISCONNECT 0x00000010 +#define WTS_EVENT_LOGON 0x00000020 +#define WTS_EVENT_LOGOFF 0x00000040 +#define WTS_EVENT_STATECHANGE 0x00000080 +#define WTS_EVENT_LICENSE 0x00000100 +#define WTS_EVENT_ALL 0x7fffffff +#define WTS_EVENT_FLUSH 0x80000000 + +#define REMOTECONTROL_KBDSHIFT_HOTKEY 0x1 +#define REMOTECONTROL_KBDCTRL_HOTKEY 0x2 +#define REMOTECONTROL_KBDALT_HOTKEY 0x4 + +typedef enum _WTS_VIRTUAL_CLASS +{ + WTSVirtualClientData, + WTSVirtualFileHandle +} WTS_VIRTUAL_CLASS; + +typedef struct _WTS_SESSION_ADDRESS +{ + DWORD AddressFamily; + BYTE Address[20]; +} WTS_SESSION_ADDRESS, *PWTS_SESSION_ADDRESS; + +#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006 +#define WTS_CHANNEL_OPTION_DYNAMIC_NO_COMPRESS 0x00000008 + +#define NOTIFY_FOR_ALL_SESSIONS 1 +#define NOTIFY_FOR_THIS_SESSION 0 + +#define WTS_PROCESS_INFO_LEVEL_0 0 +#define WTS_PROCESS_INFO_LEVEL_1 1 + +typedef struct _WTS_PROCESS_INFO_EXW +{ + DWORD SessionId; + DWORD ProcessId; + LPWSTR pProcessName; + PSID pUserSid; + DWORD NumberOfThreads; + DWORD HandleCount; + DWORD PagefileUsage; + DWORD PeakPagefileUsage; + DWORD WorkingSetSize; + DWORD PeakWorkingSetSize; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; +} WTS_PROCESS_INFO_EXW, *PWTS_PROCESS_INFO_EXW; + +typedef struct _WTS_PROCESS_INFO_EXA +{ + DWORD SessionId; + DWORD ProcessId; + LPSTR pProcessName; + PSID pUserSid; + DWORD NumberOfThreads; + DWORD HandleCount; + DWORD PagefileUsage; + DWORD PeakPagefileUsage; + DWORD WorkingSetSize; + DWORD PeakWorkingSetSize; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; +} WTS_PROCESS_INFO_EXA, *PWTS_PROCESS_INFO_EXA; + +typedef enum _WTS_TYPE_CLASS +{ + WTSTypeProcessInfoLevel0, + WTSTypeProcessInfoLevel1, + WTSTypeSessionInfoLevel1, +} WTS_TYPE_CLASS; + +typedef WCHAR WTSLISTENERNAMEW[WTS_LISTENER_NAME_LENGTH + 1]; +typedef WTSLISTENERNAMEW *PWTSLISTENERNAMEW; +typedef CHAR WTSLISTENERNAMEA[WTS_LISTENER_NAME_LENGTH + 1]; +typedef WTSLISTENERNAMEA *PWTSLISTENERNAMEA; + +typedef struct _WTSLISTENERCONFIGW +{ + ULONG version; + ULONG fEnableListener; + ULONG MaxConnectionCount; + ULONG fPromptForPassword; + ULONG fInheritColorDepth; + ULONG ColorDepth; + ULONG fInheritBrokenTimeoutSettings; + ULONG BrokenTimeoutSettings; + ULONG fDisablePrinterRedirection; + ULONG fDisableDriveRedirection; + ULONG fDisableComPortRedirection; + ULONG fDisableLPTPortRedirection; + ULONG fDisableClipboardRedirection; + ULONG fDisableAudioRedirection; + ULONG fDisablePNPRedirection; + ULONG fDisableDefaultMainClientPrinter; + ULONG LanAdapter; + ULONG PortNumber; + ULONG fInheritShadowSettings; + ULONG ShadowSettings; + ULONG TimeoutSettingsConnection; + ULONG TimeoutSettingsDisconnection; + ULONG TimeoutSettingsIdle; + ULONG SecurityLayer; + ULONG MinEncryptionLevel; + ULONG UserAuthentication; + WCHAR Comment[WTS_COMMENT_LENGTH + 1]; + WCHAR LogonUserName[USERNAME_LENGTH + 1]; + WCHAR LogonDomain[DOMAIN_LENGTH + 1]; + WCHAR WorkDirectory[MAX_PATH + 1]; + WCHAR InitialProgram[MAX_PATH + 1]; +} WTSLISTENERCONFIGW, *PWTSLISTENERCONFIGW; + +typedef struct _WTSLISTENERCONFIGA +{ + ULONG version; + ULONG fEnableListener; + ULONG MaxConnectionCount; + ULONG fPromptForPassword; + ULONG fInheritColorDepth; + ULONG ColorDepth; + ULONG fInheritBrokenTimeoutSettings; + ULONG BrokenTimeoutSettings; + ULONG fDisablePrinterRedirection; + ULONG fDisableDriveRedirection; + ULONG fDisableComPortRedirection; + ULONG fDisableLPTPortRedirection; + ULONG fDisableClipboardRedirection; + ULONG fDisableAudioRedirection; + ULONG fDisablePNPRedirection; + ULONG fDisableDefaultMainClientPrinter; + ULONG LanAdapter; + ULONG PortNumber; + ULONG fInheritShadowSettings; + ULONG ShadowSettings; + ULONG TimeoutSettingsConnection; + ULONG TimeoutSettingsDisconnection; + ULONG TimeoutSettingsIdle; + ULONG SecurityLayer; + ULONG MinEncryptionLevel; + ULONG UserAuthentication; + CHAR Comment[WTS_COMMENT_LENGTH + 1]; + CHAR LogonUserName[USERNAME_LENGTH + 1]; + CHAR LogonDomain[DOMAIN_LENGTH + 1]; + CHAR WorkDirectory[MAX_PATH + 1]; + CHAR InitialProgram[MAX_PATH + 1]; +} WTSLISTENERCONFIGA, *PWTSLISTENERCONFIGA; + #ifdef __cplusplus extern "C" { #endif +BOOL WTSStopRemoteControlSession(ULONG LogonId); + +BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); + +BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); + +BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait); + +BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait); + +BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount); + +BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount); + +HANDLE WTSOpenServerW(LPWSTR pServerName); + +HANDLE WTSOpenServerA(LPSTR pServerName); + +HANDLE WTSOpenServerExW(LPWSTR pServerName); + +HANDLE WTSOpenServerExA(LPSTR pServerName); + +VOID WTSCloseServer(HANDLE hServer); + +BOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount); + +BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount); + +BOOL WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount); + +BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount); + +BOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount); + +BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount); + +BOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode); + +BOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); + +BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned); + +BOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); + +BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned); + +BOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength); + +BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength); + +BOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, + LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait); + +BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, + LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait); + +BOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait); + +BOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait); + +BOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag); + +BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags); + +HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName); + +HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags); + +BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); + +BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead); + +BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten); + +BOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle); + +BOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle); + +BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned); + +VOID WTSFreeMemory(PVOID pMemory); + +BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags); + +BOOL WTSUnRegisterSessionNotification(HWND hWnd); + +BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags); + +BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd); + +BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken); + +BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); + +BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); + +BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount); + +BOOL WTSEnumerateProcessesExA(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPSTR* ppProcessInfo, DWORD* pCount); + +BOOL WTSEnumerateListenersW(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEW pListeners, DWORD* pCount); + +BOOL WTSEnumerateListenersA(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEA pListeners, DWORD* pCount); + +BOOL WTSQueryListenerConfigW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer); + +BOOL WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer); + +BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag); + +BOOL WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer, DWORD flag); + +BOOL WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor); + +BOOL WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor); + +BOOL WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded); + +BOOL WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded); + +BOOL WTSEnableChildSessions(BOOL bEnable); + +BOOL WTSIsChildSessionsEnabled(PBOOL pbEnabled); + +BOOL WTSGetChildSessionId(PULONG pSessionId); #ifdef __cplusplus diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index c05e1b86c..26c717e6a 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -83,6 +83,8 @@ typedef short SHORT; typedef void* HANDLE, *PHANDLE, *LPHANDLE; typedef HANDLE HINSTANCE; typedef HANDLE HMODULE; +typedef HANDLE HWND; +typedef HANDLE HBITMAP; typedef DWORD HCALL; typedef int INT, *LPINT; diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index c52fb3c7b..01d141c1b 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -27,6 +27,325 @@ #ifndef _WIN32 +BOOL WTSStopRemoteControlSession(ULONG LogonId) +{ + return TRUE; +} +BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) +{ + return TRUE; +} + +BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) +{ + return TRUE; +} + +BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount) +{ + return TRUE; +} + +HANDLE WTSOpenServerW(LPWSTR pServerName) +{ + return NULL; +} + +HANDLE WTSOpenServerA(LPSTR pServerName) +{ + return NULL; +} + +HANDLE WTSOpenServerExW(LPWSTR pServerName) +{ + return NULL; +} + +HANDLE WTSOpenServerExA(LPSTR pServerName) +{ + return NULL; +} + +VOID WTSCloseServer(HANDLE hServer) +{ + +} + +BOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode) +{ + return TRUE; +} + +BOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength) +{ + return TRUE; +} + +BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength) +{ + return TRUE; +} + +BOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, + LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, + LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait) +{ + return TRUE; +} + +BOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag) +{ + return TRUE; +} + +BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags) +{ + return TRUE; +} + +HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName) +{ + return NULL; +} + +HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags) +{ + return NULL; +} + +BOOL WTSVirtualChannelClose(HANDLE hChannelHandle) +{ + return TRUE; +} + +BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead) +{ + return TRUE; +} + +BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten) +{ + return TRUE; +} + +BOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle) +{ + return TRUE; +} + +BOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle) +{ + return TRUE; +} + +BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +VOID WTSFreeMemory(PVOID pMemory) +{ + +} + +BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) +{ + return TRUE; +} + +BOOL WTSUnRegisterSessionNotification(HWND hWnd) +{ + return TRUE; +} + +BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags) +{ + return TRUE; +} + +BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd) +{ + return TRUE; +} + +BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken) +{ + return TRUE; +} + +BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries) +{ + return TRUE; +} + +BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries) +{ + return TRUE; +} + +BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateProcessesExA(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPSTR* ppProcessInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateListenersW(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEW pListeners, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSEnumerateListenersA(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEA pListeners, DWORD* pCount) +{ + return TRUE; +} + +BOOL WTSQueryListenerConfigW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer) +{ + return TRUE; +} + +BOOL WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer) +{ + return TRUE; +} + +BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag) +{ + return TRUE; +} + +BOOL WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer, DWORD flag) +{ + return TRUE; +} + +BOOL WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor) +{ + return TRUE; +} + +BOOL WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor) +{ + return TRUE; +} + +BOOL WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded) +{ + return TRUE; +} + +BOOL WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded) +{ + return TRUE; +} + +BOOL WTSEnableChildSessions(BOOL bEnable) +{ + return TRUE; +} + +BOOL WTSIsChildSessionsEnabled(PBOOL pbEnabled) +{ + return TRUE; +} + +BOOL WTSGetChildSessionId(PULONG pSessionId) +{ + return TRUE; +} #endif From 9d1dd1458115200a1ad0ac83df96f6773d1a05a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 19 Aug 2013 20:58:42 -0400 Subject: [PATCH 014/202] libwinpr-wtsapi: updated interface definition --- winpr/include/winpr/wtsapi.h | 215 ++++++++++++++++++++------------- winpr/libwinpr/wtsapi/wtsapi.c | 3 +- 2 files changed, 135 insertions(+), 83 deletions(-) diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index 735e5fd50..6100b82ea 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -665,150 +665,201 @@ typedef struct _WTSLISTENERCONFIGA CHAR InitialProgram[MAX_PATH + 1]; } WTSLISTENERCONFIGA, *PWTSLISTENERCONFIGA; +#ifdef UNICODE +#define WTS_SERVER_INFO WTS_SERVER_INFOW +#define PWTS_SERVER_INFO PWTS_SERVER_INFOW +#define WTS_SESSION_INFO WTS_SESSION_INFOW +#define PWTS_SESSION_INFO PWTS_SESSION_INFOW +#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1W +#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1W +#define WTS_PROCESS_INFO WTS_PROCESS_INFOW +#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOW +#define WTSCONFIGINFO WTSCONFIGINFOW +#define PWTSCONFIGINFO PWTSCONFIGINFOW +#define WTSINFO WTSINFOW +#define PWTSINFO PWTSINFOW +#else +#define WTS_SERVER_INFO WTS_SERVER_INFOA +#define PWTS_SERVER_INFO PWTS_SERVER_INFOA +#define WTS_SESSION_INFO WTS_SESSION_INFOA +#define PWTS_SESSION_INFO PWTS_SESSION_INFOA +#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1A +#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1A +#define WTS_PROCESS_INFO WTS_PROCESS_INFOA +#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOA +#define WTSCONFIGINFO WTSCONFIGINFOA +#define PWTSCONFIGINFO PWTSCONFIGINFOA +#define WTSINFO WTSINFOA +#define PWTSINFO PWTSINFOA +#endif + #ifdef __cplusplus extern "C" { #endif -BOOL WTSStopRemoteControlSession(ULONG LogonId); +WINPR_API BOOL WTSStopRemoteControlSession(ULONG LogonId); -BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); +WINPR_API BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); +WINPR_API BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); -BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); +WINPR_API BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait); +WINPR_API BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait); -BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait); +WINPR_API BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount); -BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait); +WINPR_API HANDLE WTSOpenServerW(LPWSTR pServerName); +WINPR_API HANDLE WTSOpenServerA(LPSTR pServerName); -BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount); +WINPR_API HANDLE WTSOpenServerExW(LPWSTR pServerName); +WINPR_API HANDLE WTSOpenServerExA(LPSTR pServerName); -BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount); +WINPR_API VOID WTSCloseServer(HANDLE hServer); -HANDLE WTSOpenServerW(LPWSTR pServerName); +WINPR_API BOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount); -HANDLE WTSOpenServerA(LPSTR pServerName); +WINPR_API BOOL WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount); -HANDLE WTSOpenServerExW(LPWSTR pServerName); +WINPR_API BOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount); -HANDLE WTSOpenServerExA(LPSTR pServerName); +WINPR_API BOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode); -VOID WTSCloseServer(HANDLE hServer); +WINPR_API BOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); +WINPR_API BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned); -BOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount); +WINPR_API BOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); +WINPR_API BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned); -BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount); +WINPR_API BOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength); +WINPR_API BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength); -BOOL WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount); - -BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount); - -BOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount); - -BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount); - -BOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode); - -BOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); - -BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned); - -BOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); - -BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned); - -BOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength); - -BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength); - -BOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, +WINPR_API BOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait); - -BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, +WINPR_API BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, LPSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait); -BOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait); +WINPR_API BOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait); -BOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait); +WINPR_API BOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait); -BOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag); +WINPR_API BOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag); -BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags); +WINPR_API BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags); -HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName); +WINPR_API HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName); -HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags); +WINPR_API HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags); -BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); +WINPR_API BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); -BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead); +WINPR_API BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead); -BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten); +WINPR_API BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten); -BOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle); +WINPR_API BOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle); -BOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle); +WINPR_API BOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle); -BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned); +WINPR_API BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned); -VOID WTSFreeMemory(PVOID pMemory); +WINPR_API VOID WTSFreeMemory(PVOID pMemory); -BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags); +WINPR_API BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags); -BOOL WTSUnRegisterSessionNotification(HWND hWnd); +WINPR_API BOOL WTSUnRegisterSessionNotification(HWND hWnd); -BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags); +WINPR_API BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags); -BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd); +WINPR_API BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd); -BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken); +WINPR_API BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken); -BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); +WINPR_API BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); +WINPR_API BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); -BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries); +WINPR_API BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateProcessesExA(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPSTR* ppProcessInfo, DWORD* pCount); -BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount); +WINPR_API BOOL WTSEnumerateListenersW(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEW pListeners, DWORD* pCount); +WINPR_API BOOL WTSEnumerateListenersA(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEA pListeners, DWORD* pCount); -BOOL WTSEnumerateProcessesExA(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPSTR* ppProcessInfo, DWORD* pCount); +WINPR_API BOOL WTSQueryListenerConfigW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer); +WINPR_API BOOL WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer); -BOOL WTSEnumerateListenersW(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEW pListeners, DWORD* pCount); - -BOOL WTSEnumerateListenersA(HANDLE hServer, PVOID pReserved, DWORD Reserved, PWTSLISTENERNAMEA pListeners, DWORD* pCount); - -BOOL WTSQueryListenerConfigW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer); - -BOOL WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer); - -BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag); - -BOOL WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved, +WINPR_API BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag); +WINPR_API BOOL WTSCreateListenerA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, PWTSLISTENERCONFIGA pBuffer, DWORD flag); -BOOL WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, +WINPR_API BOOL WTSSetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor); - -BOOL WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, +WINPR_API BOOL WTSSetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor); -BOOL WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, +WINPR_API BOOL WTSGetListenerSecurityW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded); - -BOOL WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, +WINPR_API BOOL WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPSTR pListenerName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded); -BOOL WTSEnableChildSessions(BOOL bEnable); +WINPR_API BOOL WTSEnableChildSessions(BOOL bEnable); -BOOL WTSIsChildSessionsEnabled(PBOOL pbEnabled); - -BOOL WTSGetChildSessionId(PULONG pSessionId); +WINPR_API BOOL WTSIsChildSessionsEnabled(PBOOL pbEnabled); +WINPR_API BOOL WTSGetChildSessionId(PULONG pSessionId); #ifdef __cplusplus } #endif +#ifdef UNICODE +#define WTSStartRemoteControlSession WTSStartRemoteControlSessionW +#define WTSConnectSession WTSConnectSessionW +#define WTSEnumerateServers WTSEnumerateServersW +#define WTSOpenServer WTSOpenServerW +#define WTSOpenServerEx WTSOpenServerExW +#define WTSEnumerateSessions WTSEnumerateSessionsW +#define WTSEnumerateSessionsEx WTSEnumerateSessionsExW +#define WTSEnumerateProcesses WTSEnumerateProcessesW +#define WTSQuerySessionInformation WTSQuerySessionInformationW +#define WTSQueryUserConfig WTSQueryUserConfigW +#define WTSSetUserConfig WTSSetUserConfigW +#define WTSSendMessage WTSSendMessageW +#define WTSFreeMemoryEx WTSFreeMemoryExW +#define WTSEnumerateProcessesEx WTSEnumerateProcessesExW +#define WTSEnumerateListeners WTSEnumerateListenersW +#define WTSQueryListenerConfig WTSQueryListenerConfigW +#define WTSCreateListener WTSCreateListenerW +#define WTSSetListenerSecurity WTSSetListenerSecurityW +#define WTSGetListenerSecurity WTSGetListenerSecurityW +#else +#define WTSStartRemoteControlSession WTSStartRemoteControlSessionA +#define WTSConnectSession WTSConnectSessionA +#define WTSEnumerateServers WTSEnumerateServersA +#define WTSOpenServer WTSOpenServerA +#define WTSOpenServerEx WTSOpenServerExA +#define WTSEnumerateSessions WTSEnumerateSessionsA +#define WTSEnumerateSessionsEx WTSEnumerateSessionsExA +#define WTSEnumerateProcesses WTSEnumerateProcessesA +#define WTSQuerySessionInformation WTSQuerySessionInformationA +#define WTSQueryUserConfig WTSQueryUserConfigA +#define WTSSetUserConfig WTSSetUserConfigA +#define WTSSendMessage WTSSendMessageA +#define WTSFreeMemoryEx WTSFreeMemoryExA +#define WTSEnumerateProcessesEx WTSEnumerateProcessesExA +#define WTSEnumerateListeners WTSEnumerateListenersA +#define WTSQueryListenerConfig WTSQueryListenerConfigA +#define WTSCreateListener WTSCreateListenerA +#define WTSSetListenerSecurity WTSSetListenerSecurityA +#define WTSGetListenerSecurity WTSGetListenerSecurityA +#endif + #endif #endif /* WINPR_WTSAPI_H */ diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 01d141c1b..43f86cb57 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -294,7 +294,8 @@ BOOL WTSQueryListenerConfigA(HANDLE hServer, PVOID pReserved, DWORD Reserved, LP return TRUE; } -BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag) +BOOL WTSCreateListenerW(HANDLE hServer, PVOID pReserved, DWORD Reserved, + LPWSTR pListenerName, PWTSLISTENERCONFIGW pBuffer, DWORD flag) { return TRUE; } From 1f0caa41610df22c5c55a07f9dbc6ebd24b8af39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 20 Aug 2013 14:22:42 -0400 Subject: [PATCH 015/202] libwinpr-wtsapi: complete unicode definitions --- winpr/include/winpr/wtsapi.h | 86 ++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index 6100b82ea..951bdd84c 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -666,31 +666,69 @@ typedef struct _WTSLISTENERCONFIGA } WTSLISTENERCONFIGA, *PWTSLISTENERCONFIGA; #ifdef UNICODE -#define WTS_SERVER_INFO WTS_SERVER_INFOW -#define PWTS_SERVER_INFO PWTS_SERVER_INFOW -#define WTS_SESSION_INFO WTS_SESSION_INFOW -#define PWTS_SESSION_INFO PWTS_SESSION_INFOW -#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1W -#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1W -#define WTS_PROCESS_INFO WTS_PROCESS_INFOW -#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOW -#define WTSCONFIGINFO WTSCONFIGINFOW -#define PWTSCONFIGINFO PWTSCONFIGINFOW -#define WTSINFO WTSINFOW -#define PWTSINFO PWTSINFOW +#define WTS_SERVER_INFO WTS_SERVER_INFOW +#define PWTS_SERVER_INFO PWTS_SERVER_INFOW +#define WTS_SESSION_INFO WTS_SESSION_INFOW +#define PWTS_SESSION_INFO PWTS_SESSION_INFOW +#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1W +#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1W +#define WTS_PROCESS_INFO WTS_PROCESS_INFOW +#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOW +#define WTSCONFIGINFO WTSCONFIGINFOW +#define PWTSCONFIGINFO PWTSCONFIGINFOW +#define WTSINFO WTSINFOW +#define PWTSINFO PWTSINFOW +#define WTSINFOEX WTSINFOEXW +#define PWTSINFOEX PWTSINFOEXW +#define WTSINFOEX_LEVEL WTSINFOEX_LEVEL_W +#define PWTSINFOEX_LEVEL PWTSINFOEX_LEVEL_W +#define WTSINFOEX_LEVEL1 WTSINFOEX_LEVEL1_W +#define PWTSINFOEX_LEVEL1 PWTSINFOEX_LEVEL1_W +#define WTSCLIENT WTSCLIENTW +#define PWTSCLIENT PWTSCLIENTW +#define PRODUCT_INFO PRODUCT_INFOW +#define WTS_VALIDATION_INFORMATION WTS_VALIDATION_INFORMATIONW +#define PWTS_VALIDATION_INFORMATION PWTS_VALIDATION_INFORMATIONW +#define WTSUSERCONFIG WTSUSERCONFIGW +#define PWTSUSERCONFIG PWTSUSERCONFIGW +#define WTS_PROCESS_INFO_EX WTS_PROCESS_INFO_EXW +#define PWTS_PROCESS_INFO_EX PWTS_PROCESS_INFO_EXW +#define WTSLISTENERNAME WTSLISTENERNAMEW +#define PWTSLISTENERNAME PWTSLISTENERNAMEW +#define WTSLISTENERCONFIG WTSLISTENERCONFIGW +#define PWTSLISTENERCONFIG PWTSLISTENERCONFIGW #else -#define WTS_SERVER_INFO WTS_SERVER_INFOA -#define PWTS_SERVER_INFO PWTS_SERVER_INFOA -#define WTS_SESSION_INFO WTS_SESSION_INFOA -#define PWTS_SESSION_INFO PWTS_SESSION_INFOA -#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1A -#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1A -#define WTS_PROCESS_INFO WTS_PROCESS_INFOA -#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOA -#define WTSCONFIGINFO WTSCONFIGINFOA -#define PWTSCONFIGINFO PWTSCONFIGINFOA -#define WTSINFO WTSINFOA -#define PWTSINFO PWTSINFOA +#define WTS_SERVER_INFO WTS_SERVER_INFOA +#define PWTS_SERVER_INFO PWTS_SERVER_INFOA +#define WTS_SESSION_INFO WTS_SESSION_INFOA +#define PWTS_SESSION_INFO PWTS_SESSION_INFOA +#define WTS_SESSION_INFO_1 WTS_SESSION_INFO_1A +#define PWTS_SESSION_INFO_1 PWTS_SESSION_INFO_1A +#define WTS_PROCESS_INFO WTS_PROCESS_INFOA +#define PWTS_PROCESS_INFO PWTS_PROCESS_INFOA +#define WTSCONFIGINFO WTSCONFIGINFOA +#define PWTSCONFIGINFO PWTSCONFIGINFOA +#define WTSINFO WTSINFOA +#define PWTSINFO PWTSINFOA +#define WTSINFOEX WTSINFOEXA +#define PWTSINFOEX PWTSINFOEXA +#define WTSINFOEX_LEVEL WTSINFOEX_LEVEL_A +#define PWTSINFOEX_LEVEL PWTSINFOEX_LEVEL_A +#define WTSINFOEX_LEVEL1 WTSINFOEX_LEVEL1_A +#define PWTSINFOEX_LEVEL1 PWTSINFOEX_LEVEL1_A +#define WTSCLIENT WTSCLIENTA +#define PWTSCLIENT PWTSCLIENTA +#define PRODUCT_INFO PRODUCT_INFOA +#define WTS_VALIDATION_INFORMATION WTS_VALIDATION_INFORMATIONA +#define PWTS_VALIDATION_INFORMATION PWTS_VALIDATION_INFORMATIONA +#define WTSUSERCONFIG WTSUSERCONFIGA +#define PWTSUSERCONFIG PWTSUSERCONFIGA +#define WTS_PROCESS_INFO_EX WTS_PROCESS_INFO_EXA +#define PWTS_PROCESS_INFO_EX PWTS_PROCESS_INFO_EXA +#define WTSLISTENERNAME WTSLISTENERNAMEA +#define PWTSLISTENERNAME PWTSLISTENERNAMEA +#define WTSLISTENERCONFIG WTSLISTENERCONFIGA +#define PWTSLISTENERCONFIG PWTSLISTENERCONFIGA #endif #ifdef __cplusplus From cea6de16eed3e5a0faf962fd0f14c76eeea10122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 20 Aug 2013 15:22:31 -0400 Subject: [PATCH 016/202] libwinpr-wtsapi: add VC API --- winpr/include/winpr/wtsapi.h | 188 +++++++++++++++++++++++++++++++++ winpr/include/winpr/wtypes.h | 3 + winpr/libwinpr/wtsapi/wtsapi.c | 5 + 3 files changed, 196 insertions(+) diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index 951bdd84c..d675255c3 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -27,6 +27,194 @@ #ifndef _WIN32 +/** + * Virtual Channel Protocol (Common) + */ + +#define CHANNEL_CHUNK_LENGTH 1600 + +#define CHANNEL_PDU_LENGTH (CHANNEL_CHUNK_LENGTH + sizeof(CHANNEL_PDU_HEADER)) + +#define CHANNEL_FLAG_FIRST 0x01 +#define CHANNEL_FLAG_LAST 0x02 +#define CHANNEL_FLAG_ONLY (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST) +#define CHANNEL_FLAG_MIDDLE 0 +#define CHANNEL_FLAG_FAIL 0x100 + +#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10 +#define CHANNEL_FLAG_SUSPEND 0x20 +#define CHANNEL_FLAG_RESUME 0x40 +#define CHANNEL_FLAG_SHADOW_PERSISTENT 0x80 + +#define CHANNEL_OPTION_INITIALIZED 0x80000000 + +#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000 +#define CHANNEL_OPTION_ENCRYPT_SC 0x20000000 +#define CHANNEL_OPTION_ENCRYPT_CS 0x10000000 +#define CHANNEL_OPTION_PRI_HIGH 0x08000000 +#define CHANNEL_OPTION_PRI_MED 0x04000000 +#define CHANNEL_OPTION_PRI_LOW 0x02000000 +#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000 +#define CHANNEL_OPTION_COMPRESS 0x00400000 +#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000 +#define CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT 0x00100000 + +#define CHANNEL_MAX_COUNT 30 +#define CHANNEL_NAME_LEN 7 + +typedef struct tagCHANNEL_DEF +{ + char name[CHANNEL_NAME_LEN + 1]; + ULONG options; +} CHANNEL_DEF; +typedef CHANNEL_DEF *PCHANNEL_DEF; +typedef PCHANNEL_DEF *PPCHANNEL_DEF; + +typedef struct tagCHANNEL_PDU_HEADER +{ + UINT32 length; + UINT32 flags; +} CHANNEL_PDU_HEADER, *PCHANNEL_PDU_HEADER; + +/** + * Virtual Channel Client API + */ + +#ifdef _WIN32 +#define VCAPITYPE __stdcall +#define VCEXPORT +#else +#define VCAPITYPE CALLBACK +#define VCEXPORT __export +#endif + +typedef VOID VCAPITYPE CHANNEL_INIT_EVENT_FN(LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength); + +typedef CHANNEL_INIT_EVENT_FN *PCHANNEL_INIT_EVENT_FN; + +typedef VOID VCAPITYPE CHANNEL_INIT_EVENT_EX_FN(LPVOID lpUserParam, + LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength); + +typedef CHANNEL_INIT_EVENT_EX_FN *PCHANNEL_INIT_EVENT_EX_FN; + +#define CHANNEL_EVENT_INITIALIZED 0 +#define CHANNEL_EVENT_CONNECTED 1 +#define CHANNEL_EVENT_V1_CONNECTED 2 +#define CHANNEL_EVENT_DISCONNECTED 3 +#define CHANNEL_EVENT_TERMINATED 4 +#define CHANNEL_EVENT_REMOTE_CONTROL_START 5 +#define CHANNEL_EVENT_REMOTE_CONTROL_STOP 6 +#define CHANNEL_EVENT_DATA_RECEIVED 10 +#define CHANNEL_EVENT_WRITE_COMPLETE 11 +#define CHANNEL_EVENT_WRITE_CANCELLED 12 + +typedef VOID VCAPITYPE CHANNEL_OPEN_EVENT_FN(DWORD openHandle, UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags); + +typedef CHANNEL_OPEN_EVENT_FN *PCHANNEL_OPEN_EVENT_FN; + +typedef VOID VCAPITYPE CHANNEL_OPEN_EVENT_EX_FN(LPVOID lpUserParam, DWORD openHandle, UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags); + +typedef CHANNEL_OPEN_EVENT_EX_FN *PCHANNEL_OPEN_EVENT_EX_FN; + +#define CHANNEL_RC_OK 0 +#define CHANNEL_RC_ALREADY_INITIALIZED 1 +#define CHANNEL_RC_NOT_INITIALIZED 2 +#define CHANNEL_RC_ALREADY_CONNECTED 3 +#define CHANNEL_RC_NOT_CONNECTED 4 +#define CHANNEL_RC_TOO_MANY_CHANNELS 5 +#define CHANNEL_RC_BAD_CHANNEL 6 +#define CHANNEL_RC_BAD_CHANNEL_HANDLE 7 +#define CHANNEL_RC_NO_BUFFER 8 +#define CHANNEL_RC_BAD_INIT_HANDLE 9 +#define CHANNEL_RC_NOT_OPEN 10 +#define CHANNEL_RC_BAD_PROC 11 +#define CHANNEL_RC_NO_MEMORY 12 +#define CHANNEL_RC_UNKNOWN_CHANNEL_NAME 13 +#define CHANNEL_RC_ALREADY_OPEN 14 +#define CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY 15 +#define CHANNEL_RC_NULL_DATA 16 +#define CHANNEL_RC_ZERO_LENGTH 17 +#define CHANNEL_RC_INVALID_INSTANCE 18 +#define CHANNEL_RC_UNSUPPORTED_VERSION 19 +#define CHANNEL_RC_INITIALIZATION_ERROR 20 + +#define VIRTUAL_CHANNEL_VERSION_WIN2000 1 + +typedef UINT VCAPITYPE VIRTUALCHANNELINIT(LPVOID* ppInitHandle, PCHANNEL_DEF pChannel, + INT channelCount, ULONG versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc); + +typedef VIRTUALCHANNELINIT *PVIRTUALCHANNELINIT; + +typedef UINT VCAPITYPE VIRTUALCHANNELINITEX(LPVOID lpUserParam, LPVOID pInitHandle, PCHANNEL_DEF pChannel, + INT channelCount, ULONG versionRequested, PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx); + +typedef VIRTUALCHANNELINITEX *PVIRTUALCHANNELINITEX; + +typedef UINT VCAPITYPE VIRTUALCHANNELOPEN(LPVOID pInitHandle, LPDWORD pOpenHandle, + PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc); + +typedef VIRTUALCHANNELOPEN *PVIRTUALCHANNELOPEN; + +typedef UINT VCAPITYPE VIRTUALCHANNELOPENEX(LPVOID pInitHandle, LPDWORD pOpenHandle, + PCHAR pChannelName, PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx); + +typedef VIRTUALCHANNELOPENEX *PVIRTUALCHANNELOPENEX; + +typedef UINT VCAPITYPE VIRTUALCHANNELCLOSE(DWORD openHandle); + +typedef VIRTUALCHANNELCLOSE *PVIRTUALCHANNELCLOSE; + +typedef UINT VCAPITYPE VIRTUALCHANNELCLOSEEX(LPVOID pInitHandle, DWORD openHandle); + +typedef VIRTUALCHANNELCLOSEEX *PVIRTUALCHANNELCLOSEEX; + +typedef UINT VCAPITYPE VIRTUALCHANNELWRITE(DWORD openHandle, + LPVOID pData, ULONG dataLength, LPVOID pUserData); + +typedef VIRTUALCHANNELWRITE *PVIRTUALCHANNELWRITE; + +typedef UINT VCAPITYPE VIRTUALCHANNELWRITEEX(LPVOID pInitHandle, DWORD openHandle, + LPVOID pData, ULONG dataLength, LPVOID pUserData); + +typedef VIRTUALCHANNELWRITEEX *PVIRTUALCHANNELWRITEEX; + +typedef struct tagCHANNEL_ENTRY_POINTS +{ + DWORD cbSize; + DWORD protocolVersion; + PVIRTUALCHANNELINIT pVirtualChannelInit; + PVIRTUALCHANNELOPEN pVirtualChannelOpen; + PVIRTUALCHANNELCLOSE pVirtualChannelClose; + PVIRTUALCHANNELWRITE pVirtualChannelWrite; +} CHANNEL_ENTRY_POINTS, *PCHANNEL_ENTRY_POINTS; + +typedef struct tagCHANNEL_ENTRY_POINTS_EX +{ + DWORD cbSize; + DWORD protocolVersion; + PVIRTUALCHANNELINITEX pVirtualChannelInitEx; + PVIRTUALCHANNELOPENEX pVirtualChannelOpenEx; + PVIRTUALCHANNELCLOSEEX pVirtualChannelCloseEx; + PVIRTUALCHANNELWRITEEX pVirtualChannelWriteEx; +} CHANNEL_ENTRY_POINTS_EX, *PCHANNEL_ENTRY_POINTS_EX; + +typedef BOOL VCAPITYPE VIRTUALCHANNELENTRY(PCHANNEL_ENTRY_POINTS pEntryPoints); + +typedef VIRTUALCHANNELENTRY *PVIRTUALCHANNELENTRY; + +typedef BOOL VCAPITYPE VIRTUALCHANNELENTRYEX(PCHANNEL_ENTRY_POINTS_EX pEntryPointsEx, PVOID pInitHandle); + +typedef VIRTUALCHANNELENTRYEX *PVIRTUALCHANNELENTRYEX; + +typedef HRESULT (VCAPITYPE *PFNVCAPIGETINSTANCE)(REFIID refiid, PULONG pNumObjs, PVOID* ppObjArray); + +/** + * Windows Terminal Services API (WtsApi) + */ + #define WTS_CURRENT_SERVER ((HANDLE)NULL) #define WTS_CURRENT_SERVER_HANDLE ((HANDLE)NULL) #define WTS_CURRENT_SERVER_NAME (NULL) diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index 26c717e6a..aeaa33661 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -160,6 +160,9 @@ typedef struct _LUID LONG HighPart; } LUID, *PLUID; +typedef GUID IID; +typedef IID* REFIID; + #ifdef UNICODE #define _T(x) L ## x #else diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 43f86cb57..94f9e35ff 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -25,6 +25,11 @@ #include +/** + * Remote Desktop Services API Functions: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464/ + */ + #ifndef _WIN32 BOOL WTSStopRemoteControlSession(ULONG LogonId) From 3a9a41d900069be63dbb74e5281e432e7682c32c Mon Sep 17 00:00:00 2001 From: Todd McKinney Date: Tue, 20 Aug 2013 15:21:25 -0500 Subject: [PATCH 017/202] Add Fit Screen option to resolution settings There may be times where users want to have the desktop resolution match the device resolution on a small screen. The change adds the option without changing existing functionality of the automatic resolution setting. Also included localized text strings for the new option and addressed some issues with string comparison in non en-US locales. --- .../FreeRDPCore/res/values-es/strings.xml | 3 +++ .../FreeRDPCore/res/values-fr/strings.xml | 3 +++ .../FreeRDPCore/res/values-nl/strings.xml | 3 +++ .../FreeRDPCore/res/values/strings.xml | 3 +++ .../application/GlobalSettings.java | 2 ++ .../freerdpcore/domain/BookmarkBase.java | 26 ++++++++++++++----- .../presentation/BookmarkActivity.java | 2 +- .../presentation/SessionActivity.java | 4 +++ 8 files changed, 39 insertions(+), 7 deletions(-) diff --git a/client/Android/FreeRDPCore/res/values-es/strings.xml b/client/Android/FreeRDPCore/res/values-es/strings.xml index cf9b933a9..620823ca6 100644 --- a/client/Android/FreeRDPCore/res/values-es/strings.xml +++ b/client/Android/FreeRDPCore/res/values-es/strings.xml @@ -64,9 +64,11 @@ Resolucion Automatico + Pantalla Manual Automatico + Ajuste a la pantalla Manual 640x480 720x480 @@ -79,6 +81,7 @@ automatico + pantalla manual 640x480 720x480 diff --git a/client/Android/FreeRDPCore/res/values-fr/strings.xml b/client/Android/FreeRDPCore/res/values-fr/strings.xml index 3e0f1711f..7c1ff6d14 100644 --- a/client/Android/FreeRDPCore/res/values-fr/strings.xml +++ b/client/Android/FreeRDPCore/res/values-fr/strings.xml @@ -63,9 +63,11 @@ "Résolution" "Automatique" + "Agrandir la fenêtre" "Personalisé" "Automatique" + "Agrandir la fenêtre" "Personalisé" "640x480" "720x480" @@ -78,6 +80,7 @@ "Automatique" + "fenêtre" "Personalisé" "640x480" "720x480" diff --git a/client/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml index 4bff58d5f..0ddc53697 100644 --- a/client/Android/FreeRDPCore/res/values-nl/strings.xml +++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml @@ -64,9 +64,11 @@ Resolutie Automatisch + Schermvullend Aangepast Automatisch + Schermvullend Aangepast 640x480 720x480 @@ -79,6 +81,7 @@ Automatisch + Schermvullend Aangepast 640x480 720x480 diff --git a/client/Android/FreeRDPCore/res/values/strings.xml b/client/Android/FreeRDPCore/res/values/strings.xml index 6110afd5d..0f6aacded 100644 --- a/client/Android/FreeRDPCore/res/values/strings.xml +++ b/client/Android/FreeRDPCore/res/values/strings.xml @@ -64,9 +64,11 @@ Resolution Automatic + Fitscreen Custom Automatic + Fit Screen Custom 640x480 720x480 @@ -79,6 +81,7 @@ automatic + fitscreen custom 640x480 720x480 diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java index 5b876dd94..e44a3e750 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java @@ -27,9 +27,11 @@ public class GlobalSettings { private static final String PREF_SECURITY_ACCEPTALLCERTIFICATES = "security.accept_certificates"; private static SharedPreferences settings; + public static Context initialContext; public static void init(Context context) { + initialContext = context; settings = PreferenceManager.getDefaultSharedPreferences(context); initValues(); } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java index 981386b6d..7c7c36389 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java @@ -10,6 +10,8 @@ package com.freerdp.freerdpcore.domain; import com.freerdp.freerdpcore.application.GlobalApp; +import com.freerdp.freerdpcore.application.GlobalSettings; +import com.freerdp.freerdpcore.R; import android.content.SharedPreferences; import android.os.Parcel; @@ -143,6 +145,7 @@ public class BookmarkBase implements Parcelable, Cloneable // Screen Settings class public static class ScreenSettings implements Parcelable { + public static final int FITSCREEN = -2; public static final int AUTOMATIC = -1; public static final int CUSTOM = 0; public static final int PREDEFINED = 1; @@ -174,7 +177,7 @@ public class BookmarkBase implements Parcelable, Cloneable { this.resolution = resolution; - if (resolution == AUTOMATIC) { + if (resolution == AUTOMATIC || resolution == FITSCREEN) { width = 0; height = 0; } @@ -188,15 +191,20 @@ public class BookmarkBase implements Parcelable, Cloneable this.height = Integer.valueOf(dimensions[1]); this.resolution = PREDEFINED; } - else if (resolution.equalsIgnoreCase("custom")) + else if (resolution.equalsIgnoreCase(GlobalSettings.initialContext.getResources().getString(R.string.resolution_custom))) { this.width = width; this.height = height; this.resolution = CUSTOM; } + else if (resolution.equalsIgnoreCase(GlobalSettings.initialContext.getResources().getString(R.string.resolution_fit))) + { + this.width = this.height = 0; + this.resolution = FITSCREEN; + } else { - this.width = this.height = 0; + this.width = this.height = 0; this.resolution = AUTOMATIC; } } @@ -210,8 +218,10 @@ public class BookmarkBase implements Parcelable, Cloneable { if (isPredefined()) return (width + "x" + height); - - return (isAutomatic() ? "automatic" : "custom"); + + return (isFitScreen() ? GlobalSettings.initialContext.getResources().getString(R.string.resolution_fit) : + isAutomatic() ? GlobalSettings.initialContext.getResources().getString(R.string.resolution_automatic) : + GlobalSettings.initialContext.getResources().getString(R.string.resolution_custom)); } public boolean isPredefined() { @@ -221,7 +231,11 @@ public class BookmarkBase implements Parcelable, Cloneable public boolean isAutomatic() { return (resolution == AUTOMATIC); } - + + public boolean isFitScreen() { + return (resolution == FITSCREEN); + } + public boolean isCustom() { return (resolution == CUSTOM); } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java index 004a716e7..33e6a330d 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java @@ -451,7 +451,7 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref ListPreference listPreference = (ListPreference)findPreference(key); listPreference.setSummary(listPreference.getEntry()); - boolean enabled = listPreference.getValue().equals("custom"); + boolean enabled = listPreference.getValue().equalsIgnoreCase(getResources().getString(R.string.resolution_custom)); if (key.equals("bookmark.resolution")) { findPreference("bookmark.width").setEnabled(enabled); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java index defaf9247..c69b5ff22 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/SessionActivity.java @@ -624,6 +624,10 @@ public class SessionActivity extends Activity screenSettings.setWidth((int)((float)screenMax * 1.6f)); } } + if (screenSettings.isFitScreen()) { + screenSettings.setHeight(screen_height); + screenSettings.setWidth(screen_width); + } progressDialog = new ProgressDialog(this); progressDialog.setTitle(bookmark.getLabel()); From 552cee743102dc280bc4410a009f21544b0d01ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 20 Aug 2013 18:06:19 -0400 Subject: [PATCH 018/202] channels/server: start refactoring to fully match WTSApi --- channels/audin/server/audin.c | 39 +++++++++++--------- channels/cliprdr/server/cliprdr_main.c | 10 ++--- channels/drdynvc/server/drdynvc_main.c | 2 +- channels/rdpdr/server/rdpdr_main.c | 12 +++--- channels/rdpsnd/server/rdpsnd_main.c | 16 ++++---- channels/server/channels.c | 22 ++--------- include/freerdp/channels/wtsvc.h | 51 ++++++++++++++------------ winpr/include/winpr/wtsapi.h | 4 +- 8 files changed, 76 insertions(+), 80 deletions(-) diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 564630d8c..bc74c1f63 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -78,7 +78,7 @@ static void audin_server_send_version(audin_server* audin, wStream* s) { Stream_Write_UINT8(s, MSG_SNDIN_VERSION); Stream_Write_UINT32(s, 1); /* Version (4 bytes) */ - WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_version(audin_server* audin, wStream* s, UINT32 length) @@ -130,7 +130,7 @@ static void audin_server_send_formats(audin_server* audin, wStream* s) } } - WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 length) @@ -166,6 +166,7 @@ static BOOL audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le Stream_Read_UINT16(s, audin->context.client_formats[i].nBlockAlign); Stream_Read_UINT16(s, audin->context.client_formats[i].wBitsPerSample); Stream_Read_UINT16(s, audin->context.client_formats[i].cbSize); + if (audin->context.client_formats[i].cbSize > 0) { Stream_Seek(s, audin->context.client_formats[i].cbSize); @@ -201,7 +202,7 @@ static void audin_server_send_open(audin_server* audin, wStream* s) Stream_Write_UINT16(s, 16); /* wBitsPerSample */ Stream_Write_UINT16(s, 0); /* cbSize */ - WTSVirtualChannelWrite(audin->audin_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); } static BOOL audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 length) @@ -283,10 +284,10 @@ static void* audin_server_thread_func(void* arg) void* buffer; BYTE MessageId; BOOL ready = FALSE; - UINT32 bytes_returned = 0; + DWORD BytesReturned = 0; audin_server* audin = (audin_server*) arg; - if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) + if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); @@ -303,7 +304,7 @@ static void* audin_server_thread_func(void* arg) if (WaitForSingleObject(audin->stopEvent, 0) == WAIT_OBJECT_0) break; - if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE) + if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) break; ready = *((BOOL*) buffer); @@ -330,46 +331,48 @@ static void* audin_server_thread_func(void* arg) Stream_SetPosition(s, 0); - if (WTSVirtualChannelRead(audin->audin_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) { - if (bytes_returned == 0) + if (BytesReturned == 0) break; - Stream_EnsureRemainingCapacity(s, (int) bytes_returned); + Stream_EnsureRemainingCapacity(s, BytesReturned); - if (WTSVirtualChannelRead(audin->audin_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) + { break; + } } - if (bytes_returned < 1) + if (BytesReturned < 1) continue; Stream_Read_UINT8(s, MessageId); - bytes_returned--; + BytesReturned--; switch (MessageId) { case MSG_SNDIN_VERSION: - if (audin_server_recv_version(audin, s, bytes_returned)) + if (audin_server_recv_version(audin, s, BytesReturned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: - if (audin_server_recv_formats(audin, s, bytes_returned)) + if (audin_server_recv_formats(audin, s, BytesReturned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: - audin_server_recv_open_reply(audin, s, bytes_returned); + audin_server_recv_open_reply(audin, s, BytesReturned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: - audin_server_recv_data(audin, s, bytes_returned); + audin_server_recv_data(audin, s, BytesReturned); break; case MSG_SNDIN_FORMATCHANGE: diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 6744748c5..c3c35c669 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -96,7 +96,7 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context) Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -123,7 +123,7 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -150,7 +150,7 @@ static int cliprdr_server_send_format_list_response(CliprdrServerContext* contex Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -392,7 +392,7 @@ static void* cliprdr_server_thread(void* arg) int position; HANDLE events[8]; HANDLE ChannelEvent; - UINT32 BytesReturned; + DWORD BytesReturned; CLIPRDR_HEADER header; CliprdrServerContext* context; @@ -429,7 +429,7 @@ static void* cliprdr_server_thread(void* arg) } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); diff --git a/channels/drdynvc/server/drdynvc_main.c b/channels/drdynvc/server/drdynvc_main.c index 2897023d4..ecca8e587 100644 --- a/channels/drdynvc/server/drdynvc_main.c +++ b/channels/drdynvc/server/drdynvc_main.c @@ -35,7 +35,7 @@ static void* drdynvc_server_thread(void* arg) void* buffer; HANDLE events[8]; HANDLE ChannelEvent; - UINT32 BytesReturned; + DWORD BytesReturned; DrdynvcServerContext* context; context = (DrdynvcServerContext*) arg; diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index c55b6ec1b..58f057bac 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -51,7 +51,7 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context) Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -319,7 +319,7 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -393,7 +393,7 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context) Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -470,7 +470,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context) Stream_SealLength(s); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), NULL); Stream_Free(s, TRUE); @@ -558,7 +558,7 @@ static void* rdpdr_server_thread(void* arg) HANDLE events[8]; RDPDR_HEADER header; HANDLE ChannelEvent; - UINT32 BytesReturned; + DWORD BytesReturned; RdpdrServerContext* context; context = (RdpdrServerContext*) arg; @@ -594,7 +594,7 @@ static void* rdpdr_server_thread(void* arg) break; } - if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, Stream_Pointer(s), + if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR) Stream_Pointer(s), Stream_Capacity(s) - Stream_GetPosition(s), &BytesReturned)) { if (BytesReturned) diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index d56de7fee..070958088 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -74,7 +74,7 @@ static BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_SetPosition(s, 0); return status; @@ -163,7 +163,7 @@ static void* rdpsnd_server_thread(void* arg) UINT16 BodySize; HANDLE events[8]; HANDLE ChannelEvent; - UINT32 BytesReturned; + DWORD BytesReturned; RdpsndServerContext* context; context = (RdpsndServerContext*) arg; @@ -201,7 +201,7 @@ static void* rdpsnd_server_thread(void* arg) Stream_SetPosition(s, 0); if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); @@ -214,7 +214,7 @@ static void* rdpsnd_server_thread(void* arg) Stream_EnsureRemainingCapacity(s, BytesReturned); if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { break; } @@ -384,7 +384,7 @@ static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context) Stream_Seek(s, 3); /* bPad */ Stream_Write(s, src, 4); - WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_SetPosition(s, 0); /* Wave PDU */ @@ -395,7 +395,7 @@ static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context) if (fill_size > 0) Stream_Zero(s, fill_size); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_SetPosition(s, 0); context->priv->out_pending_frames = 0; @@ -449,7 +449,7 @@ static BOOL rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_SetPosition(s, 0); return status; @@ -480,7 +480,7 @@ static BOOL rdpsnd_server_close(RdpsndServerContext* context) Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_GetPosition(s), NULL); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_SetPosition(s, 0); return status; diff --git a/channels/server/channels.c b/channels/server/channels.c index a4c9bdc0b..53d474eba 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -662,11 +662,7 @@ void* WTSVirtualChannelOpenEx( return channel; } -BOOL WTSVirtualChannelQuery( - /* __in */ void* hChannelHandle, - /* __in */ WTS_VIRTUAL_CLASS WtsVirtualClass, - /* __out */ void** ppBuffer, - /* __out */ UINT32* pBytesReturned) +BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned) { void* pfd; BOOL bval; @@ -739,18 +735,12 @@ BOOL WTSVirtualChannelQuery( return result; } -void WTSFreeMemory( - /* __in */ void* pMemory) +VOID WTSFreeMemory(PVOID pMemory) { free(pMemory); } -BOOL WTSVirtualChannelRead( - /* __in */ void* hChannelHandle, - /* __in */ UINT32 TimeOut, - /* __out */ BYTE* Buffer, - /* __in */ UINT32 BufferSize, - /* __out */ UINT32* pBytesRead) +BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead) { wts_data_item* item; rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; @@ -784,11 +774,7 @@ BOOL WTSVirtualChannelRead( return TRUE; } -BOOL WTSVirtualChannelWrite( - /* __in */ void* hChannelHandle, - /* __in */ BYTE* Buffer, - /* __in */ UINT32 Length, - /* __out */ UINT32* pBytesWritten) +BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten) { rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; wts_data_item* item; diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h index 118cfdaa8..b1191f177 100644 --- a/include/freerdp/channels/wtsvc.h +++ b/include/freerdp/channels/wtsvc.h @@ -35,18 +35,27 @@ #include #include -typedef struct WTSVirtualChannelManager WTSVirtualChannelManager; - -#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001 +#include +#include +//#include typedef enum _WTS_VIRTUAL_CLASS { WTSVirtualClientData, WTSVirtualFileHandle, - WTSVirtualEventHandle, - WTSVirtualChannelReady + WTSVirtualEventHandle, /* Extended */ + WTSVirtualChannelReady /* Extended */ } WTS_VIRTUAL_CLASS; +#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006 +#define WTS_CHANNEL_OPTION_DYNAMIC_NO_COMPRESS 0x00000008 + +typedef struct WTSVirtualChannelManager WTSVirtualChannelManager; + #ifdef __cplusplus extern "C" { #endif @@ -72,6 +81,9 @@ FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManag * Static virtual channels must be opened from the main thread. Dynamic virtual channels * can be opened from any thread. */ + +// WINPR_API HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags); + FREERDP_API void* WTSVirtualChannelOpenEx( /* __in */ WTSVirtualChannelManager* vcm, /* __in */ const char* pVirtualName, @@ -83,17 +95,14 @@ FREERDP_API void* WTSVirtualChannelOpenEx( * Servers use this function to gain access to a virtual channel file handle * that can be used for asynchronous I/O. */ -FREERDP_API BOOL WTSVirtualChannelQuery( - /* __in */ void* hChannelHandle, - /* __in */ WTS_VIRTUAL_CLASS WtsVirtualClass, - /* __out */ void** ppBuffer, - /* __out */ UINT32* pBytesReturned); + +WINPR_API BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned); /** * Frees memory allocated by WTSVirtualChannelQuery */ -FREERDP_API void WTSFreeMemory( - /* __in */ void* pMemory); + +WINPR_API VOID WTSFreeMemory(PVOID pMemory); /** * Reads data from the server end of a virtual channel. @@ -112,25 +121,21 @@ FREERDP_API void WTSFreeMemory( * The caller should use the file handle returned by WTSVirtualChannelQuery to * determine whether a packet has arrived. */ -FREERDP_API BOOL WTSVirtualChannelRead( - /* __in */ void* hChannelHandle, - /* __in */ UINT32 TimeOut, - /* __out */ BYTE* Buffer, - /* __in */ UINT32 BufferSize, - /* __out */ UINT32* pBytesRead); + +WINPR_API BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead); /** * Writes data to the server end of a virtual channel. */ -FREERDP_API BOOL WTSVirtualChannelWrite( - /* __in */ void* hChannelHandle, - /* __in */ BYTE* Buffer, - /* __in */ UINT32 Length, - /* __out */ UINT32* pBytesWritten); + +WINPR_API BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten); /** * Closes an open virtual channel handle. */ + +// WINPR_API BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); + FREERDP_API BOOL WTSVirtualChannelClose( /* __in */ void* hChannelHandle); diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index d675255c3..099fc3b2f 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -717,7 +717,9 @@ typedef struct _WTSUSERCONFIGW typedef enum _WTS_VIRTUAL_CLASS { WTSVirtualClientData, - WTSVirtualFileHandle + WTSVirtualFileHandle, + WTSVirtualEventHandle, /* Extended */ + WTSVirtualChannelReady /* Extended */ } WTS_VIRTUAL_CLASS; typedef struct _WTS_SESSION_ADDRESS From c878200e00151c9d901b44aa97a32efe8d5950d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 20 Aug 2013 19:26:36 -0400 Subject: [PATCH 019/202] channels/server: refactor to match WTSApi + avoid conflicts --- channels/audin/server/audin.c | 2 +- channels/cliprdr/server/cliprdr_main.c | 2 +- channels/drdynvc/server/drdynvc_main.c | 4 ++-- channels/rdpdr/server/rdpdr_main.c | 2 +- channels/rdpsnd/server/rdpsnd_main.c | 2 +- channels/server/channels.c | 16 ++++++---------- include/freerdp/channels/wtsvc.h | 15 ++++----------- server/Sample/sfreerdp.c | 22 +++++++++++----------- 8 files changed, 27 insertions(+), 38 deletions(-) diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index bc74c1f63..35b50202d 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -397,7 +397,7 @@ static BOOL audin_server_open(audin_server_context* context) if (!audin->thread) { - audin->audin_channel = WTSVirtualChannelOpenEx(context->vcm, "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC); + audin->audin_channel = WTSVirtualChannelManagerOpenEx(context->vcm, "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC); if (!audin->audin_channel) return FALSE; diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index c3c35c669..3e81809f0 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -468,7 +468,7 @@ static void* cliprdr_server_thread(void* arg) static int cliprdr_server_start(CliprdrServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "cliprdr", 0); + context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "cliprdr", 0); if (!context->priv->ChannelHandle) return -1; diff --git a/channels/drdynvc/server/drdynvc_main.c b/channels/drdynvc/server/drdynvc_main.c index ecca8e587..07da57e0c 100644 --- a/channels/drdynvc/server/drdynvc_main.c +++ b/channels/drdynvc/server/drdynvc_main.c @@ -68,7 +68,7 @@ static void* drdynvc_server_thread(void* arg) } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); @@ -86,7 +86,7 @@ static void* drdynvc_server_thread(void* arg) static int drdynvc_server_start(DrdynvcServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpdr", 0); + context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdr", 0); if (!context->priv->ChannelHandle) return -1; diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 58f057bac..16c150eaa 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -630,7 +630,7 @@ static void* rdpdr_server_thread(void* arg) static int rdpdr_server_start(RdpdrServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpdr", 0); + context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdr", 0); if (!context->priv->ChannelHandle) return -1; diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index 070958088..4bc7107d5 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -488,7 +488,7 @@ static BOOL rdpsnd_server_close(RdpsndServerContext* context) static int rdpsnd_server_start(RdpsndServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpenEx(context->vcm, "rdpsnd", 0); + context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpsnd", 0); if (!context->priv->ChannelHandle) return -1; diff --git a/channels/server/channels.c b/channels/server/channels.c index 53d474eba..35da5afb2 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -518,13 +518,13 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm) /* Initialize drdynvc channel once and only once. */ vcm->drdynvc_state = DRDYNVC_STATE_INITIALIZED; - channel = WTSVirtualChannelOpenEx(vcm, "drdynvc", 0); + channel = WTSVirtualChannelManagerOpenEx(vcm, "drdynvc", 0); if (channel) { vcm->drdynvc_channel = channel; dynvc_caps = 0x00010050; /* DYNVC_CAPS_VERSION1 (4 bytes) */ - WTSVirtualChannelWrite(channel, (BYTE*) &dynvc_caps, sizeof(dynvc_caps), NULL); + WTSVirtualChannelWrite(channel, (PCHAR) &dynvc_caps, sizeof(dynvc_caps), NULL); } } @@ -555,10 +555,7 @@ HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm) return vcm->send_event; } -void* WTSVirtualChannelOpenEx( - /* __in */ WTSVirtualChannelManager* vcm, - /* __in */ const char* pVirtualName, - /* __in */ UINT32 flags) +HANDLE WTSVirtualChannelManagerOpenEx(WTSVirtualChannelManager* vcm, LPSTR pVirtualName, DWORD flags) { int i; int len; @@ -608,7 +605,7 @@ void* WTSVirtualChannelOpenEx( s = Stream_New(NULL, 64); wts_write_drdynvc_create_request(s, channel->channel_id, pVirtualName); - WTSVirtualChannelWrite(vcm->drdynvc_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_Free(s, TRUE); DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list)); @@ -851,8 +848,7 @@ BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, P return TRUE; } -BOOL WTSVirtualChannelClose( - /* __in */ void* hChannelHandle) +BOOL WTSVirtualChannelClose(HANDLE hChannelHandle) { wStream* s; wts_data_item* item; @@ -878,7 +874,7 @@ BOOL WTSVirtualChannelClose( { s = Stream_New(NULL, 8); wts_write_drdynvc_header(s, CLOSE_REQUEST_PDU, channel->channel_id); - WTSVirtualChannelWrite(vcm->drdynvc_channel, Stream_Buffer(s), Stream_GetPosition(s), NULL); + WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); Stream_Free(s, TRUE); } } diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h index b1191f177..3a01c525b 100644 --- a/include/freerdp/channels/wtsvc.h +++ b/include/freerdp/channels/wtsvc.h @@ -65,10 +65,9 @@ extern "C" { */ FREERDP_API WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client); FREERDP_API void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm); -FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, - void** fds, int* fds_count); -FREERDP_API BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm); +FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, void** fds, int* fds_count); +FREERDP_API BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm); FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm); /** @@ -84,10 +83,7 @@ FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManag // WINPR_API HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags); -FREERDP_API void* WTSVirtualChannelOpenEx( - /* __in */ WTSVirtualChannelManager* vcm, - /* __in */ const char* pVirtualName, - /* __in */ UINT32 flags); +WINPR_API HANDLE WTSVirtualChannelManagerOpenEx(WTSVirtualChannelManager* vcm, LPSTR pVirtualName, DWORD flags); /** * Returns information about a specified virtual channel. @@ -134,10 +130,7 @@ WINPR_API BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG * Closes an open virtual channel handle. */ -// WINPR_API BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); - -FREERDP_API BOOL WTSVirtualChannelClose( - /* __in */ void* hChannelHandle); +WINPR_API BOOL WTSVirtualChannelClose(HANDLE hChannelHandle); #ifdef __cplusplus } diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index a88986150..46615ec3e 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -398,10 +398,10 @@ static void* tf_debug_channel_thread_func(void* arg) void* fd; wStream* s; void* buffer; - UINT32 bytes_returned = 0; + DWORD BytesReturned = 0; testPeerContext* context = (testPeerContext*) arg; - if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) + if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); @@ -411,7 +411,7 @@ static void* tf_debug_channel_thread_func(void* arg) s = Stream_New(NULL, 4096); - WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL); + WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test1", 5, NULL); while (1) { @@ -422,25 +422,25 @@ static void* tf_debug_channel_thread_func(void* arg) Stream_SetPosition(s, 0); - if (WTSVirtualChannelRead(context->debug_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) { - if (bytes_returned == 0) + if (BytesReturned == 0) break; - Stream_EnsureRemainingCapacity(s, bytes_returned); + Stream_EnsureRemainingCapacity(s, BytesReturned); - if (WTSVirtualChannelRead(context->debug_channel, 0, Stream_Buffer(s), - Stream_Capacity(s), &bytes_returned) == FALSE) + if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) { /* should not happen */ break; } } - Stream_SetPosition(s, bytes_returned); + Stream_SetPosition(s, BytesReturned); - printf("got %d bytes\n", bytes_returned); + printf("got %d bytes\n", BytesReturned); } Stream_Free(s, TRUE); From 68ec10a9d94d9aef96ce6c1f930c529c36150a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 22 Aug 2013 10:18:38 -0400 Subject: [PATCH 020/202] libwinpr-nt: implement NtCurrentTeb() --- server/Sample/sfreerdp.c | 4 +- winpr/include/winpr/nt.h | 77 +++++++ winpr/libwinpr/error/CMakeLists.txt | 10 + winpr/libwinpr/error/error.c | 25 +-- winpr/libwinpr/error/test/.gitignore | 3 + winpr/libwinpr/error/test/CMakeLists.txt | 31 +++ .../error/test/TestErrorSetLastError.c | 89 ++++++++ winpr/libwinpr/nt/CMakeLists.txt | 53 +++++ winpr/libwinpr/nt/ModuleOptions.cmake | 8 + winpr/libwinpr/nt/module.def | 3 + winpr/libwinpr/nt/nt.c | 205 ++++++++++++++++++ winpr/libwinpr/nt/test/.gitignore | 3 + winpr/libwinpr/nt/test/CMakeLists.txt | 32 +++ winpr/libwinpr/nt/test/TestNtCreateFile.c | 8 + winpr/libwinpr/nt/test/TestNtCurrentTeb.c | 20 ++ 15 files changed, 550 insertions(+), 21 deletions(-) create mode 100644 winpr/include/winpr/nt.h create mode 100644 winpr/libwinpr/error/test/.gitignore create mode 100644 winpr/libwinpr/error/test/CMakeLists.txt create mode 100644 winpr/libwinpr/error/test/TestErrorSetLastError.c create mode 100644 winpr/libwinpr/nt/CMakeLists.txt create mode 100644 winpr/libwinpr/nt/ModuleOptions.cmake create mode 100644 winpr/libwinpr/nt/module.def create mode 100644 winpr/libwinpr/nt/nt.c create mode 100644 winpr/libwinpr/nt/test/.gitignore create mode 100644 winpr/libwinpr/nt/test/CMakeLists.txt create mode 100644 winpr/libwinpr/nt/test/TestNtCreateFile.c create mode 100644 winpr/libwinpr/nt/test/TestNtCurrentTeb.c diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 46615ec3e..6fc2b3278 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -498,7 +498,7 @@ BOOL tf_peer_post_connect(freerdp_peer* client) { if (strncmp(client->settings->ChannelDefArray[i].Name, "rdpdbg", 6) == 0) { - context->debug_channel = WTSVirtualChannelOpenEx(context->vcm, "rdpdbg", 0); + context->debug_channel = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdbg", 0); if (context->debug_channel != NULL) { @@ -580,7 +580,7 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { if (context->debug_channel) { - WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test2", 5, NULL); + WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test2", 5, NULL); } } else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */ diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h new file mode 100644 index 000000000..7a6aae0f4 --- /dev/null +++ b/winpr/include/winpr/nt.h @@ -0,0 +1,77 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Native System Services + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_NT_H +#define WINPR_NT_H + +#include +#include + +#ifndef _WIN32 + +typedef struct _PEB PEB; +typedef struct _PEB* PPEB; + +typedef struct _TEB TEB; +typedef struct _TEB* PTEB; + +/** + * Process Environment Block + */ + +struct _THREAD_BLOCK_ID +{ + DWORD ThreadId; + TEB* ThreadEnvironmentBlock; +}; +typedef struct _THREAD_BLOCK_ID THREAD_BLOCK_ID; + +struct _PEB +{ + DWORD ThreadCount; + DWORD ThreadArraySize; + THREAD_BLOCK_ID* Threads; +}; + +/* + * Thread Environment Block + */ + +struct _TEB +{ + PEB* ProcessEnvironmentBlock; + + DWORD LastErrorValue; + PVOID TlsSlots[64]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +WINPR_API PTEB NtCurrentTeb(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* WINPR_NT_H */ + diff --git a/winpr/libwinpr/error/CMakeLists.txt b/winpr/libwinpr/error/CMakeLists.txt index db6780490..eb78993c6 100644 --- a/winpr/libwinpr/error/CMakeLists.txt +++ b/winpr/libwinpr/error/CMakeLists.txt @@ -31,10 +31,20 @@ add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-nt) + if(MONOLITHIC_BUILD) else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/error/error.c b/winpr/libwinpr/error/error.c index ff11daa6b..96c35cd6c 100644 --- a/winpr/libwinpr/error/error.c +++ b/winpr/libwinpr/error/error.c @@ -23,25 +23,12 @@ #include -/** - * api-ms-win-core-errorhandling-l1-1-1.dll: - * - * GetErrorMode - * SetErrorMode - * GetLastError - * SetLastError - * RestoreLastError - * RaiseException - * UnhandledExceptionFilter - * SetUnhandledExceptionFilter - * AddVectoredExceptionHandler - * RemoveVectoredExceptionHandler - * AddVectoredContinueHandler - * RemoveVectoredContinueHandler - */ - #ifndef _WIN32 +#include + +#include + UINT GetErrorMode(void) { return 0; @@ -54,12 +41,12 @@ UINT SetErrorMode(UINT uMode) DWORD GetLastError(VOID) { - return 0; + return NtCurrentTeb()->LastErrorValue; } VOID SetLastError(DWORD dwErrCode) { - + NtCurrentTeb()->LastErrorValue = dwErrCode; } VOID RestoreLastError(DWORD dwErrCode) diff --git a/winpr/libwinpr/error/test/.gitignore b/winpr/libwinpr/error/test/.gitignore new file mode 100644 index 000000000..8f1dcb16a --- /dev/null +++ b/winpr/libwinpr/error/test/.gitignore @@ -0,0 +1,3 @@ +TestError +TestError.c + diff --git a/winpr/libwinpr/error/test/CMakeLists.txt b/winpr/libwinpr/error/test/CMakeLists.txt new file mode 100644 index 000000000..ecec7093f --- /dev/null +++ b/winpr/libwinpr/error/test/CMakeLists.txt @@ -0,0 +1,31 @@ + +set(MODULE_NAME "TestError") +set(MODULE_PREFIX "TEST_ERROR") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestErrorSetLastError.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-synch winpr-thread winpr-error) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/error/test/TestErrorSetLastError.c b/winpr/libwinpr/error/test/TestErrorSetLastError.c new file mode 100644 index 000000000..073417adc --- /dev/null +++ b/winpr/libwinpr/error/test/TestErrorSetLastError.c @@ -0,0 +1,89 @@ + +#include +#include +#include + +#include + +static int status = 0; + +static DWORD errors[4] = +{ + ERROR_INVALID_DATA, + ERROR_BROKEN_PIPE, + ERROR_INVALID_NAME, + ERROR_BAD_ARGUMENTS +}; + +static void* test_error_thread(void* arg) +{ + int id; + DWORD error; + + id = (int) (size_t) arg; + + error = errors[id]; + + SetLastError(error); + + Sleep(10); + + error = GetLastError(); + + if (error != errors[id]) + { + printf("GetLastError() failure (thread %d): Expected: 0x%04X, Actual: 0x%04X\n", + id, errors[id], error); + + if (!status) + status = -1; + + return NULL; + } + + return NULL; +} + +int TestErrorSetLastError(int argc, char* argv[]) +{ + DWORD error; + HANDLE threads[4]; + + SetLastError(ERROR_ACCESS_DENIED); + + error = GetLastError(); + + if (error != ERROR_ACCESS_DENIED) + { + printf("GetLastError() failure: Expected: 0x%04X, Actual: 0x%04X\n", + ERROR_ACCESS_DENIED, error); + return -1; + } + + threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 0, 0, NULL); + threads[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 1, 0, NULL); + threads[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 2, 0, NULL); + threads[3] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_error_thread, (void*) (size_t) 3, 0, NULL); + + WaitForSingleObject(threads[0], INFINITE); + WaitForSingleObject(threads[1], INFINITE); + WaitForSingleObject(threads[2], INFINITE); + WaitForSingleObject(threads[3], INFINITE); + + CloseHandle(threads[0]); + CloseHandle(threads[1]); + CloseHandle(threads[2]); + CloseHandle(threads[3]); + + error = GetLastError(); + + if (error != ERROR_ACCESS_DENIED) + { + printf("GetLastError() failure: Expected: 0x%04X, Actual: 0x%04X\n", + ERROR_ACCESS_DENIED, error); + return -1; + } + + return status; +} + diff --git a/winpr/libwinpr/nt/CMakeLists.txt b/winpr/libwinpr/nt/CMakeLists.txt new file mode 100644 index 000000000..b7455246e --- /dev/null +++ b/winpr/libwinpr/nt/CMakeLists.txt @@ -0,0 +1,53 @@ +# WinPR: Windows Portable Runtime +# libwinpr-nt cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-nt") +set(MODULE_PREFIX "WINPR_NT") + +set(${MODULE_PREFIX}_SRCS + nt.c) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +set(${MODULE_PREFIX}_LIBS + ${CMAKE_THREAD_LIBS_INIT} + ${CMAKE_DL_LIBS}) + +if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rt) +endif() + +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/nt/ModuleOptions.cmake b/winpr/libwinpr/nt/ModuleOptions.cmake new file mode 100644 index 000000000..750a8f556 --- /dev/null +++ b/winpr/libwinpr/nt/ModuleOptions.cmake @@ -0,0 +1,8 @@ + +set(MINWIN_LAYER "0") +set(MINWIN_GROUP "none") +set(MINWIN_MAJOR_VERSION "0") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "nt") +set(MINWIN_LONG_NAME "Windows Native System Services") +set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}") diff --git a/winpr/libwinpr/nt/module.def b/winpr/libwinpr/nt/module.def new file mode 100644 index 000000000..b45c622b5 --- /dev/null +++ b/winpr/libwinpr/nt/module.def @@ -0,0 +1,3 @@ +LIBRARY "libwinpr-nt" +EXPORTS + diff --git a/winpr/libwinpr/nt/nt.c b/winpr/libwinpr/nt/nt.c new file mode 100644 index 000000000..21f3a00a7 --- /dev/null +++ b/winpr/libwinpr/nt/nt.c @@ -0,0 +1,205 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Native System Services + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/** + * NtXxx Routines: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff557720/ + */ + +#ifndef _WIN32 + +#include + +#include + +/** + * The current implementation of NtCurrentTeb() is not the most efficient + * but it's a starting point. Beware of potential performance bottlenecks + * caused by multithreaded usage of SetLastError/GetLastError. + */ + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static PPEB g_ProcessEnvironmentBlock = NULL; + +static void NtThreadEnvironmentBlockFree(PTEB teb); +static void NtProcessEnvironmentBlockFree(PPEB peb); + +static PTEB NtThreadEnvironmentBlockNew() +{ + PTEB teb = NULL; + pthread_key_t key; + + teb = (PTEB) malloc(sizeof(TEB)); + + if (teb) + { + ZeroMemory(teb, sizeof(TEB)); + + /** + * We are not really using the key, but it provides an automatic way + * of calling NtThreadEnvironmentBlockFree on thread termination for + * the current Thread Environment Block. + */ + + pthread_key_create(&key, (void (*)(void*)) NtThreadEnvironmentBlockFree); + pthread_setspecific(key, (void*) teb); + } + + return teb; +} + +static void NtThreadEnvironmentBlockFree(PTEB teb) +{ + DWORD index; + PPEB peb = NULL; + + peb = teb->ProcessEnvironmentBlock; + + pthread_mutex_lock(&mutex); + + for (index = 0; index < peb->ThreadArraySize; index++) + { + if (peb->Threads[index].ThreadEnvironmentBlock == teb) + { + peb->Threads[index].ThreadId = 0; + peb->Threads[index].ThreadEnvironmentBlock = NULL; + peb->ThreadCount--; + break; + } + } + + if (!peb->ThreadCount) + { + NtProcessEnvironmentBlockFree(peb); + } + + pthread_mutex_unlock(&mutex); + + free(teb); +} + +static PPEB NtProcessEnvironmentBlockNew() +{ + PPEB peb = NULL; + + peb = (PPEB) malloc(sizeof(PEB)); + + if (peb) + { + ZeroMemory(peb, sizeof(PEB)); + + peb->ThreadCount = 0; + peb->ThreadArraySize = 64; + peb->Threads = (THREAD_BLOCK_ID*) malloc(sizeof(THREAD_BLOCK_ID) * peb->ThreadArraySize); + + if (peb->Threads) + { + ZeroMemory(peb->Threads, sizeof(THREAD_BLOCK_ID) * peb->ThreadArraySize); + } + } + + return peb; +} + +static void NtProcessEnvironmentBlockFree(PPEB peb) +{ + if (peb) + { + free(peb->Threads); + free(peb); + } + + g_ProcessEnvironmentBlock = NULL; +} + +PPEB NtCurrentPeb(void) +{ + PPEB peb = NULL; + + pthread_mutex_lock(&mutex); + + if (!g_ProcessEnvironmentBlock) + g_ProcessEnvironmentBlock = NtProcessEnvironmentBlockNew(); + + peb = g_ProcessEnvironmentBlock; + + pthread_mutex_unlock(&mutex); + + return peb; +} + +PTEB NtCurrentTeb(void) +{ + DWORD index; + int freeIndex; + DWORD ThreadId; + PPEB peb = NULL; + PTEB teb = NULL; + + peb = NtCurrentPeb(); + + ThreadId = (DWORD) pthread_self(); + + freeIndex = -1; + + pthread_mutex_lock(&mutex); + + for (index = 0; index < peb->ThreadArraySize; index++) + { + if (!peb->Threads[index].ThreadId) + { + if (freeIndex < 0) + freeIndex = (int) index; + } + + if (peb->Threads[index].ThreadId == ThreadId) + { + teb = peb->Threads[index].ThreadEnvironmentBlock; + break; + } + } + + if (!teb) + { + if (freeIndex >= 0) + { + teb = NtThreadEnvironmentBlockNew(); + peb->Threads[freeIndex].ThreadEnvironmentBlock = teb; + peb->Threads[freeIndex].ThreadId = ThreadId; + peb->ThreadCount++; + + teb->ProcessEnvironmentBlock = peb; + teb->LastErrorValue = 0; + } + } + + pthread_mutex_unlock(&mutex); + + return teb; +} + +#endif + diff --git a/winpr/libwinpr/nt/test/.gitignore b/winpr/libwinpr/nt/test/.gitignore new file mode 100644 index 000000000..1302271b9 --- /dev/null +++ b/winpr/libwinpr/nt/test/.gitignore @@ -0,0 +1,3 @@ +TestNt +TestNt.c + diff --git a/winpr/libwinpr/nt/test/CMakeLists.txt b/winpr/libwinpr/nt/test/CMakeLists.txt new file mode 100644 index 000000000..b3fcb8bab --- /dev/null +++ b/winpr/libwinpr/nt/test/CMakeLists.txt @@ -0,0 +1,32 @@ + +set(MODULE_NAME "TestNt") +set(MODULE_PREFIX "TEST_NT") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestNtCreateFile.c + TestNtCurrentTeb.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-nt) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/nt/test/TestNtCreateFile.c b/winpr/libwinpr/nt/test/TestNtCreateFile.c new file mode 100644 index 000000000..c39a724e0 --- /dev/null +++ b/winpr/libwinpr/nt/test/TestNtCreateFile.c @@ -0,0 +1,8 @@ + +#include + +int TestNtCreateFile(int argc, char* argv[]) +{ + return 0; +} + diff --git a/winpr/libwinpr/nt/test/TestNtCurrentTeb.c b/winpr/libwinpr/nt/test/TestNtCurrentTeb.c new file mode 100644 index 000000000..43f46a77f --- /dev/null +++ b/winpr/libwinpr/nt/test/TestNtCurrentTeb.c @@ -0,0 +1,20 @@ + +#include + +#include + +int TestNtCurrentTeb(int argc, char* argv[]) +{ + PTEB teb; + + teb = NtCurrentTeb(); + + if (!teb) + { + printf("NtCurrentTeb() returned NULL\n"); + return -1; + } + + return 0; +} + From d5679889f3539aac344de013b34cb4e75337f713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 22 Aug 2013 13:30:39 -0400 Subject: [PATCH 021/202] libwinpr-nt: start implementing core NTDLL functions --- include/freerdp/channels/rdpdr.h | 36 +---- winpr/include/winpr/file.h | 25 +--- winpr/include/winpr/io.h | 19 +-- winpr/include/winpr/nt.h | 168 ++++++++++++++++++++++ winpr/include/winpr/registry.h | 4 +- winpr/include/winpr/security.h | 7 +- winpr/include/winpr/wtypes.h | 1 - winpr/libwinpr/nt/nt.c | 162 +++++++++++++++++++++ winpr/libwinpr/nt/test/TestNtCreateFile.c | 24 +++- 9 files changed, 361 insertions(+), 85 deletions(-) diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 88b1bbe79..e1881aae2 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -21,6 +21,7 @@ #ifndef FREERDP_CHANNEL_RDPDR_H #define FREERDP_CHANNEL_RDPDR_H +#include #include #include #include @@ -113,43 +114,14 @@ enum FILE_CREATE_DISPOSITION }; /* DR_CREATE_REQ.CreateOptions [MS-SMB2] */ -enum FILE_CREATE_OPTION -{ - FILE_DIRECTORY_FILE = 0x00000001, - FILE_NON_DIRECTORY_FILE = 0x00000040, - FILE_COMPLETE_IF_OPLOCKED = 0x00000100, - FILE_DELETE_ON_CLOSE = 0x00001000, - FILE_OPEN_REPARSE_POINT = 0x00200000, - FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000 -}; /* DR_CREATE_REQ.DesiredAccess [MS-SMB2] */ -#ifndef _WIN32 - -#if 0 -#define FILE_READ_DATA 0x00000001 -#define FILE_WRITE_DATA 0x00000002 -#define FILE_APPEND_DATA 0x00000004 -#define FILE_READ_EA 0x00000008 -#define FILE_WRITE_EA 0x00000010 -#define FILE_EXECUTE 0x00000020 -#define FILE_READ_ATTRIBUTES 0x00000080 -#define FILE_WRITE_ATTRIBUTES 0x00000100 -#endif - -#include - -#endif - /* DR_CREATE_RSP.Information */ /* DR_DRIVE_CREATE_RSP.DeviceCreateResponse */ -enum FILE_RESPONSE -{ - FILE_SUPERSEDED = 0x00000000, - FILE_OPENED = 0x00000001, - FILE_OVERWRITTEN = 0x00000003 -}; + +#define FILE_OPENED 0x00000001 +#define FILE_OVERWRITTEN 0x00000003 /* DR_CORE_CLIENT_ANNOUNCE_RSP.VersionMinor */ enum RDPDR_MINOR_RDP_VERSION diff --git a/winpr/include/winpr/file.h b/winpr/include/winpr/file.h index eac472bf2..12208dae4 100644 --- a/winpr/include/winpr/file.h +++ b/winpr/include/winpr/file.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -37,30 +38,6 @@ #define INVALID_SET_FILE_POINTER ((DWORD) - 1) #define INVALID_FILE_ATTRIBUTES ((DWORD) - 1) -#define FILE_READ_DATA 0x0001 -#define FILE_LIST_DIRECTORY 0x0001 -#define FILE_WRITE_DATA 0x0002 -#define FILE_ADD_FILE 0x0002 -#define FILE_APPEND_DATA 0x0004 -#define FILE_ADD_SUBDIRECTORY 0x0004 -#define FILE_CREATE_PIPE_INSTANCE 0x0004 -#define FILE_READ_EA 0x0008 -#define FILE_WRITE_EA 0x0010 -#define FILE_EXECUTE 0x0020 -#define FILE_TRAVERSE 0x0020 -#define FILE_DELETE_CHILD 0x0040 -#define FILE_READ_ATTRIBUTES 0x0080 -#define FILE_WRITE_ATTRIBUTES 0x0100 - -#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) -#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE) -#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE) -#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE) - -#define FILE_SHARE_READ 0x00000001 -#define FILE_SHARE_WRITE 0x00000002 -#define FILE_SHARE_DELETE 0x00000004 - #define FILE_ATTRIBUTE_READONLY 0x00000001 #define FILE_ATTRIBUTE_HIDDEN 0x00000002 #define FILE_ATTRIBUTE_SYSTEM 0x00000004 diff --git a/winpr/include/winpr/io.h b/winpr/include/winpr/io.h index c182ea4ef..52d94ed17 100644 --- a/winpr/include/winpr/io.h +++ b/winpr/include/winpr/io.h @@ -25,24 +25,7 @@ #ifndef _WIN32 -#define GENERIC_READ 0x80000000 -#define GENERIC_WRITE 0x40000000 -#define GENERIC_EXECUTE 0x20000000 -#define GENERIC_ALL 0x10000000 - -#define DELETE 0x00010000 -#define READ_CONTROL 0x00020000 -#define WRITE_DAC 0x00040000 -#define WRITE_OWNER 0x00080000 -#define SYNCHRONIZE 0x00100000 -#define STANDARD_RIGHTS_REQUIRED 0x000F0000 -#define STANDARD_RIGHTS_READ 0x00020000 -#define STANDARD_RIGHTS_WRITE 0x00020000 -#define STANDARD_RIGHTS_EXECUTE 0x00020000 -#define STANDARD_RIGHTS_ALL 0x001F0000 -#define SPECIFIC_RIGHTS_ALL 0x0000FFFF -#define ACCESS_SYSTEM_SECURITY 0x01000000 -#define MAXIMUM_ALLOWED 0x02000000 +#include typedef struct _OVERLAPPED { diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index 7a6aae0f4..6af189d5f 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -61,12 +61,180 @@ struct _TEB PVOID TlsSlots[64]; }; +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 +#define GENERIC_EXECUTE 0x20000000 +#define GENERIC_ALL 0x10000000 + +#define DELETE 0x00010000 +#define READ_CONTROL 0x00020000 +#define WRITE_DAC 0x00040000 +#define WRITE_OWNER 0x00080000 +#define SYNCHRONIZE 0x00100000 +#define STANDARD_RIGHTS_REQUIRED 0x000F0000 +#define STANDARD_RIGHTS_READ 0x00020000 +#define STANDARD_RIGHTS_WRITE 0x00020000 +#define STANDARD_RIGHTS_EXECUTE 0x00020000 +#define STANDARD_RIGHTS_ALL 0x001F0000 +#define SPECIFIC_RIGHTS_ALL 0x0000FFFF +#define ACCESS_SYSTEM_SECURITY 0x01000000 +#define MAXIMUM_ALLOWED 0x02000000 + +#define FILE_READ_DATA 0x0001 +#define FILE_LIST_DIRECTORY 0x0001 +#define FILE_WRITE_DATA 0x0002 +#define FILE_ADD_FILE 0x0002 +#define FILE_APPEND_DATA 0x0004 +#define FILE_ADD_SUBDIRECTORY 0x0004 +#define FILE_CREATE_PIPE_INSTANCE 0x0004 +#define FILE_READ_EA 0x0008 +#define FILE_WRITE_EA 0x0010 +#define FILE_EXECUTE 0x0020 +#define FILE_TRAVERSE 0x0020 +#define FILE_DELETE_CHILD 0x0040 +#define FILE_READ_ATTRIBUTES 0x0080 +#define FILE_WRITE_ATTRIBUTES 0x0100 + +#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE) +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE) +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE) + +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 + +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_REMOTE_INSTANCE 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 +#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000 +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + +#define FILE_VALID_OPTION_FLAGS 0x00FFFFFF +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +typedef DWORD ACCESS_MASK; +typedef ACCESS_MASK* PACCESS_MASK; + +typedef CONST char *PCSZ; + +typedef struct _STRING +{ + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING; +typedef STRING *PSTRING; + +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; +typedef PSTRING PCANSI_STRING; + +typedef STRING OEM_STRING; +typedef PSTRING POEM_STRING; +typedef CONST STRING* PCOEM_STRING; + +typedef struct _LSA_UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; + +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_FORCE_ACCESS_CHECK 0x00000400L +#define OBJ_VALID_ATTRIBUTES 0x000007F2L + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES; +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS status; + PVOID Pointer; + } DUMMYUNIONNAME; + + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef VOID (*PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved); + #ifdef __cplusplus extern "C" { #endif WINPR_API PTEB NtCurrentTeb(void); +WINPR_API VOID RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString); + +WINPR_API VOID RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString); + +WINPR_API NTSTATUS RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, + PCANSI_STRING SourceString, BOOLEAN AllocateDestinationString); + +WINPR_API VOID RtlFreeUnicodeString(PUNICODE_STRING UnicodeString); + +WINPR_API VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes, + PUNICODE_STRING ObjectName, ULONG Attributes, HANDLE RootDirectory, + PSECURITY_DESCRIPTOR SecurityDescriptor); + +WINPR_API NTSTATUS NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, + ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); + +WINPR_API NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, + ULONG ShareAccess, ULONG OpenOptions); + +WINPR_API NTSTATUS NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, + ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, + PVOID OutputBuffer, ULONG OutputBufferLength); + +WINPR_API NTSTATUS NtClose(HANDLE Handle); + #ifdef __cplusplus } #endif diff --git a/winpr/include/winpr/registry.h b/winpr/include/winpr/registry.h index 53175ce28..e6f9757f4 100644 --- a/winpr/include/winpr/registry.h +++ b/winpr/include/winpr/registry.h @@ -35,6 +35,7 @@ extern "C" { #include #include +#include #include #include @@ -106,9 +107,6 @@ extern "C" { typedef HANDLE HKEY; typedef HANDLE* PHKEY; -typedef DWORD ACCESS_MASK; -typedef ACCESS_MASK* PACCESS_MASK; - typedef ACCESS_MASK REGSAM; #define HKEY_CLASSES_ROOT ((HKEY) (LONG_PTR) (LONG) 0x80000000) diff --git a/winpr/include/winpr/security.h b/winpr/include/winpr/security.h index 59f02d953..13a49cb28 100644 --- a/winpr/include/winpr/security.h +++ b/winpr/include/winpr/security.h @@ -30,12 +30,7 @@ #ifndef _WIN32 -typedef struct _LSA_UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; +#include #define SECURITY_MANDATORY_UNTRUSTED_RID 0x0000 #define SECURITY_MANDATORY_LOW_RID 0x1000 diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index aeaa33661..d3639d771 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -115,7 +115,6 @@ typedef WCHAR* LPWSTR, *PWSTR, *LPWCH; typedef const WCHAR *LPCWSTR,*PCWSTR; typedef unsigned __int64 QWORD; -typedef UCHAR* STRING; typedef unsigned int UINT; typedef unsigned char UINT8; diff --git a/winpr/libwinpr/nt/nt.c b/winpr/libwinpr/nt/nt.c index 21f3a00a7..d621639b7 100644 --- a/winpr/libwinpr/nt/nt.c +++ b/winpr/libwinpr/nt/nt.c @@ -201,5 +201,167 @@ PTEB NtCurrentTeb(void) return teb; } +/** + * RtlInitAnsiString routine: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff561918/ + */ + +VOID RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString) +{ + DestinationString->Buffer = (PCHAR) SourceString; + + if (!SourceString) + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + } + else + { + USHORT length = (USHORT) strlen(SourceString); + DestinationString->Length = length; + DestinationString->MaximumLength = length + 1; + } +} + +/** + * RtlInitUnicodeString routine: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff561934/ + */ + +VOID RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString) +{ + DestinationString->Buffer = (PWSTR) SourceString; + + if (!SourceString) + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + } + else + { + USHORT length = (USHORT) _wcslen(SourceString); + DestinationString->Length = length * 2; + DestinationString->MaximumLength = (length + 1) * 2; + } +} + +/** + * RtlAnsiStringToUnicodeString function: + * http://msdn.microsoft.com/en-us/library/ms648413/ + */ + +NTSTATUS RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, + PCANSI_STRING SourceString, BOOLEAN AllocateDestinationString) +{ + int index; + + if (!SourceString) + { + RtlInitUnicodeString(DestinationString, NULL); + return 0; + } + + if (AllocateDestinationString) + { + DestinationString->Length = SourceString->Length * 2; + DestinationString->MaximumLength = SourceString->MaximumLength * 2; + + DestinationString->Buffer = (PWSTR) malloc(DestinationString->MaximumLength); + + for (index = 0; index < SourceString->MaximumLength; index++) + { + DestinationString->Buffer[index] = (WCHAR) SourceString->Buffer[index]; + } + } + else + { + + } + + return 0; +} + +/** + * RtlFreeUnicodeString function: + * http://msdn.microsoft.com/en-us/library/ms648418/ + */ + +VOID RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) +{ + if (UnicodeString) + { + if (UnicodeString->Buffer) + free(UnicodeString->Buffer); + + UnicodeString->Length = 0; + UnicodeString->MaximumLength = 0; + } +} + +/** + * InitializeObjectAttributes macro + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff547804/ + */ + +VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes, + PUNICODE_STRING ObjectName, ULONG Attributes, HANDLE RootDirectory, + PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + InitializedAttributes->Length = sizeof(OBJECT_ATTRIBUTES); + InitializedAttributes->ObjectName = ObjectName; + InitializedAttributes->Attributes = Attributes; + InitializedAttributes->RootDirectory = RootDirectory; + InitializedAttributes->SecurityDescriptor = SecurityDescriptor; + InitializedAttributes->SecurityQualityOfService = NULL; +} + +/** + * NtCreateFile function: + * http://msdn.microsoft.com/en-us/library/bb432380/ + */ + +NTSTATUS NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, + ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength) +{ + return 0; +} + +/** + * NtOpenFile function: + * http://msdn.microsoft.com/en-us/library/bb432381/ + */ + +NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, + ULONG ShareAccess, ULONG OpenOptions) +{ + return 0; +} + +/** + * NtDeviceIoControlFile function: + * http://msdn.microsoft.com/en-us/library/ms648411/ + */ + +NTSTATUS NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, + ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, + PVOID OutputBuffer, ULONG OutputBufferLength) +{ + return 0; +} + +/** + * NtClose function: + * http://msdn.microsoft.com/en-us/library/ms648410/ + */ + +NTSTATUS NtClose(HANDLE Handle) +{ + return 0; +} + #endif diff --git a/winpr/libwinpr/nt/test/TestNtCreateFile.c b/winpr/libwinpr/nt/test/TestNtCreateFile.c index c39a724e0..4dcb876ae 100644 --- a/winpr/libwinpr/nt/test/TestNtCreateFile.c +++ b/winpr/libwinpr/nt/test/TestNtCreateFile.c @@ -1,8 +1,30 @@ +#include + #include int TestNtCreateFile(int argc, char* argv[]) { + HANDLE handle; + NTSTATUS ntstatus; + ULONG CreateOptions; + ANSI_STRING aString; + UNICODE_STRING uString; + ACCESS_MASK DesiredAccess = 0; + OBJECT_ATTRIBUTES attributes; + IO_STATUS_BLOCK ioStatusBlock; + + RtlInitAnsiString(&aString, "\\Device\\FreeRDP\\TEST"); + RtlAnsiStringToUnicodeString(&uString, &aString, TRUE); + + InitializeObjectAttributes(&attributes, NULL, 0, NULL, NULL); + + DesiredAccess = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE; + CreateOptions = FILE_DIRECTORY_FILE | FILE_WRITE_THROUGH; + + ntstatus = NtCreateFile(&handle, DesiredAccess, &attributes, &ioStatusBlock, 0, 0, 0, CreateOptions, 0, 0, 0); + + RtlFreeUnicodeString(&uString); + return 0; } - From c1625c1eadcc7c85bec029d350c8a9e753a22a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 22 Aug 2013 19:20:59 -0400 Subject: [PATCH 022/202] libwinpr-wtsapi: start implementation, extend NtApi --- include/freerdp/channels/rdpdr.h | 67 -- winpr/include/winpr/nt.h | 1164 +++++++++++++++++++++++++- winpr/libwinpr/nt/nt.c | 20 + winpr/libwinpr/wtsapi/CMakeLists.txt | 7 +- winpr/libwinpr/wtsapi/wtsapi.c | 124 ++- 5 files changed, 1305 insertions(+), 77 deletions(-) diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index e1881aae2..9a3077a30 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -183,73 +183,6 @@ enum RDP_LOWIO_OP RDP_LOWIO_OP_UNLOCK_MULTIPLE = 0x00000005 }; -/* NTSTATUS values */ -/* http://msdn.microsoft.com/en-us/library/cc704588.aspx */ -enum NTSTATUS -{ - STATUS_SUCCESS = 0x00000000, -#ifndef _WIN32 - STATUS_TIMEOUT = 0x00000102, - STATUS_PENDING = 0x00000103, -#endif - STATUS_REPARSE = 0x00000104, - STATUS_MORE_ENTRIES = 0x00000105, - STATUS_NOT_ALL_ASSIGNED = 0x00000106, - STATUS_OPLOCK_BREAK_IN_PROGRESS = 0x00000108, - STATUS_VOLUME_MOUNTED = 0x00000109, - STATUS_NOTIFY_CLEANUP = 0x0000010B, - STATUS_NOTIFY_ENUM_DIR = 0x0000010C, - STATUS_NO_QUOTAS_FOR_ACCOUNT = 0x0000010D, - STATUS_FILE_LOCKED_WITH_ONLY_READERS = 0x0000012A, - STATUS_FILE_LOCKED_WITH_WRITERS = 0x0000012B, - STATUS_WAIT_FOR_OPLOCK = 0x00000367, - STATUS_OBJECT_NAME_EXISTS = 0x40000000, - STATUS_BAD_CURRENT_DIRECTORY = 0x40000007, - STATUS_NO_MORE_FILES = 0x80000006, - STATUS_DEVICE_PAPER_EMPTY = 0x8000000E, - STATUS_DEVICE_POWERED_OFF = 0x8000000F, - STATUS_DEVICE_OFF_LINE = 0x80000010, - STATUS_DEVICE_BUSY = 0x80000011, - STATUS_NO_MORE_ENTRIES = 0x8000001A, - STATUS_UNSUCCESSFUL = 0xC0000001, - STATUS_NOT_IMPLEMENTED = 0xC0000002, - STATUS_INVALID_INFO_CLASS = 0xC0000003, -#ifndef _WIN32 - STATUS_INVALID_HANDLE = 0xC0000008, - STATUS_INVALID_PARAMETER = 0xC000000D, -#endif - STATUS_NO_SUCH_DEVICE = 0xC000000E, - STATUS_NO_SUCH_FILE = 0xC000000F, - STATUS_INVALID_DEVICE_REQUEST = 0xC0000010, - STATUS_END_OF_FILE = 0xC0000011, - STATUS_NO_MEDIA_IN_DEVICE = 0xC0000013, - STATUS_UNRECOGNIZED_MEDIA = 0xC0000014, - STATUS_ACCESS_DENIED = 0xc0000022, - STATUS_OBJECT_NAME_INVALID = 0xC0000033, - STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034, - STATUS_OBJECT_NAME_COLLISION = 0xc0000035, - STATUS_PORT_DISCONNECTED = 0xC0000037, - STATUS_OBJECT_PATH_INVALID = 0xC0000039, - STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A, - STATUS_INVALID_PORT_HANDLE = 0xC0000042, - STATUS_DELETE_PENDING = 0xC0000056, - STATUS_DISK_FULL = 0xC000007F, - STATUS_DEVICE_NOT_READY = 0xC00000A3, - STATUS_IO_TIMEOUT = 0xC00000B5, - STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA, - STATUS_NOT_SUPPORTED = 0xC00000BB, - STATUS_PRINT_QUEUE_FULL = 0xC00000C6, - STATUS_PRINT_CANCELLED = 0xC00000C8, - STATUS_DIRECTORY_NOT_EMPTY = 0xC0000101, - STATUS_FILE_CORRUPT_ERROR = 0xC0000102, - STATUS_NOT_A_DIRECTORY = 0xC0000103, - STATUS_NAME_TOO_LONG = 0xC0000106, - STATUS_CANCELLED = 0xC0000120, - STATUS_CANNOT_DELETE = 0xC0000121, - STATUS_FILE_DELETED = 0xC0000123, - STATUS_FILE_CLOSED = 0xC0000128 -}; - enum RDPDR_PRINTER_ANNOUNCE_FLAG { RDPDR_PRINTER_ANNOUNCE_FLAG_ASCII = 0x00000001, diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index 6af189d5f..dccf6e69b 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -25,6 +25,1163 @@ #ifndef _WIN32 +#define FACILITY_DEBUGGER 0x1 +#define FACILITY_RPC_RUNTIME 0x2 +#define FACILITY_RPC_STUBS 0x3 +#define FACILITY_IO_ERROR_CODE 0x4 +#define FACILITY_TERMINAL_SERVER 0xA +#define FACILITY_USB_ERROR_CODE 0x10 +#define FACILITY_HID_ERROR_CODE 0x11 +#define FACILITY_FIREWIRE_ERROR_CODE 0x12 +#define FACILITY_CLUSTER_ERROR_CODE 0x13 +#define FACILITY_ACPI_ERROR_CODE 0x14 +#define FACILITY_SXS_ERROR_CODE 0x15 + +#define DBG_EXCEPTION_HANDLED ((NTSTATUS)0x00010001) +#define DBG_CONTINUE ((NTSTATUS)0x00010002) +#define DBG_REPLY_LATER ((NTSTATUS)0x40010001) +#define DBG_UNABLE_TO_PROVIDE_HANDLE ((NTSTATUS)0x40010002) +#define DBG_TERMINATE_THREAD ((NTSTATUS)0x40010003) +#define DBG_TERMINATE_PROCESS ((NTSTATUS)0x40010004) +#define DBG_CONTROL_C ((NTSTATUS)0x40010005) +#define DBG_PRINTEXCEPTION_C ((NTSTATUS)0x40010006) +#define DBG_RIPEXCEPTION ((NTSTATUS)0x40010007) +#define DBG_CONTROL_BREAK ((NTSTATUS)0x40010008) +#define DBG_COMMAND_EXCEPTION ((NTSTATUS)0x40010009) +#define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS)0x80010001) +#define DBG_NO_STATE_CHANGE ((NTSTATUS)0xC0010001) +#define DBG_APP_NOT_IDLE ((NTSTATUS)0xC0010002) + +/** + * NTSTATUS codes + */ + +#if!defined(STATUS_SUCCESS) +#define STATUS_SUCCESS ((NTSTATUS)0x00000000) +#endif + +#define STATUS_SEVERITY_SUCCESS 0x0 +#define STATUS_SEVERITY_INFORMATIONAL 0x1 +#define STATUS_SEVERITY_WARNING 0x2 +#define STATUS_SEVERITY_ERROR 0x3 + +#define STATUS_WAIT_1 ((NTSTATUS)0x00000001) +#define STATUS_WAIT_2 ((NTSTATUS)0x00000002) +#define STATUS_WAIT_3 ((NTSTATUS)0x00000003) +#define STATUS_WAIT_63 ((NTSTATUS)0x0000003f) +#define STATUS_ABANDONED ((NTSTATUS)0x00000080) +#define STATUS_ABANDONED_WAIT_63 ((NTSTATUS)0x000000BF) +#define STATUS_USER_APC ((NTSTATUS)0x000000C0) +#define STATUS_KERNEL_APC ((NTSTATUS)0x00000100) +#define STATUS_ALERTED ((NTSTATUS)0x00000101) +#define STATUS_TIMEOUT ((NTSTATUS)0x00000102) +#define STATUS_PENDING ((NTSTATUS)0x00000103) +#define STATUS_REPARSE ((NTSTATUS)0x00000104) +#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105) +#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS)0x00000106) +#define STATUS_SOME_NOT_MAPPED ((NTSTATUS)0x00000107) +#define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS)0x00000108) +#define STATUS_VOLUME_MOUNTED ((NTSTATUS)0x00000109) +#define STATUS_RXACT_COMMITTED ((NTSTATUS)0x0000010A) +#define STATUS_NOTIFY_CLEANUP ((NTSTATUS)0x0000010B) +#define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS)0x0000010C) +#define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS)0x0000010D) +#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS)0x0000010E) +#define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS)0x00000110) +#define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS)0x00000111) +#define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS)0x00000112) +#define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS)0x00000113) +#define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS)0x00000114) +#define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS)0x00000115) +#define STATUS_CRASH_DUMP ((NTSTATUS)0x00000116) +#define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS)0x00000117) +#define STATUS_REPARSE_OBJECT ((NTSTATUS)0x00000118) +#define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS)0x00000119) +#define STATUS_TRANSLATION_COMPLETE ((NTSTATUS)0x00000120) +#define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS)0x00000121) +#define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS)0x00000122) +#define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS)0x00000123) +#define STATUS_PROCESS_IN_JOB ((NTSTATUS)0x00000124) +#define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS)0x00000125) +#define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS)0x00000126) + +#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000) +#define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS)0x40000001) +#define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS)0x40000002) +#define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003) +#define STATUS_RXACT_STATE_CREATED ((NTSTATUS)0x40000004) +#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005) +#define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS)0x40000006) +#define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS)0x40000007) +#define STATUS_SERIAL_MORE_WRITES ((NTSTATUS)0x40000008) +#define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009) +#define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS)0x4000000A) +#define STATUS_FT_WRITE_RECOVERY ((NTSTATUS)0x4000000B) +#define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS)0x4000000C) +#define STATUS_NULL_LM_PASSWORD ((NTSTATUS)0x4000000D) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS)0x4000000E) +#define STATUS_RECEIVE_PARTIAL ((NTSTATUS)0x4000000F) +#define STATUS_RECEIVE_EXPEDITED ((NTSTATUS)0x40000010) +#define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS)0x40000011) +#define STATUS_EVENT_DONE ((NTSTATUS)0x40000012) +#define STATUS_EVENT_PENDING ((NTSTATUS)0x40000013) +#define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS)0x40000014) +#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015) +#define STATUS_PREDEFINED_HANDLE ((NTSTATUS)0x40000016) +#define STATUS_WAS_UNLOCKED ((NTSTATUS)0x40000017) +#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018) +#define STATUS_WAS_LOCKED ((NTSTATUS)0x40000019) +#define STATUS_LOG_HARD_ERROR ((NTSTATUS)0x4000001A) +#define STATUS_ALREADY_WIN32 ((NTSTATUS)0x4000001B) +#define STATUS_WX86_UNSIMULATE ((NTSTATUS)0x4000001C) +#define STATUS_WX86_CONTINUE ((NTSTATUS)0x4000001D) +#define STATUS_WX86_SINGLE_STEP ((NTSTATUS)0x4000001E) +#define STATUS_WX86_BREAKPOINT ((NTSTATUS)0x4000001F) +#define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS)0x40000020) +#define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS)0x40000021) +#define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS)0x40000022) +#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS)0x40000023) +#define STATUS_NO_YIELD_PERFORMED ((NTSTATUS)0x40000024) +#define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS)0x40000025) +#define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS)0x40000026) +#define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS)0x40000027) +#define STATUS_WX86_CREATEWX86TIB ((NTSTATUS)0x40000028) +#define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS)0x40000029) +#define STATUS_HIBERNATED ((NTSTATUS)0x4000002A) +#define STATUS_RESUME_HIBERNATION ((NTSTATUS)0x4000002B) +#define STATUS_FIRMWARE_UPDATED ((NTSTATUS)0x4000002C) +#define STATUS_WAKE_SYSTEM ((NTSTATUS)0x40000294) +#define STATUS_DS_SHUTTING_DOWN ((NTSTATUS)0x40000370) + +#define RPC_NT_UUID_LOCAL_ONLY ((NTSTATUS)0x40020056) +#define RPC_NT_SEND_INCOMPLETE ((NTSTATUS)0x400200AF) + +#define STATUS_CTX_CDM_CONNECT ((NTSTATUS)0x400A0004) +#define STATUS_CTX_CDM_DISCONNECT ((NTSTATUS)0x400A0005) + +#define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT ((NTSTATUS)0x4015000D) + +#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001) +#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002) +#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003) +#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005) +#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006) +#define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS)0x80000007) + +#define STATUS_HANDLES_CLOSED ((NTSTATUS)0x8000000A) +#define STATUS_NO_INHERITANCE ((NTSTATUS)0x8000000B) +#define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS)0x8000000C) +#define STATUS_PARTIAL_COPY ((NTSTATUS)0x8000000D) +#define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS)0x8000000E) +#define STATUS_DEVICE_POWERED_OFF ((NTSTATUS)0x8000000F) +#define STATUS_DEVICE_OFF_LINE ((NTSTATUS)0x80000010) +#define STATUS_DEVICE_BUSY ((NTSTATUS)0x80000011) +#define STATUS_NO_MORE_EAS ((NTSTATUS)0x80000012) +#define STATUS_INVALID_EA_NAME ((NTSTATUS)0x80000013) +#define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS)0x80000014) +#define STATUS_INVALID_EA_FLAG ((NTSTATUS)0x80000015) +#define STATUS_VERIFY_REQUIRED ((NTSTATUS)0x80000016) +#define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS)0x80000017) +#define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS)0x80000018) +#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001A) +#define STATUS_FILEMARK_DETECTED ((NTSTATUS)0x8000001B) +#define STATUS_MEDIA_CHANGED ((NTSTATUS)0x8000001C) +#define STATUS_BUS_RESET ((NTSTATUS)0x8000001D) +#define STATUS_END_OF_MEDIA ((NTSTATUS)0x8000001E) +#define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS)0x8000001F) +#define STATUS_MEDIA_CHECK ((NTSTATUS)0x80000020) +#define STATUS_SETMARK_DETECTED ((NTSTATUS)0x80000021) +#define STATUS_NO_DATA_DETECTED ((NTSTATUS)0x80000022) +#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS)0x80000023) +#define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS)0x80000024) +#define STATUS_ALREADY_DISCONNECTED ((NTSTATUS)0x80000025) +#define STATUS_LONGJUMP ((NTSTATUS)0x80000026) +#define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS)0x80000027) +#define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS)0x80000028) +#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029) +#define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS)0x8000002A) +#define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS)0x8000002B) +#define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS)0x8000002C) + +#define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS)0x80000288) +#define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS)0x80000289) + +#define STATUS_CLUSTER_NODE_ALREADY_UP ((NTSTATUS)0x80130001) +#define STATUS_CLUSTER_NODE_ALREADY_DOWN ((NTSTATUS)0x80130002) +#define STATUS_CLUSTER_NETWORK_ALREADY_ONLINE ((NTSTATUS)0x80130003) +#define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE ((NTSTATUS)0x80130004) +#define STATUS_CLUSTER_NODE_ALREADY_MEMBER ((NTSTATUS)0x80130005) + +#define STATUS_WAIT_0 ((NTSTATUS)0x00000000) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001) +#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002) +#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004) +#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005) +#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006) +#define STATUS_PAGEFILE_QUOTA ((NTSTATUS)0xC0000007) +#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008) +#define STATUS_BAD_INITIAL_STACK ((NTSTATUS)0xC0000009) +#define STATUS_BAD_INITIAL_PC ((NTSTATUS)0xC000000A) +#define STATUS_INVALID_CID ((NTSTATUS)0xC000000B) +#define STATUS_TIMER_NOT_CANCELED ((NTSTATUS)0xC000000C) +#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000D) +#define STATUS_NO_SUCH_DEVICE ((NTSTATUS)0xC000000E) +#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000F) +#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010) +#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011) +#define STATUS_WRONG_VOLUME ((NTSTATUS)0xC0000012) +#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS)0xC0000013) +#define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS)0xC0000014) +#define STATUS_NONEXISTENT_SECTOR ((NTSTATUS)0xC0000015) +#define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS)0xC0000016) +#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017) +#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018) +#define STATUS_NOT_MAPPED_VIEW ((NTSTATUS)0xC0000019) +#define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS)0xC000001A) +#define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS)0xC000001B) +#define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS)0xC000001C) +#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001D) +#define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS)0xC000001E) +#define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xC000001F) +#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020) +#define STATUS_ALREADY_COMMITTED ((NTSTATUS)0xC0000021) +#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022) +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023) +#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024) +#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025) +#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026) +#define STATUS_UNWIND ((NTSTATUS)0xC0000027) +#define STATUS_BAD_STACK ((NTSTATUS)0xC0000028) +#define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS)0xC0000029) +#define STATUS_NOT_LOCKED ((NTSTATUS)0xC000002A) +#define STATUS_PARITY_ERROR ((NTSTATUS)0xC000002B) +#define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS)0xC000002C) +#define STATUS_NOT_COMMITTED ((NTSTATUS)0xC000002D) +#define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS)0xC000002E) +#define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS)0xC000002F) +#define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS)0xC0000030) +#define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS)0xC0000031) +#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS)0xC0000032) +#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033) +#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034) +#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035) +#define STATUS_PORT_DISCONNECTED ((NTSTATUS)0xC0000037) +#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS)0xC0000038) +#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039) +#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003A) +#define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS)0xC000003B) +#define STATUS_DATA_OVERRUN ((NTSTATUS)0xC000003C) +#define STATUS_DATA_LATE_ERROR ((NTSTATUS)0xC000003D) +#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003E) +#define STATUS_CRC_ERROR ((NTSTATUS)0xC000003F) +#define STATUS_SECTION_TOO_BIG ((NTSTATUS)0xC0000040) +#define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS)0xC0000041) +#define STATUS_INVALID_PORT_HANDLE ((NTSTATUS)0xC0000042) +#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043) +#define STATUS_QUOTA_EXCEEDED ((NTSTATUS)0xC0000044) +#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045) +#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046) +#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047) +#define STATUS_PORT_ALREADY_SET ((NTSTATUS)0xC0000048) +#define STATUS_SECTION_NOT_IMAGE ((NTSTATUS)0xC0000049) +#define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS)0xC000004A) +#define STATUS_THREAD_IS_TERMINATING ((NTSTATUS)0xC000004B) +#define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS)0xC000004C) +#define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS)0xC000004D) +#define STATUS_SECTION_PROTECTION ((NTSTATUS)0xC000004E) +#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS)0xC000004F) +#define STATUS_EA_TOO_LARGE ((NTSTATUS)0xC0000050) +#define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS)0xC0000051) +#define STATUS_NO_EAS_ON_FILE ((NTSTATUS)0xC0000052) +#define STATUS_EA_CORRUPT_ERROR ((NTSTATUS)0xC0000053) +#define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS)0xC0000054) +#define STATUS_LOCK_NOT_GRANTED ((NTSTATUS)0xC0000055) +#define STATUS_DELETE_PENDING ((NTSTATUS)0xC0000056) +#define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS)0xC0000057) +#define STATUS_UNKNOWN_REVISION ((NTSTATUS)0xC0000058) +#define STATUS_REVISION_MISMATCH ((NTSTATUS)0xC0000059) +#define STATUS_INVALID_OWNER ((NTSTATUS)0xC000005A) +#define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS)0xC000005B) +#define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS)0xC000005C) +#define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS)0xC000005D) +#define STATUS_NO_LOGON_SERVERS ((NTSTATUS)0xC000005E) +#define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS)0xC000005F) +#define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS)0xC0000060) +#define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061) +#define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS)0xC0000062) +#define STATUS_USER_EXISTS ((NTSTATUS)0xC0000063) +#define STATUS_NO_SUCH_USER ((NTSTATUS)0xC0000064) +#define STATUS_GROUP_EXISTS ((NTSTATUS)0xC0000065) +#define STATUS_NO_SUCH_GROUP ((NTSTATUS)0xC0000066) +#define STATUS_MEMBER_IN_GROUP ((NTSTATUS)0xC0000067) +#define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS)0xC0000068) +#define STATUS_LAST_ADMIN ((NTSTATUS)0xC0000069) +#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006A) +#define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS)0xC000006B) +#define STATUS_PASSWORD_RESTRICTION ((NTSTATUS)0xC000006C) +#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006D) +#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006E) +#define STATUS_INVALID_LOGON_HOURS ((NTSTATUS)0xC000006F) +#define STATUS_INVALID_WORKSTATION ((NTSTATUS)0xC0000070) +#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071) +#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072) +#define STATUS_NONE_MAPPED ((NTSTATUS)0xC0000073) +#define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS)0xC0000074) +#define STATUS_LUIDS_EXHAUSTED ((NTSTATUS)0xC0000075) +#define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS)0xC0000076) +#define STATUS_INVALID_ACL ((NTSTATUS)0xC0000077) +#define STATUS_INVALID_SID ((NTSTATUS)0xC0000078) +#define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS)0xC0000079) +#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007A) +#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007B) +#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007C) +#define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS)0xC000007D) +#define STATUS_RANGE_NOT_LOCKED ((NTSTATUS)0xC000007E) +#define STATUS_DISK_FULL ((NTSTATUS)0xC000007F) +#define STATUS_SERVER_DISABLED ((NTSTATUS)0xC0000080) +#define STATUS_SERVER_NOT_DISABLED ((NTSTATUS)0xC0000081) +#define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS)0xC0000082) +#define STATUS_GUIDS_EXHAUSTED ((NTSTATUS)0xC0000083) +#define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS)0xC0000084) +#define STATUS_AGENTS_EXHAUSTED ((NTSTATUS)0xC0000085) +#define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS)0xC0000086) +#define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS)0xC0000087) +#define STATUS_NOT_MAPPED_DATA ((NTSTATUS)0xC0000088) +#define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS)0xC0000089) +#define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS)0xC000008A) +#define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS)0xC000008B) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008C) +#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008D) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008E) +#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008F) +#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090) +#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091) +#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092) +#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094) +#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095) +#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096) +#define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS)0xC0000097) +#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098) +#define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS)0xC0000099) +#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009A) +#define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS)0xC000009B) +#define STATUS_DEVICE_DATA_ERROR ((NTSTATUS)0xC000009C) +#define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS)0xC000009D) +#define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS)0xC000009E) +#define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS)0xC000009F) +#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0) +#define STATUS_WORKING_SET_QUOTA ((NTSTATUS)0xC00000A1) +#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS)0xC00000A2) +#define STATUS_DEVICE_NOT_READY ((NTSTATUS)0xC00000A3) +#define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS)0xC00000A4) +#define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS)0xC00000A5) +#define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS)0xC00000A6) +#define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS)0xC00000A7) +#define STATUS_BAD_TOKEN_TYPE ((NTSTATUS)0xC00000A8) +#define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS)0xC00000A9) +#define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS)0xC00000AA) +#define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS)0xC00000AB) +#define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS)0xC00000AC) +#define STATUS_INVALID_PIPE_STATE ((NTSTATUS)0xC00000AD) +#define STATUS_PIPE_BUSY ((NTSTATUS)0xC00000AE) +#define STATUS_ILLEGAL_FUNCTION ((NTSTATUS)0xC00000AF) +#define STATUS_PIPE_DISCONNECTED ((NTSTATUS)0xC00000B0) +#define STATUS_PIPE_CLOSING ((NTSTATUS)0xC00000B1) +#define STATUS_PIPE_CONNECTED ((NTSTATUS)0xC00000B2) +#define STATUS_PIPE_LISTENING ((NTSTATUS)0xC00000B3) +#define STATUS_INVALID_READ_MODE ((NTSTATUS)0xC00000B4) +#define STATUS_IO_TIMEOUT ((NTSTATUS)0xC00000B5) +#define STATUS_FILE_FORCED_CLOSED ((NTSTATUS)0xC00000B6) +#define STATUS_PROFILING_NOT_STARTED ((NTSTATUS)0xC00000B7) +#define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS)0xC00000B8) +#define STATUS_COULD_NOT_INTERPRET ((NTSTATUS)0xC00000B9) +#define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS)0xC00000BA) +#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BB) +#define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS)0xC00000BC) +#define STATUS_DUPLICATE_NAME ((NTSTATUS)0xC00000BD) +#define STATUS_BAD_NETWORK_PATH ((NTSTATUS)0xC00000BE) +#define STATUS_NETWORK_BUSY ((NTSTATUS)0xC00000BF) +#define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS)0xC00000C0) +#define STATUS_TOO_MANY_COMMANDS ((NTSTATUS)0xC00000C1) +#define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS)0xC00000C2) +#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS)0xC00000C3) +#define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS)0xC00000C4) +#define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS)0xC00000C5) +#define STATUS_PRINT_QUEUE_FULL ((NTSTATUS)0xC00000C6) +#define STATUS_NO_SPOOL_SPACE ((NTSTATUS)0xC00000C7) +#define STATUS_PRINT_CANCELLED ((NTSTATUS)0xC00000C8) +#define STATUS_NETWORK_NAME_DELETED ((NTSTATUS)0xC00000C9) +#define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS)0xC00000CA) +#define STATUS_BAD_DEVICE_TYPE ((NTSTATUS)0xC00000CB) +#define STATUS_BAD_NETWORK_NAME ((NTSTATUS)0xC00000CC) +#define STATUS_TOO_MANY_NAMES ((NTSTATUS)0xC00000CD) +#define STATUS_TOO_MANY_SESSIONS ((NTSTATUS)0xC00000CE) +#define STATUS_SHARING_PAUSED ((NTSTATUS)0xC00000CF) +#define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS)0xC00000D0) +#define STATUS_REDIRECTOR_PAUSED ((NTSTATUS)0xC00000D1) +#define STATUS_NET_WRITE_FAULT ((NTSTATUS)0xC00000D2) +#define STATUS_PROFILING_AT_LIMIT ((NTSTATUS)0xC00000D3) +#define STATUS_NOT_SAME_DEVICE ((NTSTATUS)0xC00000D4) +#define STATUS_FILE_RENAMED ((NTSTATUS)0xC00000D5) +#define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS)0xC00000D6) +#define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS)0xC00000D7) +#define STATUS_CANT_WAIT ((NTSTATUS)0xC00000D8) +#define STATUS_PIPE_EMPTY ((NTSTATUS)0xC00000D9) +#define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS)0xC00000DA) +#define STATUS_CANT_TERMINATE_SELF ((NTSTATUS)0xC00000DB) +#define STATUS_INVALID_SERVER_STATE ((NTSTATUS)0xC00000DC) +#define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS)0xC00000DD) +#define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS)0xC00000DE) +#define STATUS_NO_SUCH_DOMAIN ((NTSTATUS)0xC00000DF) +#define STATUS_DOMAIN_EXISTS ((NTSTATUS)0xC00000E0) +#define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00000E1) +#define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS)0xC00000E2) +#define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS)0xC00000E3) +#define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS)0xC00000E4) +#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5) +#define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS)0xC00000E6) +#define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS)0xC00000E7) +#define STATUS_INVALID_USER_BUFFER ((NTSTATUS)0xC00000E8) +#define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS)0xC00000E9) +#define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS)0xC00000EA) +#define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS)0xC00000EB) +#define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS)0xC00000EC) +#define STATUS_NOT_LOGON_PROCESS ((NTSTATUS)0xC00000ED) +#define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS)0xC00000EE) +#define STATUS_INVALID_PARAMETER_1 ((NTSTATUS)0xC00000EF) +#define STATUS_INVALID_PARAMETER_2 ((NTSTATUS)0xC00000F0) +#define STATUS_INVALID_PARAMETER_3 ((NTSTATUS)0xC00000F1) +#define STATUS_INVALID_PARAMETER_4 ((NTSTATUS)0xC00000F2) +#define STATUS_INVALID_PARAMETER_5 ((NTSTATUS)0xC00000F3) +#define STATUS_INVALID_PARAMETER_6 ((NTSTATUS)0xC00000F4) +#define STATUS_INVALID_PARAMETER_7 ((NTSTATUS)0xC00000F5) +#define STATUS_INVALID_PARAMETER_8 ((NTSTATUS)0xC00000F6) +#define STATUS_INVALID_PARAMETER_9 ((NTSTATUS)0xC00000F7) +#define STATUS_INVALID_PARAMETER_10 ((NTSTATUS)0xC00000F8) +#define STATUS_INVALID_PARAMETER_11 ((NTSTATUS)0xC00000F9) +#define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xC00000FA) +#define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS)0xC00000FB) +#define STATUS_REDIRECTOR_STARTED ((NTSTATUS)0xC00000FC) +#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FD) +#define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xC00000FE) +#define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS)0xC00000FF) +#define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS)0xC0000100) +#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS)0xC0000101) +#define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS)0xC0000102) +#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xC0000103) +#define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS)0xC0000104) +#define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS)0xC0000105) +#define STATUS_NAME_TOO_LONG ((NTSTATUS)0xC0000106) +#define STATUS_FILES_OPEN ((NTSTATUS)0xC0000107) +#define STATUS_CONNECTION_IN_USE ((NTSTATUS)0xC0000108) +#define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS)0xC0000109) +#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010A) +#define STATUS_INVALID_LOGON_TYPE ((NTSTATUS)0xC000010B) +#define STATUS_NO_GUID_TRANSLATION ((NTSTATUS)0xC000010C) +#define STATUS_CANNOT_IMPERSONATE ((NTSTATUS)0xC000010D) +#define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xC000010E) +#define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS)0xC000010F) +#define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS)0xC0000110) +#define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS)0xC0000111) +#define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS)0xC0000112) +#define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS)0xC0000113) +#define STATUS_ABIOS_INVALID_LID ((NTSTATUS)0xC0000114) +#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS)0xC0000115) +#define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS)0xC0000116) +#define STATUS_NO_LDT ((NTSTATUS)0xC0000117) +#define STATUS_INVALID_LDT_SIZE ((NTSTATUS)0xC0000118) +#define STATUS_INVALID_LDT_OFFSET ((NTSTATUS)0xC0000119) +#define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS)0xC000011A) +#define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS)0xC000011B) +#define STATUS_RXACT_INVALID_STATE ((NTSTATUS)0xC000011C) +#define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS)0xC000011D) +#define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS)0xC000011E) +#define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS)0xC000011F) +#define STATUS_CANCELLED ((NTSTATUS)0xC0000120) +#define STATUS_CANNOT_DELETE ((NTSTATUS)0xC0000121) +#define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS)0xC0000122) +#define STATUS_FILE_DELETED ((NTSTATUS)0xC0000123) +#define STATUS_SPECIAL_ACCOUNT ((NTSTATUS)0xC0000124) +#define STATUS_SPECIAL_GROUP ((NTSTATUS)0xC0000125) +#define STATUS_SPECIAL_USER ((NTSTATUS)0xC0000126) +#define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS)0xC0000127) +#define STATUS_FILE_CLOSED ((NTSTATUS)0xC0000128) +#define STATUS_TOO_MANY_THREADS ((NTSTATUS)0xC0000129) +#define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS)0xC000012A) +#define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS)0xC000012B) +#define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS)0xC000012C) +#define STATUS_COMMITMENT_LIMIT ((NTSTATUS)0xC000012D) +#define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS)0xC000012E) +#define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS)0xC000012F) +#define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS)0xC0000130) +#define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS)0xC0000131) +#define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS)0xC0000132) +#define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS)0xC0000133) +#define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS)0xC0000134) +#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135) +#define STATUS_OPEN_FAILED ((NTSTATUS)0xC0000136) +#define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS)0xC0000137) +#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138) +#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139) +#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013A) +#define STATUS_LOCAL_DISCONNECT ((NTSTATUS)0xC000013B) +#define STATUS_REMOTE_DISCONNECT ((NTSTATUS)0xC000013C) +#define STATUS_REMOTE_RESOURCES ((NTSTATUS)0xC000013D) +#define STATUS_LINK_FAILED ((NTSTATUS)0xC000013E) +#define STATUS_LINK_TIMEOUT ((NTSTATUS)0xC000013F) +#define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140) +#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141) +#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142) +#define STATUS_MISSING_SYSTEMFILE ((NTSTATUS)0xC0000143) +#define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS)0xC0000144) +#define STATUS_APP_INIT_FAILURE ((NTSTATUS)0xC0000145) +#define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS)0xC0000146) +#define STATUS_NO_PAGEFILE ((NTSTATUS)0xC0000147) +#define STATUS_INVALID_LEVEL ((NTSTATUS)0xC0000148) +#define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS)0xC0000149) +#define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS)0xC000014A) +#define STATUS_PIPE_BROKEN ((NTSTATUS)0xC000014B) +#define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014C) +#define STATUS_REGISTRY_IO_FAILED ((NTSTATUS)0xC000014D) +#define STATUS_NO_EVENT_PAIR ((NTSTATUS)0xC000014E) +#define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS)0xC000014F) +#define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS)0xC0000150) +#define STATUS_NO_SUCH_ALIAS ((NTSTATUS)0xC0000151) +#define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS)0xC0000152) +#define STATUS_MEMBER_IN_ALIAS ((NTSTATUS)0xC0000153) +#define STATUS_ALIAS_EXISTS ((NTSTATUS)0xC0000154) +#define STATUS_LOGON_NOT_GRANTED ((NTSTATUS)0xC0000155) +#define STATUS_TOO_MANY_SECRETS ((NTSTATUS)0xC0000156) +#define STATUS_SECRET_TOO_LONG ((NTSTATUS)0xC0000157) +#define STATUS_INTERNAL_DB_ERROR ((NTSTATUS)0xC0000158) +#define STATUS_FULLSCREEN_MODE ((NTSTATUS)0xC0000159) +#define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS)0xC000015A) +#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015B) +#define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015C) +#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000015D) +#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS)0xC000015E) +#define STATUS_FT_MISSING_MEMBER ((NTSTATUS)0xC000015F) +#define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS)0xC0000160) +#define STATUS_ILLEGAL_CHARACTER ((NTSTATUS)0xC0000161) +#define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS)0xC0000162) +#define STATUS_UNDEFINED_CHARACTER ((NTSTATUS)0xC0000163) +#define STATUS_FLOPPY_VOLUME ((NTSTATUS)0xC0000164) +#define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS)0xC0000165) +#define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS)0xC0000166) +#define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS)0xC0000167) +#define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS)0xC0000168) +#define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS)0xC0000169) +#define STATUS_DISK_OPERATION_FAILED ((NTSTATUS)0xC000016A) +#define STATUS_DISK_RESET_FAILED ((NTSTATUS)0xC000016B) +#define STATUS_SHARED_IRQ_BUSY ((NTSTATUS)0xC000016C) +#define STATUS_FT_ORPHANING ((NTSTATUS)0xC000016D) +#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS)0xC000016E) + +#define STATUS_PARTITION_FAILURE ((NTSTATUS)0xC0000172) +#define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS)0xC0000173) +#define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS)0xC0000174) +#define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS)0xC0000175) +#define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS)0xC0000176) +#define STATUS_EOM_OVERFLOW ((NTSTATUS)0xC0000177) +#define STATUS_NO_MEDIA ((NTSTATUS)0xC0000178) +#define STATUS_NO_SUCH_MEMBER ((NTSTATUS)0xC000017A) +#define STATUS_INVALID_MEMBER ((NTSTATUS)0xC000017B) +#define STATUS_KEY_DELETED ((NTSTATUS)0xC000017C) +#define STATUS_NO_LOG_SPACE ((NTSTATUS)0xC000017D) +#define STATUS_TOO_MANY_SIDS ((NTSTATUS)0xC000017E) +#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000017F) +#define STATUS_KEY_HAS_CHILDREN ((NTSTATUS)0xC0000180) +#define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS)0xC0000181) +#define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS)0xC0000182) +#define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS)0xC0000183) +#define STATUS_INVALID_DEVICE_STATE ((NTSTATUS)0xC0000184) +#define STATUS_IO_DEVICE_ERROR ((NTSTATUS)0xC0000185) +#define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS)0xC0000186) +#define STATUS_BACKUP_CONTROLLER ((NTSTATUS)0xC0000187) +#define STATUS_LOG_FILE_FULL ((NTSTATUS)0xC0000188) +#define STATUS_TOO_LATE ((NTSTATUS)0xC0000189) +#define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS)0xC000018A) +#define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS)0xC000018B) +#define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS)0xC000018C) +#define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS)0xC000018D) +#define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS)0xC000018E) +#define STATUS_EVENTLOG_CANT_START ((NTSTATUS)0xC000018F) +#define STATUS_TRUST_FAILURE ((NTSTATUS)0xC0000190) +#define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS)0xC0000191) +#define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS)0xC0000192) +#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193) +#define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS)0xC0000194) +#define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS)0xC0000195) +#define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS)0xC0000196) +#define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS)0xC0000197) +#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS)0xC0000198) +#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS)0xC0000199) +#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS)0xC000019A) +#define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS)0xC000019B) +#define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS)0xC000019C) +#define STATUS_NO_USER_SESSION_KEY ((NTSTATUS)0xC0000202) +#define STATUS_USER_SESSION_DELETED ((NTSTATUS)0xC0000203) +#define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS)0xC0000204) +#define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS)0xC0000205) +#define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS)0xC0000206) +#define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS)0xC0000207) +#define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS)0xC0000208) +#define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS)0xC0000209) +#define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS)0xC000020A) +#define STATUS_ADDRESS_CLOSED ((NTSTATUS)0xC000020B) +#define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS)0xC000020C) +#define STATUS_CONNECTION_RESET ((NTSTATUS)0xC000020D) +#define STATUS_TOO_MANY_NODES ((NTSTATUS)0xC000020E) +#define STATUS_TRANSACTION_ABORTED ((NTSTATUS)0xC000020F) +#define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS)0xC0000210) +#define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS)0xC0000211) +#define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS)0xC0000212) +#define STATUS_TRANSACTION_RESPONDED ((NTSTATUS)0xC0000213) +#define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS)0xC0000214) +#define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS)0xC0000215) +#define STATUS_NOT_SERVER_SESSION ((NTSTATUS)0xC0000216) +#define STATUS_NOT_CLIENT_SESSION ((NTSTATUS)0xC0000217) +#define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS)0xC0000218) +#define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS)0xC0000219) +#define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS)0xC000021A) +#define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS)0xC000021B) +#define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS)0xC000021C) +#define STATUS_VDM_HARD_ERROR ((NTSTATUS)0xC000021D) +#define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS)0xC000021E) +#define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS)0xC000021F) +#define STATUS_MAPPED_ALIGNMENT ((NTSTATUS)0xC0000220) +#define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS)0xC0000221) +#define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS)0xC0000222) +#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS)0xC0000223) +#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224) +#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225) +#define STATUS_NOT_TINY_STREAM ((NTSTATUS)0xC0000226) +#define STATUS_RECOVERY_FAILURE ((NTSTATUS)0xC0000227) +#define STATUS_STACK_OVERFLOW_READ ((NTSTATUS)0xC0000228) +#define STATUS_FAIL_CHECK ((NTSTATUS)0xC0000229) +#define STATUS_DUPLICATE_OBJECTID ((NTSTATUS)0xC000022A) +#define STATUS_OBJECTID_EXISTS ((NTSTATUS)0xC000022B) +#define STATUS_CONVERT_TO_LARGE ((NTSTATUS)0xC000022C) +#define STATUS_RETRY ((NTSTATUS)0xC000022D) +#define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS)0xC000022E) +#define STATUS_ALLOCATE_BUCKET ((NTSTATUS)0xC000022F) +#define STATUS_PROPSET_NOT_FOUND ((NTSTATUS)0xC0000230) +#define STATUS_MARSHALL_OVERFLOW ((NTSTATUS)0xC0000231) +#define STATUS_INVALID_VARIANT ((NTSTATUS)0xC0000232) +#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS)0xC0000233) +#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234) +#define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xC0000235) +#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236) +#define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS)0xC0000237) +#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000238) +#define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS)0xC0000239) +#define STATUS_CONNECTION_INVALID ((NTSTATUS)0xC000023A) +#define STATUS_CONNECTION_ACTIVE ((NTSTATUS)0xC000023B) +#define STATUS_NETWORK_UNREACHABLE ((NTSTATUS)0xC000023C) +#define STATUS_HOST_UNREACHABLE ((NTSTATUS)0xC000023D) +#define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS)0xC000023E) +#define STATUS_PORT_UNREACHABLE ((NTSTATUS)0xC000023F) +#define STATUS_REQUEST_ABORTED ((NTSTATUS)0xC0000240) +#define STATUS_CONNECTION_ABORTED ((NTSTATUS)0xC0000241) +#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242) +#define STATUS_USER_MAPPED_FILE ((NTSTATUS)0xC0000243) +#define STATUS_AUDIT_FAILED ((NTSTATUS)0xC0000244) +#define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS)0xC0000245) +#define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS)0xC0000246) +#define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS)0xC0000247) +#define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS)0xC0000248) +#define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS)0xC0000249) +#define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS)0xC0000250) +#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS)0xC0000251) +#define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS)0xC0000252) +#define STATUS_LPC_REPLY_LOST ((NTSTATUS)0xC0000253) +#define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS)0xC0000254) +#define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS)0xC0000255) +#define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS)0xC0000256) +#define STATUS_PATH_NOT_COVERED ((NTSTATUS)0xC0000257) +#define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS)0xC0000258) +#define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS)0xC0000259) +#define STATUS_PWD_TOO_SHORT ((NTSTATUS)0xC000025A) +#define STATUS_PWD_TOO_RECENT ((NTSTATUS)0xC000025B) +#define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS)0xC000025C) +#define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS)0xC000025E) +#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xC000025F) +#define STATUS_INVALID_HW_PROFILE ((NTSTATUS)0xC0000260) +#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS)0xC0000261) +#define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000262) +#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000263) +#define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS)0xC0000264) +#define STATUS_TOO_MANY_LINKS ((NTSTATUS)0xC0000265) +#define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS)0xC0000266) +#define STATUS_FILE_IS_OFFLINE ((NTSTATUS)0xC0000267) +#define STATUS_EVALUATION_EXPIRATION ((NTSTATUS)0xC0000268) +#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS)0xC0000269) +#define STATUS_LICENSE_VIOLATION ((NTSTATUS)0xC000026A) +#define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS)0xC000026B) +#define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS)0xC000026C) +#define STATUS_DFS_UNAVAILABLE ((NTSTATUS)0xC000026D) +#define STATUS_VOLUME_DISMOUNTED ((NTSTATUS)0xC000026E) +#define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS)0xC000026F) +#define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000270) +#define STATUS_VALIDATE_CONTINUE ((NTSTATUS)0xC0000271) +#define STATUS_NO_MATCH ((NTSTATUS)0xC0000272) +#define STATUS_NO_MORE_MATCHES ((NTSTATUS)0xC0000273) +#define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS)0xC0000275) +#define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS)0xC0000276) +#define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS)0xC0000277) +#define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS)0xC0000278) +#define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS)0xC0000279) +#define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000280) +#define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS)0xC0000281) +#define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS)0xC0000282) +#define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS)0xC0000283) +#define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS)0xC0000284) +#define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS)0xC0000285) +#define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS)0xC0000286) +#define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS)0xC0000287) +#define STATUS_ENCRYPTION_FAILED ((NTSTATUS)0xC000028A) +#define STATUS_DECRYPTION_FAILED ((NTSTATUS)0xC000028B) +#define STATUS_RANGE_NOT_FOUND ((NTSTATUS)0xC000028C) +#define STATUS_NO_RECOVERY_POLICY ((NTSTATUS)0xC000028D) +#define STATUS_NO_EFS ((NTSTATUS)0xC000028E) +#define STATUS_WRONG_EFS ((NTSTATUS)0xC000028F) +#define STATUS_NO_USER_KEYS ((NTSTATUS)0xC0000290) +#define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS)0xC0000291) +#define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS)0xC0000292) +#define STATUS_FILE_ENCRYPTED ((NTSTATUS)0xC0000293) +#define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS)0xC0000295) +#define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS)0xC0000296) +#define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS)0xC0000297) +#define STATUS_WMI_TRY_AGAIN ((NTSTATUS)0xC0000298) +#define STATUS_SHARED_POLICY ((NTSTATUS)0xC0000299) +#define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS)0xC000029A) +#define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS)0xC000029B) +#define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS)0xC000029C) +#define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS)0xC000029D) +#define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS)0xC000029E) +#define STATUS_NO_TRACKING_SERVICE ((NTSTATUS)0xC000029F) +#define STATUS_SERVER_SID_MISMATCH ((NTSTATUS)0xC00002A0) +#define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS)0xC00002A1) +#define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS)0xC00002A2) +#define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS)0xC00002A3) +#define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS)0xC00002A4) +#define STATUS_DS_BUSY ((NTSTATUS)0xC00002A5) +#define STATUS_DS_UNAVAILABLE ((NTSTATUS)0xC00002A6) +#define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS)0xC00002A7) +#define STATUS_DS_NO_MORE_RIDS ((NTSTATUS)0xC00002A8) +#define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS)0xC00002A9) +#define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS)0xC00002AA) +#define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS)0xC00002AB) +#define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS)0xC00002AC) +#define STATUS_DS_CANT_ON_RDN ((NTSTATUS)0xC00002AD) +#define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS)0xC00002AE) +#define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS)0xC00002AF) +#define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS)0xC00002B0) +#define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS)0xC00002B1) +#define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS)0xC00002B2) +#define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS)0xC00002B3) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5) +#define STATUS_DEVICE_REMOVED ((NTSTATUS)0xC00002B6) +#define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS)0xC00002B7) +#define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS)0xC00002B8) +#define STATUS_NOINTERFACE ((NTSTATUS)0xC00002B9) +#define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS)0xC00002C1) +#define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS)0xC00002C2) +#define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS)0xC00002C3) +#define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS)0xC00002C4) +#define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS)0xC00002C5) +#define STATUS_WMI_READ_ONLY ((NTSTATUS)0xC00002C6) +#define STATUS_WMI_SET_FAILURE ((NTSTATUS)0xC00002C7) +#define STATUS_COMMITMENT_MINIMUM ((NTSTATUS)0xC00002C8) +#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9) +#define STATUS_TRANSPORT_FULL ((NTSTATUS)0xC00002CA) +#define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002CB) +#define STATUS_ONLY_IF_CONNECTED ((NTSTATUS)0xC00002CC) +#define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS)0xC00002CD) +#define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS)0xC00002CE) +#define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS)0xC00002CF) +#define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS)0xC00002D0) +#define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS)0xC00002D1) +#define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS)0xC00002D2) +#define STATUS_POWER_STATE_INVALID ((NTSTATUS)0xC00002D3) +#define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS)0xC00002D4) +#define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D5) +#define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS)0xC00002D6) +#define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D7) +#define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC00002D8) +#define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS)0xC00002D9) +#define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS)0xC00002DA) +#define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS)0xC00002DB) +#define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS)0xC00002DC) +#define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS)0xC00002DD) +#define STATUS_INSUFFICIENT_POWER ((NTSTATUS)0xC00002DE) +#define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS)0xC00002DF) +#define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS)0xC00002E0) +#define STATUS_DS_CANT_START ((NTSTATUS)0xC00002E1) +#define STATUS_DS_INIT_FAILURE ((NTSTATUS)0xC00002E2) +#define STATUS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002E3) +#define STATUS_DS_GC_REQUIRED ((NTSTATUS)0xC00002E4) +#define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS)0xC00002E5) +#define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS)0xC00002E6) +#define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS)0xC00002E7) +#define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS)0xC00002E8) +#define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS)0xC00002E9) +#define STATUS_CANNOT_MAKE ((NTSTATUS)0xC00002EA) +#define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS)0xC00002EB) +#define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002EC) +#define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS)0xC00002ED) +#define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS)0xC00002EE) +#define STATUS_NO_TGT_REPLY ((NTSTATUS)0xC00002EF) +#define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS)0xC00002F0) +#define STATUS_NO_IP_ADDRESSES ((NTSTATUS)0xC00002F1) +#define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS)0xC00002F2) +#define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS)0xC00002F3) +#define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS)0xC00002F4) +#define STATUS_MUST_BE_KDC ((NTSTATUS)0xC00002F5) +#define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS)0xC00002F6) +#define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS)0xC00002F7) +#define STATUS_NO_PA_DATA ((NTSTATUS)0xC00002F8) +#define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS)0xC00002F9) +#define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS)0xC00002FA) +#define STATUS_KDC_INVALID_REQUEST ((NTSTATUS)0xC00002FB) +#define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS)0xC00002FC) +#define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS)0xC00002FD) +#define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FE) +#define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS)0xC00002FF) +#define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS)0xC0000300) +#define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS)0xC0000301) +#define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS)0xC0000302) +#define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS)0xC0000303) +#define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS)0xC0000304) +#define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS)0xC0000305) +#define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS)0xC0000306) +#define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS)0xC0000307) +#define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS)0xC0000308) +#define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS)0xC0000309) +#define STATUS_CSS_REGION_MISMATCH ((NTSTATUS)0xC000030A) +#define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS)0xC000030B) +#define STATUS_PKINIT_FAILURE ((NTSTATUS)0xC0000320) +#define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS)0xC0000321) +#define STATUS_NO_KERB_KEY ((NTSTATUS)0xC0000322) +#define STATUS_HOST_DOWN ((NTSTATUS)0xC0000350) +#define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS)0xC0000351) +#define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS)0xC0000352) +#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353) +#define STATUS_DEBUGGER_INACTIVE ((NTSTATUS)0xC0000354) +#define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS)0xC0000355) +#define STATUS_AUDITING_DISABLED ((NTSTATUS)0xC0000356) +#define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS)0xC0000357) +#define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS)0xC0000358) +#define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS)0xC0000359) +#define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS)0xC000035A) +#define STATUS_BAD_BINDINGS ((NTSTATUS)0xC000035B) +#define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS)0xC000035C) +#define STATUS_APPHELP_BLOCK ((NTSTATUS)0xC000035D) +#define STATUS_ALL_SIDS_FILTERED ((NTSTATUS)0xC000035E) +#define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS)0xC000035F) +#define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS)0xC0000361) +#define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS)0xC0000362) +#define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS)0xC0000363) +#define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS)0xC0000364) +#define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS)0xC0000365) +#define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS)0xC0000366) +#define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS)0x00000367) +#define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS)0xC0000368) +#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS)0xC0000369) +#define STATUS_MCA_OCCURED ((NTSTATUS)0xC000036A) +#define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS)0xC000036B) +#define STATUS_DRIVER_BLOCKED ((NTSTATUS)0xC000036C) +#define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS)0xC000036D) +#define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS)0xC000036E) +#define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS)0xC000036F) +#define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS)0xC0000380) +#define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS)0xC0000381) +#define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS)0xC0000382) +#define STATUS_SMARTCARD_NO_CARD ((NTSTATUS)0xC0000383) +#define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS)0xC0000384) +#define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS)0xC0000385) +#define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS)0xC0000386) +#define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS)0xC0000387) +#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388) +#define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS)0xC0000389) +#define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS)0xC000038A) +#define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS)0xC000038B) +#define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038C) +#define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038D) +#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038E) +#define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS)0xC000038F) +#define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS)0xC0000401) +#define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS)0xC0000402) +#define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS)0xC0000403) +#define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS)0xC0000404) +#define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS)0xC0000405) +#define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS)0xC0000406) +#define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS)0xC0000407) +#define STATUS_USER2USER_REQUIRED ((NTSTATUS)0xC0000408) +#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409) +#define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS)0xC000040A) +#define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS)0xC000040B) +#define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS)0xC000040C) +#define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS)0xC000040D) +#define STATUS_KDC_CERT_EXPIRED ((NTSTATUS)0xC000040E) +#define STATUS_KDC_CERT_REVOKED ((NTSTATUS)0xC000040F) +#define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS)0xC0000410) +#define STATUS_HIBERNATION_FAILURE ((NTSTATUS)0xC0000411) +#define STATUS_DELAY_LOAD_FAILED ((NTSTATUS)0xC0000412) +#define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) +#define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) +#define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) +#define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS)0xC0000417) +#define STATUS_ASSERTION_FAILURE ((NTSTATUS)0xC0000420L) +#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423) +#define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898) + +#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001) +#define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002) +#define RPC_NT_INVALID_BINDING ((NTSTATUS)0xC0020003) +#define RPC_NT_PROTSEQ_NOT_SUPPORTED ((NTSTATUS)0xC0020004) +#define RPC_NT_INVALID_RPC_PROTSEQ ((NTSTATUS)0xC0020005) +#define RPC_NT_INVALID_STRING_UUID ((NTSTATUS)0xC0020006) +#define RPC_NT_INVALID_ENDPOINT_FORMAT ((NTSTATUS)0xC0020007) +#define RPC_NT_INVALID_NET_ADDR ((NTSTATUS)0xC0020008) +#define RPC_NT_NO_ENDPOINT_FOUND ((NTSTATUS)0xC0020009) +#define RPC_NT_INVALID_TIMEOUT ((NTSTATUS)0xC002000A) +#define RPC_NT_OBJECT_NOT_FOUND ((NTSTATUS)0xC002000B) +#define RPC_NT_ALREADY_REGISTERED ((NTSTATUS)0xC002000C) +#define RPC_NT_TYPE_ALREADY_REGISTERED ((NTSTATUS)0xC002000D) +#define RPC_NT_ALREADY_LISTENING ((NTSTATUS)0xC002000E) +#define RPC_NT_NO_PROTSEQS_REGISTERED ((NTSTATUS)0xC002000F) +#define RPC_NT_NOT_LISTENING ((NTSTATUS)0xC0020010) +#define RPC_NT_UNKNOWN_MGR_TYPE ((NTSTATUS)0xC0020011) +#define RPC_NT_UNKNOWN_IF ((NTSTATUS)0xC0020012) +#define RPC_NT_NO_BINDINGS ((NTSTATUS)0xC0020013) +#define RPC_NT_NO_PROTSEQS ((NTSTATUS)0xC0020014) +#define RPC_NT_CANT_CREATE_ENDPOINT ((NTSTATUS)0xC0020015) +#define RPC_NT_OUT_OF_RESOURCES ((NTSTATUS)0xC0020016) +#define RPC_NT_SERVER_UNAVAILABLE ((NTSTATUS)0xC0020017) +#define RPC_NT_SERVER_TOO_BUSY ((NTSTATUS)0xC0020018) +#define RPC_NT_INVALID_NETWORK_OPTIONS ((NTSTATUS)0xC0020019) +#define RPC_NT_NO_CALL_ACTIVE ((NTSTATUS)0xC002001A) +#define RPC_NT_CALL_FAILED ((NTSTATUS)0xC002001B) +#define RPC_NT_CALL_FAILED_DNE ((NTSTATUS)0xC002001C) +#define RPC_NT_PROTOCOL_ERROR ((NTSTATUS)0xC002001D) +#define RPC_NT_UNSUPPORTED_TRANS_SYN ((NTSTATUS)0xC002001F) +#define RPC_NT_UNSUPPORTED_TYPE ((NTSTATUS)0xC0020021) +#define RPC_NT_INVALID_TAG ((NTSTATUS)0xC0020022) +#define RPC_NT_INVALID_BOUND ((NTSTATUS)0xC0020023) +#define RPC_NT_NO_ENTRY_NAME ((NTSTATUS)0xC0020024) +#define RPC_NT_INVALID_NAME_SYNTAX ((NTSTATUS)0xC0020025) +#define RPC_NT_UNSUPPORTED_NAME_SYNTAX ((NTSTATUS)0xC0020026) +#define RPC_NT_UUID_NO_ADDRESS ((NTSTATUS)0xC0020028) +#define RPC_NT_DUPLICATE_ENDPOINT ((NTSTATUS)0xC0020029) +#define RPC_NT_UNKNOWN_AUTHN_TYPE ((NTSTATUS)0xC002002A) +#define RPC_NT_MAX_CALLS_TOO_SMALL ((NTSTATUS)0xC002002B) +#define RPC_NT_STRING_TOO_LONG ((NTSTATUS)0xC002002C) +#define RPC_NT_PROTSEQ_NOT_FOUND ((NTSTATUS)0xC002002D) +#define RPC_NT_PROCNUM_OUT_OF_RANGE ((NTSTATUS)0xC002002E) +#define RPC_NT_BINDING_HAS_NO_AUTH ((NTSTATUS)0xC002002F) +#define RPC_NT_UNKNOWN_AUTHN_SERVICE ((NTSTATUS)0xC0020030) +#define RPC_NT_UNKNOWN_AUTHN_LEVEL ((NTSTATUS)0xC0020031) +#define RPC_NT_INVALID_AUTH_IDENTITY ((NTSTATUS)0xC0020032) +#define RPC_NT_UNKNOWN_AUTHZ_SERVICE ((NTSTATUS)0xC0020033) +#define EPT_NT_INVALID_ENTRY ((NTSTATUS)0xC0020034) +#define EPT_NT_CANT_PERFORM_OP ((NTSTATUS)0xC0020035) +#define EPT_NT_NOT_REGISTERED ((NTSTATUS)0xC0020036) +#define RPC_NT_NOTHING_TO_EXPORT ((NTSTATUS)0xC0020037) +#define RPC_NT_INCOMPLETE_NAME ((NTSTATUS)0xC0020038) +#define RPC_NT_INVALID_VERS_OPTION ((NTSTATUS)0xC0020039) +#define RPC_NT_NO_MORE_MEMBERS ((NTSTATUS)0xC002003A) +#define RPC_NT_NOT_ALL_OBJS_UNEXPORTED ((NTSTATUS)0xC002003B) +#define RPC_NT_INTERFACE_NOT_FOUND ((NTSTATUS)0xC002003C) +#define RPC_NT_ENTRY_ALREADY_EXISTS ((NTSTATUS)0xC002003D) +#define RPC_NT_ENTRY_NOT_FOUND ((NTSTATUS)0xC002003E) +#define RPC_NT_NAME_SERVICE_UNAVAILABLE ((NTSTATUS)0xC002003F) +#define RPC_NT_INVALID_NAF_ID ((NTSTATUS)0xC0020040) +#define RPC_NT_CANNOT_SUPPORT ((NTSTATUS)0xC0020041) +#define RPC_NT_NO_CONTEXT_AVAILABLE ((NTSTATUS)0xC0020042) +#define RPC_NT_INTERNAL_ERROR ((NTSTATUS)0xC0020043) +#define RPC_NT_ZERO_DIVIDE ((NTSTATUS)0xC0020044) +#define RPC_NT_ADDRESS_ERROR ((NTSTATUS)0xC0020045) +#define RPC_NT_FP_DIV_ZERO ((NTSTATUS)0xC0020046) +#define RPC_NT_FP_UNDERFLOW ((NTSTATUS)0xC0020047) +#define RPC_NT_FP_OVERFLOW ((NTSTATUS)0xC0020048) +#define RPC_NT_CALL_IN_PROGRESS ((NTSTATUS)0xC0020049) +#define RPC_NT_NO_MORE_BINDINGS ((NTSTATUS)0xC002004A) +#define RPC_NT_GROUP_MEMBER_NOT_FOUND ((NTSTATUS)0xC002004B) +#define EPT_NT_CANT_CREATE ((NTSTATUS)0xC002004C) +#define RPC_NT_INVALID_OBJECT ((NTSTATUS)0xC002004D) +#define RPC_NT_NO_INTERFACES ((NTSTATUS)0xC002004F) +#define RPC_NT_CALL_CANCELLED ((NTSTATUS)0xC0020050) +#define RPC_NT_BINDING_INCOMPLETE ((NTSTATUS)0xC0020051) +#define RPC_NT_COMM_FAILURE ((NTSTATUS)0xC0020052) +#define RPC_NT_UNSUPPORTED_AUTHN_LEVEL ((NTSTATUS)0xC0020053) +#define RPC_NT_NO_PRINC_NAME ((NTSTATUS)0xC0020054) +#define RPC_NT_NOT_RPC_ERROR ((NTSTATUS)0xC0020055) +#define RPC_NT_SEC_PKG_ERROR ((NTSTATUS)0xC0020057) +#define RPC_NT_NOT_CANCELLED ((NTSTATUS)0xC0020058) +#define RPC_NT_INVALID_ASYNC_HANDLE ((NTSTATUS)0xC0020062) +#define RPC_NT_INVALID_ASYNC_CALL ((NTSTATUS)0xC0020063) + +#define RPC_NT_NO_MORE_ENTRIES ((NTSTATUS)0xC0030001) +#define RPC_NT_SS_CHAR_TRANS_OPEN_FAIL ((NTSTATUS)0xC0030002) +#define RPC_NT_SS_CHAR_TRANS_SHORT_FILE ((NTSTATUS)0xC0030003) +#define RPC_NT_SS_IN_NULL_CONTEXT ((NTSTATUS)0xC0030004) +#define RPC_NT_SS_CONTEXT_MISMATCH ((NTSTATUS)0xC0030005) +#define RPC_NT_SS_CONTEXT_DAMAGED ((NTSTATUS)0xC0030006) +#define RPC_NT_SS_HANDLES_MISMATCH ((NTSTATUS)0xC0030007) +#define RPC_NT_SS_CANNOT_GET_CALL_HANDLE ((NTSTATUS)0xC0030008) +#define RPC_NT_NULL_REF_POINTER ((NTSTATUS)0xC0030009) +#define RPC_NT_ENUM_VALUE_OUT_OF_RANGE ((NTSTATUS)0xC003000A) +#define RPC_NT_BYTE_COUNT_TOO_SMALL ((NTSTATUS)0xC003000B) +#define RPC_NT_BAD_STUB_DATA ((NTSTATUS)0xC003000C) +#define RPC_NT_INVALID_ES_ACTION ((NTSTATUS)0xC0030059) +#define RPC_NT_WRONG_ES_VERSION ((NTSTATUS)0xC003005A) +#define RPC_NT_WRONG_STUB_VERSION ((NTSTATUS)0xC003005B) +#define RPC_NT_INVALID_PIPE_OBJECT ((NTSTATUS)0xC003005C) +#define RPC_NT_INVALID_PIPE_OPERATION ((NTSTATUS)0xC003005D) +#define RPC_NT_WRONG_PIPE_VERSION ((NTSTATUS)0xC003005E) +#define RPC_NT_PIPE_CLOSED ((NTSTATUS)0xC003005F) +#define RPC_NT_PIPE_DISCIPLINE_ERROR ((NTSTATUS)0xC0030060) +#define RPC_NT_PIPE_EMPTY ((NTSTATUS)0xC0030061) + +#define STATUS_PNP_BAD_MPS_TABLE ((NTSTATUS)0xC0040035) +#define STATUS_PNP_TRANSLATION_FAILED ((NTSTATUS)0xC0040036) +#define STATUS_PNP_IRQ_TRANSLATION_FAILED ((NTSTATUS)0xC0040037) +#define STATUS_PNP_INVALID_ID ((NTSTATUS)0xC0040038) + +#define STATUS_ACPI_INVALID_OPCODE ((NTSTATUS)0xC0140001L) +#define STATUS_ACPI_STACK_OVERFLOW ((NTSTATUS)0xC0140002L) +#define STATUS_ACPI_ASSERT_FAILED ((NTSTATUS)0xC0140003L) +#define STATUS_ACPI_INVALID_INDEX ((NTSTATUS)0xC0140004L) +#define STATUS_ACPI_INVALID_ARGUMENT ((NTSTATUS)0xC0140005L) +#define STATUS_ACPI_FATAL ((NTSTATUS)0xC0140006L) +#define STATUS_ACPI_INVALID_SUPERNAME ((NTSTATUS)0xC0140007L) +#define STATUS_ACPI_INVALID_ARGTYPE ((NTSTATUS)0xC0140008L) +#define STATUS_ACPI_INVALID_OBJTYPE ((NTSTATUS)0xC0140009L) +#define STATUS_ACPI_INVALID_TARGETTYPE ((NTSTATUS)0xC014000AL) +#define STATUS_ACPI_INCORRECT_ARGUMENT_COUNT ((NTSTATUS)0xC014000BL) +#define STATUS_ACPI_ADDRESS_NOT_MAPPED ((NTSTATUS)0xC014000CL) +#define STATUS_ACPI_INVALID_EVENTTYPE ((NTSTATUS)0xC014000DL) +#define STATUS_ACPI_HANDLER_COLLISION ((NTSTATUS)0xC014000EL) +#define STATUS_ACPI_INVALID_DATA ((NTSTATUS)0xC014000FL) +#define STATUS_ACPI_INVALID_REGION ((NTSTATUS)0xC0140010L) +#define STATUS_ACPI_INVALID_ACCESS_SIZE ((NTSTATUS)0xC0140011L) +#define STATUS_ACPI_ACQUIRE_GLOBAL_LOCK ((NTSTATUS)0xC0140012L) +#define STATUS_ACPI_ALREADY_INITIALIZED ((NTSTATUS)0xC0140013L) +#define STATUS_ACPI_NOT_INITIALIZED ((NTSTATUS)0xC0140014L) +#define STATUS_ACPI_INVALID_MUTEX_LEVEL ((NTSTATUS)0xC0140015L) +#define STATUS_ACPI_MUTEX_NOT_OWNED ((NTSTATUS)0xC0140016L) +#define STATUS_ACPI_MUTEX_NOT_OWNER ((NTSTATUS)0xC0140017L) +#define STATUS_ACPI_RS_ACCESS ((NTSTATUS)0xC0140018L) +#define STATUS_ACPI_INVALID_TABLE ((NTSTATUS)0xC0140019L) +#define STATUS_ACPI_REG_HANDLER_FAILED ((NTSTATUS)0xC0140020L) +#define STATUS_ACPI_POWER_REQUEST_FAILED ((NTSTATUS)0xC0140021L) + +#define STATUS_CTX_WINSTATION_NAME_INVALID ((NTSTATUS)0xC00A0001) +#define STATUS_CTX_INVALID_PD ((NTSTATUS)0xC00A0002) +#define STATUS_CTX_PD_NOT_FOUND ((NTSTATUS)0xC00A0003) +#define STATUS_CTX_CLOSE_PENDING ((NTSTATUS)0xC00A0006) +#define STATUS_CTX_NO_OUTBUF ((NTSTATUS)0xC00A0007) +#define STATUS_CTX_MODEM_INF_NOT_FOUND ((NTSTATUS)0xC00A0008) +#define STATUS_CTX_INVALID_MODEMNAME ((NTSTATUS)0xC00A0009) +#define STATUS_CTX_RESPONSE_ERROR ((NTSTATUS)0xC00A000A) +#define STATUS_CTX_MODEM_RESPONSE_TIMEOUT ((NTSTATUS)0xC00A000B) +#define STATUS_CTX_MODEM_RESPONSE_NO_CARRIER ((NTSTATUS)0xC00A000C) +#define STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE ((NTSTATUS)0xC00A000D) +#define STATUS_CTX_MODEM_RESPONSE_BUSY ((NTSTATUS)0xC00A000E) +#define STATUS_CTX_MODEM_RESPONSE_VOICE ((NTSTATUS)0xC00A000F) +#define STATUS_CTX_TD_ERROR ((NTSTATUS)0xC00A0010) +#define STATUS_CTX_LICENSE_CLIENT_INVALID ((NTSTATUS)0xC00A0012) +#define STATUS_CTX_LICENSE_NOT_AVAILABLE ((NTSTATUS)0xC00A0013) +#define STATUS_CTX_LICENSE_EXPIRED ((NTSTATUS)0xC00A0014) +#define STATUS_CTX_WINSTATION_NOT_FOUND ((NTSTATUS)0xC00A0015) +#define STATUS_CTX_WINSTATION_NAME_COLLISION ((NTSTATUS)0xC00A0016) +#define STATUS_CTX_WINSTATION_BUSY ((NTSTATUS)0xC00A0017) +#define STATUS_CTX_BAD_VIDEO_MODE ((NTSTATUS)0xC00A0018) +#define STATUS_CTX_GRAPHICS_INVALID ((NTSTATUS)0xC00A0022) +#define STATUS_CTX_NOT_CONSOLE ((NTSTATUS)0xC00A0024) +#define STATUS_CTX_CLIENT_QUERY_TIMEOUT ((NTSTATUS)0xC00A0026) +#define STATUS_CTX_CONSOLE_DISCONNECT ((NTSTATUS)0xC00A0027) +#define STATUS_CTX_CONSOLE_CONNECT ((NTSTATUS)0xC00A0028) +#define STATUS_CTX_SHADOW_DENIED ((NTSTATUS)0xC00A002A) +#define STATUS_CTX_WINSTATION_ACCESS_DENIED ((NTSTATUS)0xC00A002B) +#define STATUS_CTX_INVALID_WD ((NTSTATUS)0xC00A002E) +#define STATUS_CTX_WD_NOT_FOUND ((NTSTATUS)0xC00A002F) +#define STATUS_CTX_SHADOW_INVALID ((NTSTATUS)0xC00A0030) +#define STATUS_CTX_SHADOW_DISABLED ((NTSTATUS)0xC00A0031) +#define STATUS_RDP_PROTOCOL_ERROR ((NTSTATUS)0xC00A0032) +#define STATUS_CTX_CLIENT_LICENSE_NOT_SET ((NTSTATUS)0xC00A0033) +#define STATUS_CTX_CLIENT_LICENSE_IN_USE ((NTSTATUS)0xC00A0034) +#define STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE ((NTSTATUS)0xC00A0035) +#define STATUS_CTX_SHADOW_NOT_RUNNING ((NTSTATUS)0xC00A0036) + +#define STATUS_CLUSTER_INVALID_NODE ((NTSTATUS)0xC0130001) +#define STATUS_CLUSTER_NODE_EXISTS ((NTSTATUS)0xC0130002) +#define STATUS_CLUSTER_JOIN_IN_PROGRESS ((NTSTATUS)0xC0130003) +#define STATUS_CLUSTER_NODE_NOT_FOUND ((NTSTATUS)0xC0130004) +#define STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND ((NTSTATUS)0xC0130005) +#define STATUS_CLUSTER_NETWORK_EXISTS ((NTSTATUS)0xC0130006) +#define STATUS_CLUSTER_NETWORK_NOT_FOUND ((NTSTATUS)0xC0130007) +#define STATUS_CLUSTER_NETINTERFACE_EXISTS ((NTSTATUS)0xC0130008) +#define STATUS_CLUSTER_NETINTERFACE_NOT_FOUND ((NTSTATUS)0xC0130009) +#define STATUS_CLUSTER_INVALID_REQUEST ((NTSTATUS)0xC013000A) +#define STATUS_CLUSTER_INVALID_NETWORK_PROVIDER ((NTSTATUS)0xC013000B) +#define STATUS_CLUSTER_NODE_DOWN ((NTSTATUS)0xC013000C) +#define STATUS_CLUSTER_NODE_UNREACHABLE ((NTSTATUS)0xC013000D) +#define STATUS_CLUSTER_NODE_NOT_MEMBER ((NTSTATUS)0xC013000E) +#define STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS ((NTSTATUS)0xC013000F) +#define STATUS_CLUSTER_INVALID_NETWORK ((NTSTATUS)0xC0130010) +#define STATUS_CLUSTER_NO_NET_ADAPTERS ((NTSTATUS)0xC0130011) +#define STATUS_CLUSTER_NODE_UP ((NTSTATUS)0xC0130012) +#define STATUS_CLUSTER_NODE_PAUSED ((NTSTATUS)0xC0130013) +#define STATUS_CLUSTER_NODE_NOT_PAUSED ((NTSTATUS)0xC0130014) +#define STATUS_CLUSTER_NO_SECURITY_CONTEXT ((NTSTATUS)0xC0130015) +#define STATUS_CLUSTER_NETWORK_NOT_INTERNAL ((NTSTATUS)0xC0130016) +#define STATUS_CLUSTER_POISONED ((NTSTATUS)0xC0130017) + +#define STATUS_SXS_SECTION_NOT_FOUND ((NTSTATUS)0xC0150001) +#define STATUS_SXS_CANT_GEN_ACTCTX ((NTSTATUS)0xC0150002) +#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT ((NTSTATUS)0xC0150003) +#define STATUS_SXS_ASSEMBLY_NOT_FOUND ((NTSTATUS)0xC0150004) +#define STATUS_SXS_MANIFEST_FORMAT_ERROR ((NTSTATUS)0xC0150005) +#define STATUS_SXS_MANIFEST_PARSE_ERROR ((NTSTATUS)0xC0150006) +#define STATUS_SXS_ACTIVATION_CONTEXT_DISABLED ((NTSTATUS)0xC0150007) +#define STATUS_SXS_KEY_NOT_FOUND ((NTSTATUS)0xC0150008) +#define STATUS_SXS_VERSION_CONFLICT ((NTSTATUS)0xC0150009) +#define STATUS_SXS_WRONG_SECTION_TYPE ((NTSTATUS)0xC015000A) +#define STATUS_SXS_THREAD_QUERIES_DISABLED ((NTSTATUS)0xC015000B) +#define STATUS_SXS_ASSEMBLY_MISSING ((NTSTATUS)0xC015000C) +#define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET ((NTSTATUS)0xC015000E) +#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000F) +#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010) +#define STATUS_SXS_MULTIPLE_DEACTIVATION ((NTSTATUS)0xC0150011) +#define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY ((NTSTATUS)0xC0150012) +#define STATUS_SXS_PROCESS_TERMINATION_REQUESTED ((NTSTATUS)0xC0150013) +#define STATUS_SXS_CORRUPT_ACTIVATION_STACK ((NTSTATUS)0xC0150014) +#define STATUS_SXS_CORRUPTION ((NTSTATUS)0xC0150015) +#define STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE ((NTSTATUS)0xC0150016) +#define STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME ((NTSTATUS)0xC0150017) +#define STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE ((NTSTATUS)0xC0150018) +#define STATUS_SXS_IDENTITY_PARSE_ERROR ((NTSTATUS)0xC0150019) +#define STATUS_SXS_COMPONENT_STORE_CORRUPT ((NTSTATUS)0xC015001A) +#define STATUS_SXS_FILE_HASH_MISMATCH ((NTSTATUS)0xC015001B) +#define STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT ((NTSTATUS)0xC015001C) +#define STATUS_SXS_IDENTITIES_DIFFERENT ((NTSTATUS)0xC015001D) +#define STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT ((NTSTATUS)0xC015001E) +#define STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY ((NTSTATUS)0xC015001F) +#define STATUS_ADVANCED_INSTALLER_FAILED ((NTSTATUS)0xC0150020) +#define STATUS_XML_ENCODING_MISMATCH ((NTSTATUS)0xC0150021) +#define STATUS_SXS_MANIFEST_TOO_BIG ((NTSTATUS)0xC0150022) +#define STATUS_SXS_SETTING_NOT_REGISTERED ((NTSTATUS)0xC0150023) +#define STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE ((NTSTATUS)0xC0150024) +#define STATUS_SXS_PRIMITIVE_INSTALLER_FAILED ((NTSTATUS)0xC0150025) +#define STATUS_GENERIC_COMMAND_FAILED ((NTSTATUS)0xC0150026) +#define STATUS_SXS_FILE_HASH_MISSING ((NTSTATUS)0xC0150027) + typedef struct _PEB PEB; typedef struct _PEB* PPEB; @@ -193,8 +1350,7 @@ typedef struct _IO_STATUS_BLOCK { NTSTATUS status; PVOID Pointer; - } DUMMYUNIONNAME; - + }; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; @@ -215,6 +1371,8 @@ WINPR_API NTSTATUS RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationStrin WINPR_API VOID RtlFreeUnicodeString(PUNICODE_STRING UnicodeString); +WINPR_API ULONG RtlNtStatusToDosError(NTSTATUS status); + WINPR_API VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes, PUNICODE_STRING ObjectName, ULONG Attributes, HANDLE RootDirectory, PSECURITY_DESCRIPTOR SecurityDescriptor); @@ -235,6 +1393,8 @@ WINPR_API NTSTATUS NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, WINPR_API NTSTATUS NtClose(HANDLE Handle); +WINPR_API NTSTATUS NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout); + #ifdef __cplusplus } #endif diff --git a/winpr/libwinpr/nt/nt.c b/winpr/libwinpr/nt/nt.c index d621639b7..5ce1afc58 100644 --- a/winpr/libwinpr/nt/nt.c +++ b/winpr/libwinpr/nt/nt.c @@ -298,6 +298,16 @@ VOID RtlFreeUnicodeString(PUNICODE_STRING UnicodeString) } } +/** + * RtlNtStatusToDosError function: + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680600/ + */ + +ULONG RtlNtStatusToDosError(NTSTATUS status) +{ + return status; +} + /** * InitializeObjectAttributes macro * http://msdn.microsoft.com/en-us/library/windows/hardware/ff547804/ @@ -363,5 +373,15 @@ NTSTATUS NtClose(HANDLE Handle) return 0; } +/** + * NtWaitForSingleObject function: + * http://msdn.microsoft.com/en-us/library/ms648412/ + */ + +NTSTATUS NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout) +{ + return 0; +} + #endif diff --git a/winpr/libwinpr/wtsapi/CMakeLists.txt b/winpr/libwinpr/wtsapi/CMakeLists.txt index 929f7b6e8..9befec840 100644 --- a/winpr/libwinpr/wtsapi/CMakeLists.txt +++ b/winpr/libwinpr/wtsapi/CMakeLists.txt @@ -31,9 +31,10 @@ add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") -if(WIN32) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} credui) -endif() +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-nt winpr-io winpr-synch) if(MONOLITHIC_BUILD) set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 94f9e35ff..600abe570 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -201,37 +201,151 @@ HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags) BOOL WTSVirtualChannelClose(HANDLE hChannelHandle) { + if (!hChannelHandle || (hChannelHandle == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* TODO: properly close handle */ + return TRUE; } BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead) { - return TRUE; + OVERLAPPED overlapped; + + if (!hChannelHandle || (hChannelHandle == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + overlapped.hEvent = 0; + overlapped.Offset = 0; + overlapped.OffsetHigh = 0; + + if (ReadFile(hChannelHandle, Buffer, BufferSize, pBytesRead, &overlapped)) + return TRUE; + + if (GetLastError() != ERROR_IO_PENDING) + return FALSE; + + if (!TimeOut) + { + CancelIo(hChannelHandle); + *pBytesRead = 0; + return TRUE; + } + + if (WaitForSingleObject(hChannelHandle, TimeOut) == WAIT_TIMEOUT) + { + CancelIo(hChannelHandle); + SetLastError(ERROR_IO_INCOMPLETE); + return FALSE; + } + + return GetOverlappedResult(hChannelHandle, &overlapped, pBytesRead, 0); } BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten) { + OVERLAPPED overlapped; + + if (!hChannelHandle || (hChannelHandle == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + overlapped.hEvent = 0; + overlapped.Offset = 0; + overlapped.OffsetHigh = 0; + + if (WriteFile(hChannelHandle, Buffer, Length, pBytesWritten, &overlapped)) + return TRUE; + + if (GetLastError() == ERROR_IO_PENDING) + return GetOverlappedResult(hChannelHandle, &overlapped, pBytesWritten, 1); + + return FALSE; +} + +BOOL VirtualChannelIoctl(HANDLE hChannelHandle, ULONG IoControlCode) +{ + DWORD error; + NTSTATUS ntstatus; + IO_STATUS_BLOCK ioStatusBlock; + + if (!hChannelHandle || (hChannelHandle == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + ntstatus = NtDeviceIoControlFile(hChannelHandle, 0, 0, 0, &ioStatusBlock, IoControlCode, 0, 0, 0, 0); + + if (ntstatus == STATUS_PENDING) + { + ntstatus = NtWaitForSingleObject(hChannelHandle, 0, 0); + + if (ntstatus >= 0) + ntstatus = ioStatusBlock.status; + } + + if (ntstatus == STATUS_BUFFER_OVERFLOW) + { + ntstatus = STATUS_BUFFER_TOO_SMALL; + error = RtlNtStatusToDosError(ntstatus); + SetLastError(error); + return FALSE; + } + + if (ntstatus < 0) + { + error = RtlNtStatusToDosError(ntstatus); + SetLastError(error); + return FALSE; + } + return TRUE; } +#define FILE_DEVICE_TERMSRV 0x00000038 + BOOL WTSVirtualChannelPurgeInput(HANDLE hChannelHandle) { - return TRUE; + return VirtualChannelIoctl(hChannelHandle, (FILE_DEVICE_TERMSRV << 16) | 0x0107); } BOOL WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle) { - return TRUE; + return VirtualChannelIoctl(hChannelHandle, (FILE_DEVICE_TERMSRV << 16) | 0x010B); } BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned) { - return TRUE; + if (!hChannelHandle || (hChannelHandle == INVALID_HANDLE_VALUE)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (WtsVirtualClass == WTSVirtualFileHandle) + { + *ppBuffer = malloc(sizeof(void*)); + CopyMemory(*ppBuffer, &hChannelHandle, sizeof(void*)); + *pBytesReturned = sizeof(void*); + return TRUE; + } + + return FALSE; } VOID WTSFreeMemory(PVOID pMemory) { - + free(pMemory); } BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) From 8423fccbc2904236929fa4c7a9afabcf6982560c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 22 Aug 2013 22:36:37 -0400 Subject: [PATCH 023/202] libwinpr-pipe: add support for overlapped i/o with named pipes (synchronous, compatible implementation) --- CMakeLists.txt | 1 + config.h.in | 1 + winpr/libwinpr/file/file.c | 165 ++++++++++++++++++++++++++++----- winpr/libwinpr/io/io.c | 74 ++++++++++++--- winpr/libwinpr/pipe/pipe.c | 9 ++ winpr/libwinpr/pipe/pipe.h | 2 + winpr/libwinpr/wtsapi/wtsapi.c | 65 +++++++++++-- 7 files changed, 270 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a38dd3a19..4ca2f3475 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,6 +270,7 @@ if(NOT IOS AND NOT ANDROID) endif() if(UNIX OR CYGWIN) + check_include_files(sys/eventfd.h HAVE_AIO_H) check_include_files(sys/eventfd.h HAVE_EVENTFD_H) check_include_files(sys/timerfd.h HAVE_TIMERFD_H) set(X11_FEATURE_TYPE "RECOMMENDED") diff --git a/config.h.in b/config.h.in index 83b0abecb..bbbe36102 100755 --- a/config.h.in +++ b/config.h.in @@ -32,6 +32,7 @@ #cmakedefine HAVE_EVENTFD_H #cmakedefine HAVE_TIMERFD_H #cmakedefine HAVE_TM_GMTOFF +#cmakedefine HAVE_AIO_H /* Options */ diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index feaf66d25..48bfaeb69 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -124,6 +125,21 @@ * http://download.microsoft.com/download/4/3/8/43889780-8d45-4b2e-9d3a-c696a890309f/File%20System%20Behavior%20Overview.pdf */ +/** + * Asynchronous I/O - The GNU C Library: + * http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html + */ + +/** + * aio.h - asynchronous input and output: + * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/aio.h.html + */ + +/** + * Asynchronous I/O User Guide: + * http://code.google.com/p/kernel/wiki/AIOUserGuide + */ + #ifndef _WIN32 #ifdef HAVE_UNISTD_H @@ -142,6 +158,14 @@ #include #include +#ifdef HAVE_AIO_H +#undef HAVE_AIO_H /* disable for now, incomplete */ +#endif + +#ifdef HAVE_AIO_H +#include +#endif + #ifdef ANDROID #include #else @@ -184,6 +208,7 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, pNamedPipe->nOutBufferSize = 0; pNamedPipe->nInBufferSize = 0; pNamedPipe->nDefaultTimeOut = 0; + pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName); pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName); @@ -255,20 +280,66 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, pipe = (WINPR_NAMED_PIPE*) Object; - status = nNumberOfBytesToRead; - - if (pipe->clientfd != -1) - status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead); - else - return FALSE; - - if (status < 0) + if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) { - *lpNumberOfBytesRead = 0; - return FALSE; - } + status = nNumberOfBytesToRead; - *lpNumberOfBytesRead = status; + if (pipe->clientfd == -1) + return FALSE; + + status = read(pipe->clientfd, lpBuffer, nNumberOfBytesToRead); + + if (status < 0) + { + *lpNumberOfBytesRead = 0; + return FALSE; + } + + *lpNumberOfBytesRead = status; + } + else + { + /* Overlapped I/O */ + + if (!lpOverlapped) + return FALSE; + + if (pipe->clientfd == -1) + return FALSE; + + pipe->lpOverlapped = lpOverlapped; + +#ifdef HAVE_AIO_H + { + struct aiocb cb; + + ZeroMemory(&cb, sizeof(struct aiocb)); + cb.aio_nbytes = nNumberOfBytesToRead; + cb.aio_fildes = pipe->clientfd; + cb.aio_offset = lpOverlapped->Offset; + cb.aio_buf = lpBuffer; + + status = aio_read(&cb); + + printf("aio_read status: %d\n", status); + + if (status < 0) + { + return FALSE; + } + } +#else + + /* synchronous behavior */ + + lpOverlapped->Internal = 0; + lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToRead; + lpOverlapped->Pointer = (PVOID) lpBuffer; + + SetEvent(lpOverlapped->hEvent); + +#endif + } return TRUE; } @@ -317,20 +388,66 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, pipe = (WINPR_NAMED_PIPE*) Object; - status = nNumberOfBytesToWrite; - - if (pipe->clientfd != -1) - status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite); - else - return FALSE; - - if (status < 0) + if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) { - *lpNumberOfBytesWritten = 0; - return FALSE; - } + status = nNumberOfBytesToWrite; - *lpNumberOfBytesWritten = status; + if (pipe->clientfd == -1) + return FALSE; + + status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite); + + if (status < 0) + { + *lpNumberOfBytesWritten = 0; + return FALSE; + } + + *lpNumberOfBytesWritten = status; + } + else + { + /* Overlapped I/O */ + + if (!lpOverlapped) + return FALSE; + + if (pipe->clientfd == -1) + return FALSE; + + pipe->lpOverlapped = lpOverlapped; + +#ifdef HAVE_AIO_H + { + struct aiocb cb; + + ZeroMemory(&cb, sizeof(struct aiocb)); + cb.aio_nbytes = nNumberOfBytesToWrite; + cb.aio_fildes = pipe->clientfd; + cb.aio_offset = lpOverlapped->Offset; + cb.aio_buf = lpBuffer; + + status = aio_write(&cb); + + printf("aio_write status: %d\n", status); + + if (status < 0) + { + return FALSE; + } + } +#else + + /* synchronous behavior */ + + lpOverlapped->Internal = 1; + lpOverlapped->InternalHigh = (ULONG_PTR) nNumberOfBytesToWrite; + lpOverlapped->Pointer = (PVOID) lpBuffer; + + SetEvent(lpOverlapped->hEvent); + +#endif + } return TRUE; } diff --git a/winpr/libwinpr/io/io.c b/winpr/libwinpr/io/io.c index b319e6c77..bf6adaa9c 100644 --- a/winpr/libwinpr/io/io.c +++ b/winpr/libwinpr/io/io.c @@ -23,25 +23,69 @@ #include -/** - * api-ms-win-core-io-l1-1-1.dll: - * - * GetOverlappedResult - * GetOverlappedResultEx - * DeviceIoControl - * CreateIoCompletionPort - * GetQueuedCompletionStatus - * GetQueuedCompletionStatusEx - * PostQueuedCompletionStatus - * CancelIo - * CancelIoEx - * CancelSynchronousIo - */ - #ifndef _WIN32 +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "../handle/handle.h" + +#include "../pipe/pipe.h" + BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait) { + ULONG Type; + PVOID Object; + + if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) + return FALSE; + + else if (Type == HANDLE_TYPE_NAMED_PIPE) + { + int status; + DWORD request; + PVOID lpBuffer; + DWORD nNumberOfBytes; + WINPR_NAMED_PIPE* pipe; + + pipe = (WINPR_NAMED_PIPE*) Object; + + if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) + return FALSE; + + if (pipe->clientfd == -1) + return FALSE; + + lpBuffer = lpOverlapped->Pointer; + request = (DWORD) lpOverlapped->Internal; + nNumberOfBytes = (DWORD) lpOverlapped->InternalHigh; + + if (request == 0) + { + status = read(pipe->clientfd, lpBuffer, nNumberOfBytes); + } + else + { + status = write(pipe->clientfd, lpBuffer, nNumberOfBytes); + } + + if (status < 0) + { + *lpNumberOfBytesTransferred = 0; + return FALSE; + } + + *lpNumberOfBytesTransferred = status; + } + return TRUE; } diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 241f131b9..2345da32c 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -108,6 +108,7 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; + pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName); pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName); @@ -177,6 +178,14 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) pNamedPipe->clientfd = status; + if (pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) + { + if (!lpOverlapped) + return FALSE; + + SetEvent(lpOverlapped->hEvent); + } + return TRUE; } diff --git a/winpr/libwinpr/pipe/pipe.h b/winpr/libwinpr/pipe/pipe.h index 2c326a771..efc79989a 100644 --- a/winpr/libwinpr/pipe/pipe.h +++ b/winpr/libwinpr/pipe/pipe.h @@ -51,6 +51,8 @@ struct winpr_named_pipe DWORD nOutBufferSize; DWORD nInBufferSize; DWORD nDefaultTimeOut; + DWORD dwFlagsAndAttributes; + LPOVERLAPPED lpOverlapped; }; typedef struct winpr_named_pipe WINPR_NAMED_PIPE; diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 600abe570..8e8201f5d 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -32,11 +32,6 @@ #ifndef _WIN32 -BOOL WTSStopRemoteControlSession(ULONG LogonId) -{ - return TRUE; -} - BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) { return TRUE; @@ -47,6 +42,11 @@ BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, return TRUE; } +BOOL WTSStopRemoteControlSession(ULONG LogonId) +{ + return TRUE; +} + BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait) { return TRUE; @@ -191,11 +191,24 @@ BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags) HANDLE WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName) { - return NULL; + HANDLE handle = NULL; + + if (hServer != WTS_CURRENT_SERVER_HANDLE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + return handle; } HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags) { + HANDLE handle = NULL; + + if (!flags) + return WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, SessionId, pVirtualName); + return NULL; } @@ -375,12 +388,48 @@ BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken) BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries) { - return TRUE; + BOOL status = TRUE; + + switch (WTSTypeClass) + { + case WTSTypeProcessInfoLevel0: + break; + + case WTSTypeProcessInfoLevel1: + break; + + case WTSTypeSessionInfoLevel1: + break; + + default: + status = FALSE; + break; + } + + return status; } BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries) { - return TRUE; + BOOL status = TRUE; + + switch (WTSTypeClass) + { + case WTSTypeProcessInfoLevel0: + break; + + case WTSTypeProcessInfoLevel1: + break; + + case WTSTypeSessionInfoLevel1: + break; + + default: + status = FALSE; + break; + } + + return status; } BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount) From e429136c0c7364bdd4f6eb7ea26f07bdae13309f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 23 Aug 2013 00:06:22 -0400 Subject: [PATCH 024/202] libwinpr-wtsapi: started internal RPC stubs --- client/X11/CMakeLists.txt | 2 - winpr/include/winpr/wtsapi.h | 2 +- winpr/libwinpr/wtsapi/CMakeLists.txt | 4 +- winpr/libwinpr/wtsapi/wtsapi.c | 103 ++++++++-------- winpr/libwinpr/wtsapi/wtsrpc_c.c | 170 +++++++++++++++++++++++++++ winpr/libwinpr/wtsapi/wtsrpc_c.h | 76 ++++++++++++ 6 files changed, 303 insertions(+), 54 deletions(-) create mode 100644 winpr/libwinpr/wtsapi/wtsrpc_c.c create mode 100644 winpr/libwinpr/wtsapi/wtsrpc_c.h diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 907200733..3a8749c56 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -92,8 +92,6 @@ if(WITH_MANPAGES) MODULE freerdp MODULES freerdp-core freerdp-utils) - message(WARNING "GAD_LIBS: ${GAD_LIBS}") - target_link_libraries(generate_argument_docbook ${GAD_LIBS}) add_custom_command(OUTPUT xfreerdp.1 diff --git a/winpr/include/winpr/wtsapi.h b/winpr/include/winpr/wtsapi.h index 099fc3b2f..42f2b0101 100644 --- a/winpr/include/winpr/wtsapi.h +++ b/winpr/include/winpr/wtsapi.h @@ -930,8 +930,8 @@ WINPR_API BOOL WTSStopRemoteControlSession(ULONG LogonId); WINPR_API BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); WINPR_API BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); -WINPR_API BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait); WINPR_API BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait); +WINPR_API BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait); WINPR_API BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount); WINPR_API BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount); diff --git a/winpr/libwinpr/wtsapi/CMakeLists.txt b/winpr/libwinpr/wtsapi/CMakeLists.txt index 9befec840..e7f3443dc 100644 --- a/winpr/libwinpr/wtsapi/CMakeLists.txt +++ b/winpr/libwinpr/wtsapi/CMakeLists.txt @@ -19,7 +19,9 @@ set(MODULE_NAME "winpr-wtsapi") set(MODULE_PREFIX "WINPR_WTSAPI") set(${MODULE_PREFIX}_SRCS - wtsapi.c) + wtsapi.c + wtsrpc_c.c + wtsrpc_c.h) if(MSVC AND (NOT MONOLITHIC_BUILD)) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 8e8201f5d..56e7bf5a3 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -32,9 +32,11 @@ #ifndef _WIN32 +#include "wtsrpc_c.h" + BOOL WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) { - return TRUE; + return RpcStartRemoteControlSession(NULL, pTargetServerName, TargetLogonId, HotkeyVk, HotkeyModifiers); } BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) @@ -44,7 +46,12 @@ BOOL WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BOOL WTSStopRemoteControlSession(ULONG LogonId) { - return TRUE; + return RpcStopRemoteControlSession(NULL, LogonId); +} + +BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait) +{ + return RpcConnectSession(NULL, LogonId, TargetLogonId, pPassword, bWait); } BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait) @@ -52,14 +59,9 @@ BOOL WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL return TRUE; } -BOOL WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait) -{ - return TRUE; -} - BOOL WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount) { - return TRUE; + return RpcEnumerateServers(NULL, pDomainName, Reserved, Version, ppServerInfo, pCount); } BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA* ppServerInfo, DWORD* pCount) @@ -69,7 +71,7 @@ BOOL WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS HANDLE WTSOpenServerW(LPWSTR pServerName) { - return NULL; + return RpcOpenServer(NULL, pServerName); } HANDLE WTSOpenServerA(LPSTR pServerName) @@ -79,7 +81,7 @@ HANDLE WTSOpenServerA(LPSTR pServerName) HANDLE WTSOpenServerExW(LPWSTR pServerName) { - return NULL; + return RpcOpenServerEx(NULL, pServerName); } HANDLE WTSOpenServerExA(LPSTR pServerName) @@ -89,12 +91,12 @@ HANDLE WTSOpenServerExA(LPSTR pServerName) VOID WTSCloseServer(HANDLE hServer) { - + RpcCloseServer(NULL, hServer); } BOOL WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount) { - return TRUE; + return RpcEnumerateSessions(NULL, hServer, Reserved, Version, ppSessionInfo, pCount); } BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount) @@ -104,7 +106,7 @@ BOOL WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_S BOOL WTSEnumerateSessionsExW(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount) { - return TRUE; + return RpcEnumerateSessionsEx(NULL, hServer, pLevel, Filter, ppSessionInfo, pCount); } BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_SESSION_INFO_1A* ppSessionInfo, DWORD* pCount) @@ -114,7 +116,7 @@ BOOL WTSEnumerateSessionsExA(HANDLE hServer, DWORD* pLevel, DWORD Filter, PWTS_S BOOL WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) { - return TRUE; + return RpcEnumerateProcesses(NULL, hServer, Reserved, Version, ppProcessInfo, pCount); } BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount) @@ -124,12 +126,12 @@ BOOL WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_ BOOL WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode) { - return TRUE; + return RpcTerminateProcess(NULL, hServer, ProcessId, ExitCode); } BOOL WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) { - return TRUE; + return RpcQuerySessionInformation(NULL, hServer, SessionId, WTSInfoClass, ppBuffer, pBytesReturned); } BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPSTR* ppBuffer, DWORD* pBytesReturned) @@ -139,7 +141,7 @@ BOOL WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS BOOL WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) { - return TRUE; + return RpcQueryUserConfig(NULL, pServerName, pUserName, WTSConfigClass, ppBuffer, pBytesReturned); } BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR* ppBuffer, DWORD* pBytesReturned) @@ -149,7 +151,7 @@ BOOL WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WT BOOL WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength) { - return TRUE; + return RpcSetUserConfig(NULL, pServerName, pUserName, WTSConfigClass, pBuffer, DataLength); } BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength) @@ -160,7 +162,8 @@ BOOL WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSC BOOL WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait) { - return TRUE; + return RpcSendMessage(NULL, hServer, SessionId, pTitle, TitleLength, + pMessage, MessageLength, Style, Timeout, pResponse, bWait); } BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, @@ -171,17 +174,17 @@ BOOL WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleL BOOL WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait) { - return TRUE; + return RpcDisconnectSession(NULL, hServer, SessionId, bWait); } BOOL WTSLogoffSession(HANDLE hServer, DWORD SessionId, BOOL bWait) { - return TRUE; + return RpcLogoffSession(NULL, hServer, SessionId, bWait); } BOOL WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag) { - return TRUE; + return RpcShutdownSystem(NULL, hServer, ShutdownFlag); } BOOL WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags) @@ -361,31 +364,6 @@ VOID WTSFreeMemory(PVOID pMemory) free(pMemory); } -BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) -{ - return TRUE; -} - -BOOL WTSUnRegisterSessionNotification(HWND hWnd) -{ - return TRUE; -} - -BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags) -{ - return TRUE; -} - -BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd) -{ - return TRUE; -} - -BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken) -{ - return TRUE; -} - BOOL WTSFreeMemoryExW(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOfEntries) { BOOL status = TRUE; @@ -432,6 +410,31 @@ BOOL WTSFreeMemoryExA(WTS_TYPE_CLASS WTSTypeClass, PVOID pMemory, ULONG NumberOf return status; } +BOOL WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) +{ + return RpcRegisterSessionNotification(NULL, hWnd, dwFlags); +} + +BOOL WTSUnRegisterSessionNotification(HWND hWnd) +{ + return RpcUnRegisterSessionNotification(NULL, hWnd); +} + +BOOL WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags) +{ + return RpcRegisterSessionNotificationEx(NULL, hServer, hWnd, dwFlags); +} + +BOOL WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd) +{ + return RpcUnRegisterSessionNotificationEx(NULL, hServer, hWnd); +} + +BOOL WTSQueryUserToken(ULONG SessionId, PHANDLE phToken) +{ + return TRUE; +} + BOOL WTSEnumerateProcessesExW(HANDLE hServer, DWORD* pLevel, DWORD SessionId, LPWSTR* ppProcessInfo, DWORD* pCount) { return TRUE; @@ -504,17 +507,17 @@ BOOL WTSGetListenerSecurityA(HANDLE hServer, PVOID pReserved, DWORD Reserved, BOOL WTSEnableChildSessions(BOOL bEnable) { - return TRUE; + return RpcEnableChildSessions(NULL, bEnable); } BOOL WTSIsChildSessionsEnabled(PBOOL pbEnabled) { - return TRUE; + return RpcIsChildSessionsEnabled(NULL, pbEnabled); } BOOL WTSGetChildSessionId(PULONG pSessionId) { - return TRUE; + return RpcGetChildSessionId(NULL, pSessionId); } #endif diff --git a/winpr/libwinpr/wtsapi/wtsrpc_c.c b/winpr/libwinpr/wtsapi/wtsrpc_c.c new file mode 100644 index 000000000..18b4a05a9 --- /dev/null +++ b/winpr/libwinpr/wtsapi/wtsrpc_c.c @@ -0,0 +1,170 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Terminal Services API + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#ifndef _WIN32 + +#include "wtsrpc_c.h" + +/** + * RPC Client Stubs + */ + +BOOL RpcStartRemoteControlSession(void* context, LPWSTR pTargetServerName, + ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) +{ + return TRUE; +} + +BOOL RpcStopRemoteControlSession(void* context, ULONG LogonId) +{ + return TRUE; +} + +BOOL RpcConnectSession(void* context, ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait) +{ + return TRUE; +} + +BOOL RpcEnumerateServers(void* context, LPWSTR pDomainName, DWORD Reserved, + DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount) +{ + return TRUE; +} + +HANDLE RpcOpenServer(void* context, LPWSTR pServerName) +{ + return NULL; +} + +HANDLE RpcOpenServerEx(void* context, LPWSTR pServerName) +{ + return NULL; +} + +VOID RpcCloseServer(void* context, HANDLE hServer) +{ + +} + +BOOL RpcEnumerateSessions(void* context, HANDLE hServer, DWORD Reserved, + DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL RpcEnumerateSessionsEx(void* context, HANDLE hServer, DWORD* pLevel, + DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL RpcEnumerateProcesses(void* context, HANDLE hServer, DWORD Reserved, + DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) +{ + return TRUE; +} + +BOOL RpcTerminateProcess(void* context, HANDLE hServer, DWORD ProcessId, DWORD ExitCode) +{ + return TRUE; +} + +BOOL RpcQuerySessionInformation(void* context, HANDLE hServer, DWORD SessionId, + WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL RpcQueryUserConfig(void* context, LPWSTR pServerName, LPWSTR pUserName, + WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned) +{ + return TRUE; +} + +BOOL RpcSetUserConfig(void* context, LPWSTR pServerName, LPWSTR pUserName, + WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength) +{ + return TRUE; +} + +BOOL RpcSendMessage(void* context, HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, + LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait) +{ + return TRUE; +} + +BOOL RpcDisconnectSession(void* context, HANDLE hServer, DWORD SessionId, BOOL bWait) +{ + return TRUE; +} + +BOOL RpcLogoffSession(void* context, HANDLE hServer, DWORD SessionId, BOOL bWait) +{ + return TRUE; +} + +BOOL RpcShutdownSystem(void* context, HANDLE hServer, DWORD ShutdownFlag) +{ + return TRUE; +} + +BOOL RpcRegisterSessionNotification(void* context, HWND hWnd, DWORD dwFlags) +{ + return TRUE; +} + +BOOL RpcUnRegisterSessionNotification(void* context, HWND hWnd) +{ + return TRUE; +} + +BOOL RpcRegisterSessionNotificationEx(void* context, HANDLE hServer, HWND hWnd, DWORD dwFlags) +{ + return TRUE; +} + +BOOL RpcUnRegisterSessionNotificationEx(void* context, HANDLE hServer, HWND hWnd) +{ + return TRUE; +} + +BOOL RpcEnableChildSessions(void* context, BOOL bEnable) +{ + return TRUE; +} + +BOOL RpcIsChildSessionsEnabled(void* context, PBOOL pbEnabled) +{ + return TRUE; +} + +BOOL RpcGetChildSessionId(void* context, PULONG pSessionId) +{ + return TRUE; +} + +#endif diff --git a/winpr/libwinpr/wtsapi/wtsrpc_c.h b/winpr/libwinpr/wtsapi/wtsrpc_c.h new file mode 100644 index 000000000..8377f786f --- /dev/null +++ b/winpr/libwinpr/wtsapi/wtsrpc_c.h @@ -0,0 +1,76 @@ +/** + * WinPR: Windows Portable Runtime + * Windows Terminal Services API + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_WTSAPI_RPC_CLIENT_STUBS_H +#define WINPR_WTSAPI_RPC_CLIENT_STUBS_H + +/** + * RPC Client Stubs + */ + +BOOL RpcStartRemoteControlSession(void* context, LPWSTR pTargetServerName, + ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers); +BOOL RpcStopRemoteControlSession(void* context, ULONG LogonId); + +BOOL RpcConnectSession(void* context, ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait); + +BOOL RpcEnumerateServers(void* context, LPWSTR pDomainName, DWORD Reserved, + DWORD Version, PWTS_SERVER_INFOW* ppServerInfo, DWORD* pCount); + +HANDLE RpcOpenServer(void* context, LPWSTR pServerName); +HANDLE RpcOpenServerEx(void* context, LPWSTR pServerName); +VOID RpcCloseServer(void* context, HANDLE hServer); + +BOOL RpcEnumerateSessions(void* context, HANDLE hServer, DWORD Reserved, + DWORD Version, PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount); +BOOL RpcEnumerateSessionsEx(void* context, HANDLE hServer, DWORD* pLevel, + DWORD Filter, PWTS_SESSION_INFO_1W* ppSessionInfo, DWORD* pCount); + +BOOL RpcEnumerateProcesses(void* context, HANDLE hServer, DWORD Reserved, + DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount); +BOOL RpcTerminateProcess(void* context, HANDLE hServer, DWORD ProcessId, DWORD ExitCode); + +BOOL RpcQuerySessionInformation(void* context, HANDLE hServer, DWORD SessionId, + WTS_INFO_CLASS WTSInfoClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); + +BOOL RpcQueryUserConfig(void* context, LPWSTR pServerName, LPWSTR pUserName, + WTS_CONFIG_CLASS WTSConfigClass, LPWSTR* ppBuffer, DWORD* pBytesReturned); +BOOL RpcSetUserConfig(void* context, LPWSTR pServerName, LPWSTR pUserName, + WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength); + +BOOL RpcSendMessage(void* context, HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, + LPWSTR pMessage, DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD* pResponse, BOOL bWait); + +BOOL RpcDisconnectSession(void* context, HANDLE hServer, DWORD SessionId, BOOL bWait); + +BOOL RpcLogoffSession(void* context, HANDLE hServer, DWORD SessionId, BOOL bWait); + +BOOL RpcShutdownSystem(void* context, HANDLE hServer, DWORD ShutdownFlag); + +BOOL RpcRegisterSessionNotification(void* context, HWND hWnd, DWORD dwFlags); +BOOL RpcUnRegisterSessionNotification(void* context, HWND hWnd); + +BOOL RpcRegisterSessionNotificationEx(void* context, HANDLE hServer, HWND hWnd, DWORD dwFlags); +BOOL RpcUnRegisterSessionNotificationEx(void* context, HANDLE hServer, HWND hWnd); + +BOOL RpcEnableChildSessions(void* context, BOOL bEnable); +BOOL RpcIsChildSessionsEnabled(void* context, PBOOL pbEnabled); +BOOL RpcGetChildSessionId(void* context, PULONG pSessionId); + +#endif /* WINPR_WTSAPI_RPC_CLIENT_STUBS_H */ From 90c2cb22ab21150741b6eddce91814d034be2429 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 29 Aug 2013 09:44:41 +0200 Subject: [PATCH 025/202] winpr: fixed test building --- winpr/libwinpr/file/CMakeLists.txt | 2 +- winpr/libwinpr/wtsapi/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/file/CMakeLists.txt b/winpr/libwinpr/file/CMakeLists.txt index 7ab377c6d..9014f4cda 100644 --- a/winpr/libwinpr/file/CMakeLists.txt +++ b/winpr/libwinpr/file/CMakeLists.txt @@ -31,7 +31,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SO set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL MODULE winpr - MODULES winpr-crt winpr-handle winpr-path) + MODULES winpr-crt winpr-handle winpr-path winpr-synch) if(MONOLITHIC_BUILD) diff --git a/winpr/libwinpr/wtsapi/CMakeLists.txt b/winpr/libwinpr/wtsapi/CMakeLists.txt index e7f3443dc..07a933c70 100644 --- a/winpr/libwinpr/wtsapi/CMakeLists.txt +++ b/winpr/libwinpr/wtsapi/CMakeLists.txt @@ -36,7 +36,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SO set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL MODULE winpr - MODULES winpr-nt winpr-io winpr-synch) + MODULES winpr-nt winpr-io winpr-synch winpr-file winpr-error) if(MONOLITHIC_BUILD) set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) From 8ecbb86acf5e43cc1c3596807b388787046ee4cf Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 09:33:12 +0200 Subject: [PATCH 026/202] Fixed issue #1281, thread shutdown now properly waiting for quit. --- channels/audin/client/alsa/audin_alsa.c | 40 ++++++++++++++----------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index 0fd034514..c5213799e 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -163,14 +163,9 @@ static BOOL audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size } if (WaitForSingleObject(alsa->stopEvent, 0) == WAIT_OBJECT_0) - { - ret = 0; - frames = 0; - } + break; else - { ret = alsa->receive(encoded_data, encoded_size, alsa->user_data); - } alsa->buffer_frames = 0; @@ -182,7 +177,7 @@ static BOOL audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size frames -= cframes; } - return ret; + return (ret) ? TRUE : FALSE; } static void* audin_alsa_thread_func(void* arg) @@ -198,9 +193,6 @@ static void* audin_alsa_thread_func(void* arg) rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; - alsa->buffer = (BYTE*) malloc(tbytes_per_frame * alsa->frames_per_packet); - ZeroMemory(alsa->buffer, tbytes_per_frame * alsa->frames_per_packet); - alsa->buffer_frames = 0; buffer = (BYTE*) malloc(rbytes_per_frame * alsa->frames_per_packet); ZeroMemory(buffer, rbytes_per_frame * alsa->frames_per_packet); freerdp_dsp_context_reset_adpcm(alsa->dsp_context); @@ -241,15 +233,11 @@ static void* audin_alsa_thread_func(void* arg) free(buffer); - free(alsa->buffer); - alsa->buffer = NULL; - if (capture_handle) snd_pcm_close(capture_handle); - SetEvent(alsa->stopEvent); - DEBUG_DVC("out"); + ExitThread(0); return NULL; } @@ -258,8 +246,6 @@ static void audin_alsa_free(IAudinDevice* device) { AudinALSADevice* alsa = (AudinALSADevice*) device; - SetEvent(alsa->stopEvent); - freerdp_dsp_context_free(alsa->dsp_context); free(alsa->device_name); @@ -337,6 +323,8 @@ static void audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN static void audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* user_data) { + int rbytes_per_frame; + int tbytes_per_frame; AudinALSADevice* alsa = (AudinALSADevice*) device; DEBUG_DVC(""); @@ -345,7 +333,14 @@ static void audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* us alsa->user_data = user_data; alsa->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - alsa->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL); + alsa->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL); + + rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; + tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; + alsa->buffer = (BYTE*) malloc(tbytes_per_frame * alsa->frames_per_packet); + ZeroMemory(alsa->buffer, tbytes_per_frame * alsa->frames_per_packet); + alsa->buffer_frames = 0; } static void audin_alsa_close(IAudinDevice* device) @@ -355,7 +350,16 @@ static void audin_alsa_close(IAudinDevice* device) DEBUG_DVC(""); SetEvent(alsa->stopEvent); + WaitForSingleObject(alsa->thread, INFINITE); + CloseHandle(alsa->stopEvent); + CloseHandle(alsa->thread); + if (alsa->buffer) + free(alsa->buffer); + alsa->buffer = NULL; + + alsa->stopEvent = NULL; + alsa->thread = NULL; alsa->receive = NULL; alsa->user_data = NULL; } From d1c24aa873a0eaff4e90b0f8f19e028e5077883f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 15:42:34 +0200 Subject: [PATCH 027/202] Fixed coverity issue 1047640. --- channels/cliprdr/client/cliprdr_format.c | 35 +++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index 426475a64..59a729262 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -62,21 +62,25 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS for (i = 0; i < cb_event->num_formats; i++) { const char* name; - int name_length; + int name_length, short_name_length = 32, x; switch (cb_event->formats[i]) { case CB_FORMAT_HTML: - name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML); + name = CFSTR_HTML; + name_length = sizeof(CFSTR_HTML); break; case CB_FORMAT_PNG: - name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG); + name = CFSTR_PNG; + name_length = sizeof(CFSTR_PNG); break; case CB_FORMAT_JPEG: - name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG); + name = CFSTR_JPEG; + name_length = sizeof(CFSTR_JPEG); break; case CB_FORMAT_GIF: - name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF); + name = CFSTR_GIF; + name_length = sizeof(CFSTR_GIF); break; default: name = "\0\0"; @@ -85,12 +89,23 @@ void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIS } if (!cliprdr->use_long_format_names) - name_length = 32; - - Stream_EnsureRemainingCapacity(body, 4 + name_length); + { + x = (name_length > short_name_length) ? + name_length : short_name_length; - Stream_Write_UINT32(body, cb_event->formats[i]); - Stream_Write(body, name, name_length); + Stream_EnsureRemainingCapacity(body, 4 + short_name_length); + Stream_Write_UINT32(body, cb_event->formats[i]); + Stream_Write(body, name, x); + + while (x++ < short_name_length) + Stream_Write(body, "\0", 1); + } + else + { + Stream_EnsureRemainingCapacity(body, 4 + name_length); + Stream_Write_UINT32(body, cb_event->formats[i]); + Stream_Write(body, name, name_length); + } } Stream_SealLength(body); From 42ceabbebbb4975e6fbc8708490e66cd9306ec3a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 15:44:37 +0200 Subject: [PATCH 028/202] Fixed coverity issue 1047636 --- channels/client/addin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/client/addin.c b/channels/client/addin.c index f85314258..d7494e20f 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -182,6 +182,8 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszAddinPath); NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszPattern); + free(pszPattern); + cchSearchPath = strlen(pszSearchPath); hFind = FindFirstFileA(pszSearchPath, &FindData); From 82f0efd6e62af469427de021e6822a14064a7851 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 15:45:41 +0200 Subject: [PATCH 029/202] Fixed coverity issue 1047635 --- channels/client/addin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/client/addin.c b/channels/client/addin.c index d7494e20f..ca12927d5 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -188,6 +188,8 @@ FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSub hFind = FindFirstFileA(pszSearchPath, &FindData); + free(pszSearchPath); + nAddins = 0; ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128); ppAddins[nAddins] = NULL; From a55afb58a438afe614fac21a9cafd605213b6bfb Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 15:53:50 +0200 Subject: [PATCH 030/202] Fixed coverity issue 1047634 --- winpr/libwinpr/crt/unicode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/winpr/libwinpr/crt/unicode.c b/winpr/libwinpr/crt/unicode.c index 672afc123..639a5e999 100644 --- a/winpr/libwinpr/crt/unicode.c +++ b/winpr/libwinpr/crt/unicode.c @@ -352,5 +352,11 @@ int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int if (status != cbMultiByte) status = 0; + if ((status <= 0) && allocate) + { + free(*lpMultiByteStr); + *lpMultiByteStr = NULL; + } + return status; } From caecdba4c8e613d6eef783c5b9840d319bc13072 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:05:02 +0200 Subject: [PATCH 031/202] Fixed coverity issue 1047625 --- client/common/cmdline.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 0faf2f6f2..a681d3d2e 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1153,6 +1153,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin { settings->MonitorIds[i] = atoi(p[i]); } + + free(p); } } CommandLineSwitchCase(arg, "monitor-list") From a7b77db020483443f74257f97d8640eca0fc3440 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:08:40 +0200 Subject: [PATCH 032/202] Fixed coverity issue 1047624 --- client/common/compatibility.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 40f7a326e..5bf6625b5 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -279,6 +279,11 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg } } + for (i=0; iargc; i++) + free(args->argv[i]); + free(args->argv); + free(args); + return (index - old_index); } From 04c59ba3c58e00ecb0d43f4d2cb542e9dc0047a5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:13:09 +0200 Subject: [PATCH 033/202] Fixed coverity issue 1047623 --- client/common/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/common/file.c b/client/common/file.c index a1ec5a362..01028410c 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -456,7 +456,10 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name) fseek(fp, 0, SEEK_SET); if (file_size < 1) + { + fclose(fp); return FALSE; + } buffer = (BYTE*) malloc(file_size + 2); read_size = fread(buffer, file_size, 1, fp); @@ -466,6 +469,7 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name) if (!ferror(fp)) read_size = file_size; } + fclose(fp); if (read_size < 1) { From 57569229db5004b792bd21dedb254241f6df7962 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:16:03 +0200 Subject: [PATCH 034/202] Fixed coverity issue 1047622 --- client/common/file.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/common/file.c b/client/common/file.c index 01028410c..14bd5039b 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -673,14 +673,19 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~((size_t) file->Username)) { - char* user; - char* domain; + char* user = NULL; + char* domain = NULL; freerdp_parse_username(file->Username, &user, &domain); freerdp_set_param_string(settings, FreeRDP_Username, user); if (domain != NULL) freerdp_set_param_string(settings, FreeRDP_Domain, domain); + + if (user) + free(user); + if(domain) + free(domain); } if (~file->ServerPort) From c05daf9f74e9c878df9d688ed8b57fd22ad19ee0 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:19:33 +0200 Subject: [PATCH 035/202] Fixed coverity issue 1047621 --- libfreerdp/codec/rfx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 0cbcbd0d8..7c52ce072 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -689,6 +689,10 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (Stream_GetRemainingLength(s) < 6) { DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->numTiles); + if (work_objects) + free(work_objects); + if (params) + free(params); return FALSE; } @@ -697,7 +701,12 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (Stream_GetRemainingLength(s) < blockLen - 6) { - DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->numTiles, blockLen); + DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", + i, message->numTiles, blockLen); + if (work_objects) + free(work_objects); + if (params) + free(params); return FALSE; } From 0dae05678b222a916948bb310ec88fe6688b2fe8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:22:35 +0200 Subject: [PATCH 036/202] Fixed coverity issue 1047619 --- libfreerdp/common/addin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfreerdp/common/addin.c b/libfreerdp/common/addin.c index 07680aa0e..9e40f6ac7 100644 --- a/libfreerdp/common/addin.c +++ b/libfreerdp/common/addin.c @@ -143,6 +143,7 @@ void* freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszE if (entry) return entry; + FreeLibrary(library); return entry; } From f9c327ce0192cff929ba4cc03ea3f610a9083376 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:23:56 +0200 Subject: [PATCH 037/202] Fixed coverity issue 1047618 --- libfreerdp/core/extension.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/core/extension.c b/libfreerdp/core/extension.c index 496bfc91e..ce062fe57 100644 --- a/libfreerdp/core/extension.c +++ b/libfreerdp/core/extension.c @@ -147,6 +147,8 @@ static int extension_load_plugins(rdpExtension* extension) fprintf(stderr, "extension_load_plugins: %s entry returns error.\n", path); continue; } + + DLCLOSE(han); } return 0; From 91cfc90f3b5882ace9458575424f69b07ba4f771 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:26:11 +0200 Subject: [PATCH 038/202] Fixed coverity issue 1047617 --- libfreerdp/core/gateway/rpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index 3e6f68b95..ae024cd9e 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -433,6 +433,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) if (encrypt_status != SEC_E_OK) { fprintf(stderr, "EncryptMessage status: 0x%08X\n", encrypt_status); + free(request_pdu); return -1; } From a861cdbdd9ae39b890d5faca9cccaa68c3599dc1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:28:00 +0200 Subject: [PATCH 039/202] Fixed coverity issue 1047616 --- libfreerdp/core/gateway/tsg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index cf013f2d8..ddd68b9cc 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -599,7 +599,10 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (SizeValue != packetResponse->responseDataLen) { - fprintf(stderr, "Unexpected size value: %d, expected: %d\n", SizeValue, packetResponse->responseDataLen); + fprintf(stderr, "Unexpected size value: %d, expected: %d\n", + SizeValue, packetResponse->responseDataLen); + free(packetResponse); + free(packet); return FALSE; } From 15466fc37dfc1e1be71a07bfcbad467ffbdaaad8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:29:12 +0200 Subject: [PATCH 040/202] Fixed coverity issue 1047615 --- libfreerdp/core/gateway/tsg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index ddd68b9cc..675d38124 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -321,6 +321,9 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n", tsgCaps->capabilityType); + free(tsgCaps); + free(versionCaps); + free(packetCapsResponse); return FALSE; } From 66da66cdc232a353d3b999175387a24c6af756f2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:31:35 +0200 Subject: [PATCH 041/202] Fixed coverity issue 1047614 --- libfreerdp/core/gateway/tsg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 675d38124..52aa0030d 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -788,6 +788,9 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) break; } + if (packet) + free(packet); + return TRUE; } From e6c3dbde3d038e48955589b7973f07ae6bd13fc4 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:42:23 +0200 Subject: [PATCH 042/202] Fixed coverity issue 1047612 --- libfreerdp/core/nego.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index e60b2f680..f3370e6e8 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -482,11 +482,9 @@ BOOL nego_recv_response(rdpNego* nego) status = nego_recv(nego->transport, s, nego); + Stream_Free(s, TRUE); if (status < 0) - { - Stream_Free(s, TRUE); return FALSE; - } Stream_Free(s, TRUE); return TRUE; From 022439aa4c39072fe4070f044491cf41b90665a8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 16:44:54 +0200 Subject: [PATCH 043/202] Fixed coverity issue 1047611 --- libfreerdp/core/nla.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 875c0ae73..2978a2a79 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -718,7 +718,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) { int length; BYTE* buffer; - ULONG pfQOP; + ULONG pfQOP = 0; BYTE* public_key1; BYTE* public_key2; int public_key_length; @@ -1145,7 +1145,10 @@ int credssp_recv(rdpCredssp* credssp) if(!ber_read_sequence_tag(s, &length) || !ber_read_contextual_tag(s, 0, &length, TRUE) || !ber_read_integer(s, &version)) + { + Stream_Free(s, TRUE); return -1; + } /* [1] negoTokens (NegoData) */ if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE) @@ -1155,7 +1158,10 @@ int credssp_recv(rdpCredssp* credssp) !ber_read_contextual_tag(s, 0, &length, TRUE) || /* [0] negoToken */ !ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ Stream_GetRemainingLength(s) < length) + { + Stream_Free(s, TRUE); return -1; + } sspi_SecBufferAlloc(&credssp->negoToken, length); Stream_Read(s, credssp->negoToken.pvBuffer, length); credssp->negoToken.cbBuffer = length; @@ -1166,7 +1172,10 @@ int credssp_recv(rdpCredssp* credssp) { if(!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ Stream_GetRemainingLength(s) < length) + { + Stream_Free(s, TRUE); return -1; + } sspi_SecBufferAlloc(&credssp->authInfo, length); Stream_Read(s, credssp->authInfo.pvBuffer, length); credssp->authInfo.cbBuffer = length; @@ -1177,7 +1186,10 @@ int credssp_recv(rdpCredssp* credssp) { if(!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */ Stream_GetRemainingLength(s) < length) + { + Stream_Free(s, TRUE); return -1; + } sspi_SecBufferAlloc(&credssp->pubKeyAuth, length); Stream_Read(s, credssp->pubKeyAuth.pvBuffer, length); credssp->pubKeyAuth.cbBuffer = length; From 057519796062aa6cdc60e36698ffb0fda3af02e2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:05:31 +0200 Subject: [PATCH 044/202] Fixed coverity issue 1047609 --- libfreerdp/crypto/base64.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libfreerdp/crypto/base64.c b/libfreerdp/crypto/base64.c index f7050fea4..be1285079 100644 --- a/libfreerdp/crypto/base64.c +++ b/libfreerdp/crypto/base64.c @@ -115,10 +115,16 @@ static void* base64_decode(BYTE* s, int length, int* data_len) n[3] = base64_decode_char(*p++); if ((n[0] == -1) || (n[1] == -1)) + { + free(data); return NULL; + } if ((n[2] == -1) && (n[3] != -1)) + { + free(data); return NULL; + } q[0] = (n[0] << 2) + (n[1] >> 4); From c7abfb8fa1edd5876d200b6e1ff369139bcdcd7b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:08:53 +0200 Subject: [PATCH 045/202] Fixed coverity issue 1047608 --- libfreerdp/crypto/tls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 0c4bce4c9..c7586344d 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -591,6 +591,8 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) break; } } + + free(alt_names_length); } /* if the certificate is valid and the certificate name matches, verification succeeds */ From e9be3e9500f1e5a553fce0ccbcabbd17f83e6dae Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:10:58 +0200 Subject: [PATCH 046/202] Fixed coverity issue 1047607 --- libfreerdp/crypto/tls.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index c7586344d..3bcdc89e1 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -691,6 +691,9 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) free(common_name); #endif + if (alt_names) + free(alt_names); + return verification_status; } From 53e0d53b996fbc2a6dbe24ed22aca366aff76f06 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:35:01 +0200 Subject: [PATCH 047/202] Fixed coverity issue 1047603 --- winpr/libwinpr/file/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index feaf66d25..843a09fc0 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -475,6 +475,7 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) } } + free(pFileSearch); return INVALID_HANDLE_VALUE; } From 64c3aafcc65e2b2463220157884f78f41b2995b3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:36:55 +0200 Subject: [PATCH 048/202] Fixed coverity issue 1047602 --- winpr/libwinpr/pipe/pipe.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 241f131b9..ec65eee03 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -65,7 +65,13 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP pWritePipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE)); if (!pReadPipe || !pWritePipe) + { + if (pReadPipe) + free(pReadPipe); + if (pWritePipe) + free(pWritePipe); return FALSE; + } pReadPipe->fd = pipe_fd[0]; pWritePipe->fd = pipe_fd[1]; From 4bd1c567bd42cbf810681bfe58e37479b2cbda5f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:40:29 +0200 Subject: [PATCH 049/202] Fixed coverity issue 1047600 --- winpr/libwinpr/sspi/NTLM/ntlm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index d2137a865..271a51023 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -81,22 +81,23 @@ void ntlm_SetContextServicePrincipalNameA(NTLM_CONTEXT* context, char* ServicePr void ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) { + char *name = TargetName; DWORD nSize = 0; if (!TargetName) { GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize); - TargetName = malloc(nSize); + name = malloc(nSize); GetComputerNameExA(ComputerNameDnsHostname, TargetName, &nSize); CharUpperA(TargetName); } context->TargetName.cbBuffer = ConvertToUnicode(CP_UTF8, 0, - TargetName, -1, (LPWSTR*) &context->TargetName.pvBuffer, 0) - 1; + name, -1, (LPWSTR*) &context->TargetName.pvBuffer, 0) - 1; context->TargetName.cbBuffer *= 2; - if (nSize > 0) - free(TargetName); + if (!TargetName) + free(name); } NTLM_CONTEXT* ntlm_ContextNew() From e2cd11332b5bd737acb5554deb688f4ea63b92f4 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:44:35 +0200 Subject: [PATCH 050/202] Fixed coverity issue 1047599 --- winpr/libwinpr/sspi/NTLM/ntlm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 271a51023..4809935d0 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -43,20 +43,21 @@ char* NTLM_PACKAGE_NAME = "NTLM"; void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) { + char *ws = Workstation; DWORD nSize = 0; if (!Workstation) { GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); - Workstation = malloc(nSize); + ws = malloc(nSize); GetComputerNameExA(ComputerNameNetBIOS, Workstation, &nSize); } context->Workstation.Length = ConvertToUnicode(CP_UTF8, 0, - Workstation, -1, &context->Workstation.Buffer, 0) - 1; + ws, -1, &context->Workstation.Buffer, 0) - 1; context->Workstation.Length *= 2; - if (nSize > 0) + if (!Workstation) free(Workstation); } From 1673e526f5d9ae02029321a1fc8a267d6644442f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:46:07 +0200 Subject: [PATCH 051/202] Fixed coverity issue 1047598 --- winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 1 + 1 file changed, 1 insertion(+) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 854e13581..5bd0a81a5 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -279,6 +279,7 @@ void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) { fprintf(stderr, "Error: Could not find user in SAM database\n"); } + SamClose(sam); } void ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash) From f231f3fcc55edcca453f58f2bf60f2165c6700d7 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:50:10 +0200 Subject: [PATCH 052/202] Fixed coverity issue 1047597 --- winpr/libwinpr/sspi/NTLM/ntlm_message.c | 1 + 1 file changed, 1 insertion(+) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 8b17d6990..487a4d5fc 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -799,6 +799,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer winpr_HexDump(context->MessageIntegrityCheck, 16); fprintf(stderr, "Actual MIC:\n"); winpr_HexDump(message->MessageIntegrityCheck, 16); + Stream_Free(s, FALSE); return SEC_E_MESSAGE_ALTERED; } From 0c08b584b899fa52d9d5af26470c1e032eb00e4b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:51:43 +0200 Subject: [PATCH 053/202] Fixed coverity issue 1047596 --- winpr/libwinpr/synch/event.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index ece585cbf..3b96127b7 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -70,12 +70,14 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, if (event->pipe_fd[0] < 0) { fprintf(stderr, "CreateEventW: failed to create event\n"); + free(event); return NULL; } #else if (pipe(event->pipe_fd) < 0) { fprintf(stderr, "CreateEventW: failed to create event\n"); + free(event); return NULL; } #endif From 04e9338668accddfe617e13912330d8c487db520 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 28 Aug 2013 17:53:47 +0200 Subject: [PATCH 054/202] Fixed coverity issue 1047595 --- winpr/libwinpr/synch/semaphore.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/winpr/libwinpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c index e2d3771fc..4c54fa12e 100644 --- a/winpr/libwinpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -57,7 +57,11 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti while (lInitialCount > 0) { if (write(semaphore->pipe_fd[1], "-", 1) != 1) + { + close(semaphore->pipe_fd[0]); + close(semaphore->pipe_fd[1]); return FALSE; + } lInitialCount--; } From 020bae25d725f2356751387066b62a0acca2c214 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:02:24 +0200 Subject: [PATCH 055/202] Fixed coverity issue 1047594 --- winpr/libwinpr/utils/sam.c | 1 + 1 file changed, 1 insertion(+) diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index 0aa0bc883..bd0db1c4e 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -286,6 +286,7 @@ WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, DomainMatch = 1; } } + free(EntryDomain); } else { From 87a9a24ef274089ed71bc1344289e996e77dff64 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:05:42 +0200 Subject: [PATCH 056/202] Fixed coverity issue 1047593 --- winpr/libwinpr/rpc/ndr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winpr/libwinpr/rpc/ndr.c b/winpr/libwinpr/rpc/ndr.c index 0cec370e2..3434238c2 100644 --- a/winpr/libwinpr/rpc/ndr.c +++ b/winpr/libwinpr/rpc/ndr.c @@ -143,6 +143,10 @@ void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_P for (i = 0; i < numberParams; i++) { +#ifdef __x86_64__ + float tmp; +#endif + arg = pStubMsg->StackTop + params[i].StackOffset; fmt = (PFORMAT_STRING) &pStubMsg->StubDesc->pFormatTypes[params[i].Type.Offset]; @@ -151,7 +155,7 @@ void NdrProcessParams(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, NDR_P !(params[i].Attributes.IsSimpleRef) && ((params[i].Type.FormatChar) == FC_FLOAT) && !fpuArgs) { - float tmp = *(double*) arg; + tmp = *(double*) arg; arg = (unsigned char*) &tmp; } #endif From bda6ede46383423588d0fa787261f3842986e206 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:10:00 +0200 Subject: [PATCH 057/202] Fixed coverity issue 1047590 --- libfreerdp/codec/dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/codec/dsp.c b/libfreerdp/codec/dsp.c index 868af3e71..734940d4e 100644 --- a/libfreerdp/codec/dsp.c +++ b/libfreerdp/codec/dsp.c @@ -112,7 +112,7 @@ static const INT16 ima_step_size_table[] = }; static UINT16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm, - int channel, BYTE sample) + unsigned int channel, BYTE sample) { INT32 ss; INT32 d; From 82382d88bafab25f4e0c772f9f83bf5c2e33848b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:29:03 +0200 Subject: [PATCH 058/202] Fixed coverity issue 1047568 --- channels/drive/client/drive_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index d4baee68c..046013836 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -117,7 +117,7 @@ static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* disk, UINT32 id) static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp) { - char* path; + char* path = NULL; int status; UINT32 FileId; DRIVE_FILE* file; From 75c0ecb3628cf64b29472b88877c664520494d77 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:37:14 +0200 Subject: [PATCH 059/202] Fixed coverity issue 1047564 --- libfreerdp/codec/rfx.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 7c52ce072..af8737aad 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -677,7 +677,21 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (context->priv->UseThreads) { work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles); - params = (RFX_TILE_PROCESS_WORK_PARAM*) malloc(sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->numTiles); + params = (RFX_TILE_PROCESS_WORK_PARAM*) + malloc(sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->numTiles); + + if (!work_objects) + { + if (params) + free(params); + return FALSE; + } + if (!params) + { + if (work_objects) + free(work_objects); + return FALSE; + } } /* tiles */ From 629ac4ad28bd56fe3e9ce97c70ffc35cc4c87f77 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:42:08 +0200 Subject: [PATCH 060/202] Fixed coverity issue 1047588 --- winpr/libwinpr/synch/semaphore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winpr/libwinpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c index 4c54fa12e..9e33d8a8a 100644 --- a/winpr/libwinpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -39,6 +39,8 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) malloc(sizeof(WINPR_SEMAPHORE)); + if (!semaphore) + return NULL; semaphore->pipe_fd[0] = -1; semaphore->pipe_fd[0] = -1; From d519bc31155112bfcfb7eb5eb4c8384d148ccf97 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:46:44 +0200 Subject: [PATCH 061/202] Fixed coverity issue 1047592 --- winpr/libwinpr/path/shell.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 0c41e54c0..1bf44f340 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -276,11 +276,14 @@ char* GetCombinedPath(char* basePath, char* subPath) int length; HRESULT status; char* path = NULL; - int basePathLength; - int subPathLength; + char* subPathCpy; + int basePathLength = 0; + int subPathLength = 0; - basePathLength = strlen(basePath); - subPathLength = strlen(subPath); + if (basePath) + basePathLength = strlen(basePath); + if (subPath) + subPathLength = strlen(subPath); length = basePathLength + subPathLength + 1; path = (char*) malloc(length + 1); @@ -293,12 +296,12 @@ char* GetCombinedPath(char* basePath, char* subPath) if (!subPath) return path; - subPath = _strdup(subPath); - PathCchConvertStyleA(subPath, subPathLength, PATH_STYLE_NATIVE); + subPathCpy = _strdup(subPath); + PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE); - status = NativePathCchAppendA(path, length + 1, subPath); + status = NativePathCchAppendA(path, length + 1, subPathCpy); - free(subPath); + free(subPathCpy); return path; } From c5fc2de7107c5f80ca68c72b01355bb7bb3a1527 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:49:19 +0200 Subject: [PATCH 062/202] Fixed coverity issue 1047651 --- client/common/compatibility.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 5bf6625b5..57f2ac322 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -246,10 +246,9 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg a = p; } - p = strchr(p, ':'); - if (p != NULL) { + p = strchr(p, ':'); length = p - a; args->argv[j + 1] = malloc(length + 1); CopyMemory(args->argv[j + 1], a, length); From 1d3e8c7cb3d9e5025d067ee147d5dcd54afa439a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:51:36 +0200 Subject: [PATCH 063/202] Fixed coverity issue 1047650 --- libfreerdp/gdi/16bpp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/gdi/16bpp.c b/libfreerdp/gdi/16bpp.c index f9e1a1be5..9437ea6d6 100644 --- a/libfreerdp/gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -754,6 +754,9 @@ static int BitBlt_PATPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) { + if (!hdcDest) + return 0; + if (hdcSrc != NULL) { if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0) From ac3fb4c676201bb196e0b51408c2963144218c7a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:52:35 +0200 Subject: [PATCH 064/202] Fixed coverity issue 1047649 --- libfreerdp/gdi/32bpp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/gdi/32bpp.c b/libfreerdp/gdi/32bpp.c index 3b3c05ef4..d3d91c0b9 100644 --- a/libfreerdp/gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -850,6 +850,9 @@ static int BitBlt_PATPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) { + if (!hdcDest) + return 0; + if (hdcSrc != NULL) { if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0) From 96285eec5872051a9364b60d67c49101e677a06d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:55:07 +0200 Subject: [PATCH 065/202] Fixed coverity issue 1047647 --- winpr/libwinpr/crt/string.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index 716c607a6..a98f2fb63 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -241,6 +241,9 @@ LPSTR CharLowerA(LPSTR lpsz) int i; int length; + if (!lpsz) + return (LPSTR) NULL; + length = strlen(lpsz); if (length < 1) @@ -248,15 +251,14 @@ LPSTR CharLowerA(LPSTR lpsz) if (length == 1) { - LPSTR pc = NULL; char c = *lpsz; if ((c >= 'A') && (c <= 'Z')) c = c + 32; - *pc = c; + *lpsz = c; - return pc; + return lpsz; } for (i = 0; i < length; i++) From a3550932199e506542065a48798a2c6922e48a4b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 10:59:00 +0200 Subject: [PATCH 066/202] Fixed coverity issue 1047645 --- winpr/libwinpr/rpc/ndr_correlation.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winpr/libwinpr/rpc/ndr_correlation.c b/winpr/libwinpr/rpc/ndr_correlation.c index 1afb31843..e12ee35d8 100644 --- a/winpr/libwinpr/rpc/ndr_correlation.c +++ b/winpr/libwinpr/rpc/ndr_correlation.c @@ -80,6 +80,8 @@ PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem if (pStubMsg->StackTop) ptr = pStubMsg->StackTop; } + else + return pFormat; switch (correlation_operator) { From a3c319c9736fc95bc507043269c7478b0723dd63 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 11:01:58 +0200 Subject: [PATCH 067/202] Fixed coverity issue 1047567 --- channels/parallel/client/parallel_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 16bf4bbb0..ae4c5a4dc 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -137,7 +137,7 @@ static void parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) buffer = (BYTE*) malloc(Length); - status = read(parallel->file, irp->output->pointer, Length); + status = read(parallel->file, buffer, Length); if (status < 0) { From 1e2455fa4aa34dcefed3cc550faa5e7155bedde8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 11:07:19 +0200 Subject: [PATCH 068/202] Fixed various memory leaks and compiler warnings. --- channels/tsmf/client/alsa/tsmf_alsa.c | 4 ++-- client/X11/xf_gdi.c | 4 ++++ client/X11/xf_rail.c | 2 +- include/freerdp/utils/debug.h | 7 ++++++- libfreerdp/core/freerdp.c | 10 +++++++++- libfreerdp/core/listener.c | 1 + libfreerdp/crypto/tls.c | 2 +- libfreerdp/utils/pcap.c | 2 ++ libfreerdp/utils/profiler.c | 3 ++- winpr/libwinpr/synch/sleep.c | 4 +++- 10 files changed, 31 insertions(+), 8 deletions(-) diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index 74c78a744..a6b67d71a 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -74,11 +74,11 @@ static BOOL tsmf_alsa_open(ITSMFAudioDevice* audio, const char* device) if (!device) { if (!alsa->device[0]) - strcpy(alsa->device, "default"); + strncpy(alsa->device, "default", sizeof(alsa->device)); } else { - strcpy(alsa->device, device); + strncpy(alsa->device, device, sizeof(alsa->device)); } return tsmf_alsa_open_device(alsa); diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 158c61778..eb295cdab 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -998,6 +998,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); + free(xfc->bmp_codec_nsc); + xfc->bmp_codec_nsc = NULL; xf_gdi_surface_update_frame(xfc, surface_bits_command->destLeft, surface_bits_command->destTop, @@ -1026,6 +1028,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); + free(xfc->bmp_codec_none); + xfc->bmp_codec_none = NULL; xf_gdi_surface_update_frame(xfc, surface_bits_command->destLeft, surface_bits_command->destTop, diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 459d0f911..4e4f17f03 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -565,7 +565,7 @@ const char* movetype_names[] = void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* channels, wMessage* event) { - int x, y; + int x = 0, y = 0; rdpRail* rail; int direction = 0; Window child_window; diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h index eb6b61301..a62ec19a0 100644 --- a/include/freerdp/utils/debug.h +++ b/include/freerdp/utils/debug.h @@ -23,7 +23,12 @@ #include #define DEBUG_NULL(fmt, ...) do { } while (0) -#define DEBUG_PRINT(_dbg_str, fmt, ...) fprintf(stderr, _dbg_str fmt "\n" , __FUNCTION__, __LINE__, ## __VA_ARGS__) +#define DEBUG_PRINT(_dbg_str, fmt, ...) do { \ + fprintf(stderr, _dbg_str, __FUNCTION__, __LINE__); \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } while( 0 ) + #define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%d): ", fmt, ## __VA_ARGS__) #define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%d): ", fmt, ## __VA_ARGS__) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index d068beca3..b0b865180 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -164,7 +164,8 @@ BOOL freerdp_connect(freerdp* instance) StreamPool_Return(rdp->transport->ReceivePool, s); } - + pcap_close(update->pcap_rfx); + update->pcap_rfx = NULL; status = TRUE; goto freerdp_connect_finally; } @@ -306,6 +307,13 @@ BOOL freerdp_disconnect(freerdp* instance) IFCALL(instance->PostDisconnect, instance); + if (instance->update->pcap_rfx) + { + instance->update->dump_rfx = FALSE; + pcap_close(instance->update->pcap_rfx); + instance->update->pcap_rfx = NULL; + } + return TRUE; } diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index fb49bf3d4..b74c4ec43 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -306,6 +306,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) continue; #endif perror("accept"); + free(client); return FALSE; } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 3bcdc89e1..401ef43a1 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -592,7 +592,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) } } - free(alt_names_length); + free(alt_names_lengths); } /* if the certificate is valid and the certificate name matches, verification succeeds */ diff --git a/libfreerdp/utils/pcap.c b/libfreerdp/utils/pcap.c index 52d912bf3..5e174a847 100644 --- a/libfreerdp/utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -218,4 +218,6 @@ void pcap_close(rdpPcap* pcap) if (pcap->fp != NULL) fclose(pcap->fp); + + free(pcap); } diff --git a/libfreerdp/utils/profiler.c b/libfreerdp/utils/profiler.c index 3d8fae62d..794f3e7f1 100644 --- a/libfreerdp/utils/profiler.c +++ b/libfreerdp/utils/profiler.c @@ -70,7 +70,8 @@ void profiler_print(PROFILER* profiler) double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; - fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); + fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", + profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); } void profiler_print_footer() diff --git a/winpr/libwinpr/synch/sleep.c b/winpr/libwinpr/synch/sleep.c index 096e24323..6e83de72d 100644 --- a/winpr/libwinpr/synch/sleep.c +++ b/winpr/libwinpr/synch/sleep.c @@ -30,7 +30,9 @@ #include #ifdef HAVE_UNISTD_H -#define _XOPEN_SOURCE 500 + #ifndef _XOPEN_SOURCE + #define _XOPEN_SOURCE 500 + #endif #include #endif From 62330ca669053355e38c0f4640a296c96ff52de4 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 11:38:28 +0200 Subject: [PATCH 069/202] Fixed variable mixup. --- winpr/libwinpr/sspi/NTLM/ntlm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 4809935d0..2848e4abd 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -50,7 +50,7 @@ void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) { GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); ws = malloc(nSize); - GetComputerNameExA(ComputerNameNetBIOS, Workstation, &nSize); + GetComputerNameExA(ComputerNameNetBIOS, ws, &nSize); } context->Workstation.Length = ConvertToUnicode(CP_UTF8, 0, From a3b531c036f49e76406a9cc700fa47a058bed7c6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 29 Aug 2013 15:30:22 +0200 Subject: [PATCH 070/202] Fixed issues found with clang-analyzer --- channels/rdpsnd/client/rdpsnd_main.c | 3 ++ .../smartcard/client/smartcard_operations.c | 3 ++ channels/urbdrc/client/data_transfer.c | 2 + .../urbdrc/client/libusb/libusb_udevice.c | 6 +++ client/X11/xf_window.c | 1 + client/common/compatibility.c | 9 ++++ libfreerdp/codec/rfx.c | 49 ++++++++++++++----- libfreerdp/core/gateway/http.c | 6 +++ libfreerdp/core/gateway/tsg.c | 16 ++++-- libfreerdp/core/listener.c | 5 +- libfreerdp/crypto/er.c | 13 +++-- winpr/libwinpr/crt/string.c | 9 ++-- winpr/libwinpr/file/file.c | 4 ++ winpr/libwinpr/file/pattern.c | 2 +- winpr/libwinpr/path/shell.c | 2 + winpr/libwinpr/registry/registry_reg.c | 3 ++ winpr/libwinpr/rpc/ndr_correlation.c | 3 ++ winpr/libwinpr/sspi/NTLM/ntlm_message.c | 1 + winpr/libwinpr/synch/semaphore.c | 2 + winpr/libwinpr/synch/timer.c | 8 ++- winpr/libwinpr/utils/collections/Reference.c | 3 ++ 21 files changed, 124 insertions(+), 26 deletions(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 35ba973d7..f8d612276 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -417,7 +417,10 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wAudioLength = rdpsnd_compute_audio_time_length(format, size); if (!rdpsnd->device) + { + free(wave); return; + } if (rdpsnd->device->WaveDecode) { diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index d75b1d3d9..e36b6d8a4 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1032,7 +1032,10 @@ static UINT32 handle_Control(IRP* irp) sendBuffer = malloc(outBufferSize); if (!sendBuffer) + { + free(recvBuffer); return smartcard_output_return(irp, SCARD_E_NO_MEMORY); + } status = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength, sendBuffer, (DWORD) outBufferSize, &nBytesReturned); diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c index 99d714513..f0aa961d1 100644 --- a/channels/urbdrc/client/data_transfer.c +++ b/channels/urbdrc/client/data_transfer.c @@ -279,6 +279,7 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da default: LLOGLN(urbdrc_debug, ("urbdrc_process_io_control: unknown IoControlCode 0x%X", IoControlCode)); + zfree(OutputBuffer); return -1; break; } @@ -1718,6 +1719,7 @@ static int urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE break; default: fprintf(stderr, "urb_control_feature_request: Error Command %x\n", command); + zfree(out_data); return -1; } diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index a2f417527..82775fffb 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -485,6 +485,7 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(LIBUSB_DEVICE* libusb_dev) if (ret < 0) { fprintf(stderr, "libusb_get_device_descriptor: ERROR!!\n"); + free(descriptor); return NULL; } @@ -1543,6 +1544,9 @@ static int func_cancel_xact_request(TRANSFER_REQUEST *request) { int status; + if (!request) + return -1; + if ((!request->transfer) || (request->endpoint != request->transfer->endpoint) || (request->transfer->endpoint == 0) || (request->submit != 1)) { @@ -1583,6 +1587,8 @@ cancel_retry: while (request_queue->has_next(request_queue)) { request = request_queue->get_next(request_queue); + if (!request) + continue; LLOGLN(libusb_debug, ("%s: CancelId:0x%x RequestId:0x%x endpoint 0x%x!!", __func__, RequestId, request->RequestId, request->endpoint)); diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index e12cdc344..b428048a5 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -832,6 +832,7 @@ void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon) PropModeReplace, (BYTE*) propdata, propsize); XFlush(xfc->display); + free(propdata); } void xf_SetWindowRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 57f2ac322..048afa599 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -125,6 +125,9 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args) } else if (strcmp(args->argv[0], "rdpdr") == 0) { + if (args->argc < 2) + return -1; + if ((strcmp(args->argv[1], "disk") == 0) || (strcmp(args->argv[1], "drive") == 0)) { @@ -156,11 +159,17 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args) } else if (strcmp(args->argv[0], "rdpsnd") == 0) { + if (args->argc < 2) + return -1; + freerdp_addin_replace_argument_value(args, args->argv[1], "sys", args->argv[1]); freerdp_client_add_static_channel(settings, args->argc, args->argv); } else if (strcmp(args->argv[0], "rail") == 0) { + if (args->argc < 2) + return -1; + settings->RemoteApplicationProgram = _strdup(args->argv[1]); } else diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index af8737aad..00e6adea6 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -583,7 +583,7 @@ void CALLBACK rfx_process_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, wStream* s) { - int i; + int i, close_cnt; int pos; BYTE quant; RFX_TILE* tile; @@ -692,9 +692,12 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa free(work_objects); return FALSE; } + ZeroMemory(work_objects, sizeof(PTP_WORK) * message->numTiles); + ZeroMemory(params, sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->numTiles); } /* tiles */ + close_cnt = 0; for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); @@ -760,6 +763,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa (void*) ¶ms[i], &context->priv->ThreadPoolEnv); SubmitThreadpoolWork(work_objects[i]); + close_cnt = i + 1; } else { @@ -771,16 +775,18 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (context->priv->UseThreads) { - for (i = 0; i < message->numTiles; i++) + for (i = 0; i < close_cnt; i++) { WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); CloseThreadpoolWork(work_objects[i]); } - - free(work_objects); - free(params); } + if (work_objects) + free(work_objects); + if (params) + free(params); + for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; @@ -1063,7 +1069,7 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline) { - int i; + int i, close_cnt; int xIdx; int yIdx; int numTilesX; @@ -1077,6 +1083,9 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, RFX_TILE_COMPOSE_WORK_PARAM* params = NULL; message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); + if (!message) + return NULL; + ZeroMemory(message, sizeof(RFX_MESSAGE)); if (context->state == RFX_STATE_SEND_HEADERS) @@ -1116,9 +1125,24 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, if (context->priv->UseThreads) { work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles); - params = (RFX_TILE_COMPOSE_WORK_PARAM*) malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); + if (!work_objects) + { + free(message); + return NULL; + } + params = (RFX_TILE_COMPOSE_WORK_PARAM*) + malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); + if (!params) + { + free(message); + free(work_objects); + return NULL; + } + ZeroMemory(work_objects, sizeof(PTP_WORK) * message->numTiles); + ZeroMemory(params, sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); } + close_cnt = 0; for (yIdx = 0; yIdx < numTilesY; yIdx++) { for (xIdx = 0; xIdx < numTilesX; xIdx++) @@ -1164,6 +1188,7 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, (void*) ¶ms[i], &context->priv->ThreadPoolEnv); SubmitThreadpoolWork(work_objects[i]); + close_cnt = i + 1; } else { @@ -1174,11 +1199,11 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, message->tilesDataSize = 0; - for (i = 0; i < message->numTiles; i++) + for (i = 0; i < close_cnt; i++) { tile = message->tiles[i]; - if (context->priv->UseThreads) + if (context->priv->UseThreads && work_objects) { WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); CloseThreadpoolWork(work_objects[i]); @@ -1187,11 +1212,11 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, message->tilesDataSize += rfx_tile_length(tile); } - if (context->priv->UseThreads) - { + if (work_objects) free(work_objects); + + if (params) free(params); - } return message; } diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index ca1845479..aebaa736f 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -365,6 +365,12 @@ BOOL http_response_parse_header(HttpResponse* http_response) char end_of_header_char; char c; + if (!http_response) + return FALSE; + + if (!http_response->lines) + return FALSE; + if (!http_response_parse_header_status_line(http_response, http_response->lines[0])) return FALSE; diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 52aa0030d..3a2008c24 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -399,6 +399,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", versionCaps->tsgHeader.ComponentId); + free(packet); return FALSE; } @@ -436,6 +437,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_CAPS_RESPONSE " "or TSG_PACKET_TYPE_QUARENC_RESPONSE\n", packet->packetId); + free(packet); return FALSE; } @@ -565,7 +567,9 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || (SwitchValue != TSG_PACKET_TYPE_RESPONSE)) { - fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n", packet->packetId); + fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n", + packet->packetId); + free(packet); return FALSE; } @@ -580,6 +584,8 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected Packet Response Flags: 0x%08X, Expected TSG_PACKET_TYPE_QUARREQUEST\n", packetResponse->flags); + free(packet); + free(packetResponse); return FALSE; } @@ -715,7 +721,9 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET)) { - fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n", packet->packetId); + fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n", + packet->packetId); + free(packet); return FALSE; } @@ -783,7 +791,9 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) break; default: - fprintf(stderr, "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", SwitchValue); + fprintf(stderr, "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", + SwitchValue); + free(packet); return FALSE; break; } diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index b74c4ec43..e275ad404 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -279,7 +279,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) int i; void* sin_addr; int peer_sockfd; - freerdp_peer* client; + freerdp_peer* client = NULL; socklen_t peer_addr_size; struct sockaddr_storage peer_addr; rdpListener* listener = (rdpListener*) instance->listener; @@ -306,7 +306,8 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) continue; #endif perror("accept"); - free(client); + if (client) + free(client); return FALSE; } diff --git a/libfreerdp/crypto/er.c b/libfreerdp/crypto/er.c index 04d0c1ca6..e5a5f72f9 100644 --- a/libfreerdp/crypto/er.c +++ b/libfreerdp/crypto/er.c @@ -34,6 +34,13 @@ void er_read_length(wStream* s, int* length) Stream_Read_UINT8(s, byte); + if (!length) + return; + + *length = 0; + if (!s) + return; + if (byte & 0x80) { byte &= ~(0x80); @@ -236,7 +243,7 @@ int er_skip_sequence_tag(int length) BOOL er_read_enumerated(wStream* s, BYTE* enumerated, BYTE count) { - int length; + int length = 0; er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE); er_read_length(s, &length); @@ -320,7 +327,7 @@ int er_skip_octet_string(int length) BOOL er_read_BOOL(wStream* s, BOOL* value) { - int length; + int length = 0; BYTE v; if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE)) @@ -348,7 +355,7 @@ void er_write_BOOL(wStream* s, BOOL value) BOOL er_read_integer(wStream* s, UINT32* value) { - int length; + int length = 0; er_read_universal_tag(s, ER_TAG_INTEGER, FALSE); er_read_length(s, &length); diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index a98f2fb63..ed7c84a44 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -159,22 +159,23 @@ LPSTR CharUpperA(LPSTR lpsz) int i; int length; - length = strlen(lpsz); + if (!lpsz) + return NULL; + length = strlen(lpsz); if (length < 1) return (LPSTR) NULL; if (length == 1) { - LPSTR pc = NULL; char c = *lpsz; if ((c >= 'a') && (c <= 'z')) c = c - 32; - *pc = c; + *lpsz = c; - return pc; + return lpsz; } for (i = 0; i < length; i++) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 843a09fc0..3df76f3d1 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -205,7 +205,11 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); if (status != 0) + { + close(pNamedPipe->clientfd); + free(pNamedPipe); return INVALID_HANDLE_VALUE; + } return hNamedPipe; } diff --git a/winpr/libwinpr/file/pattern.c b/winpr/libwinpr/file/pattern.c index 4a79cd3ce..ff319a1c9 100644 --- a/winpr/libwinpr/file/pattern.c +++ b/winpr/libwinpr/file/pattern.c @@ -314,7 +314,7 @@ BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern) LPSTR lpY; size_t cchX; size_t cchY; - LPSTR lpMatchEnd; + LPSTR lpMatchEnd = NULL; LPSTR lpSubPattern; size_t cchSubPattern; LPSTR lpSubFileName; diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 1bf44f340..ff1b2cf70 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -287,6 +287,8 @@ char* GetCombinedPath(char* basePath, char* subPath) length = basePathLength + subPathLength + 1; path = (char*) malloc(length + 1); + if (!path) + return NULL; CopyMemory(path, basePath, basePathLength); path[basePathLength] = '\0'; diff --git a/winpr/libwinpr/registry/registry_reg.c b/winpr/libwinpr/registry/registry_reg.c index 93cd26031..e986346b1 100644 --- a/winpr/libwinpr/registry/registry_reg.c +++ b/winpr/libwinpr/registry/registry_reg.c @@ -183,6 +183,9 @@ RegVal* reg_load_value(Reg* reg, RegKey* key) BOOL reg_load_has_next_line(Reg* reg) { + if (!reg) + return FALSE; + return (reg->next_line != NULL) ? 1 : 0; } diff --git a/winpr/libwinpr/rpc/ndr_correlation.c b/winpr/libwinpr/rpc/ndr_correlation.c index e12ee35d8..523cf6f1c 100644 --- a/winpr/libwinpr/rpc/ndr_correlation.c +++ b/winpr/libwinpr/rpc/ndr_correlation.c @@ -112,6 +112,9 @@ PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMem break; } + if (!ptr) + return pFormat; + switch (type) { case FC_LONG: diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 487a4d5fc..e1b733a0b 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -650,6 +650,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer message = &context->AUTHENTICATE_MESSAGE; ZeroMemory(message, sizeof(NTLM_AUTHENTICATE_MESSAGE)); + ZeroMemory(&response, sizeof(NTLMv2_RESPONSE)); s = Stream_New(buffer->pvBuffer, buffer->cbBuffer); diff --git a/winpr/libwinpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c index 9e33d8a8a..9cff8b6e0 100644 --- a/winpr/libwinpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -53,6 +53,7 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti if (pipe(semaphore->pipe_fd) < 0) { fprintf(stderr, "CreateSemaphoreW: failed to create semaphore\n"); + free(semaphore); return NULL; } @@ -62,6 +63,7 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti { close(semaphore->pipe_fd[0]); close(semaphore->pipe_fd[1]); + free(semaphore); return FALSE; } diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index bc32ffcdb..32b38a042 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -53,14 +53,20 @@ HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManua #ifdef HAVE_TIMERFD_H timer->fd = timerfd_create(CLOCK_MONOTONIC, 0); - if (timer->fd <= 0) + { + free(timer); return NULL; + } status = fcntl(timer->fd, F_SETFL, O_NONBLOCK); if (status) + { + close(timer->fd); + free(timer); return NULL; + } #endif } diff --git a/winpr/libwinpr/utils/collections/Reference.c b/winpr/libwinpr/utils/collections/Reference.c index 171123661..ab62c366e 100644 --- a/winpr/libwinpr/utils/collections/Reference.c +++ b/winpr/libwinpr/utils/collections/Reference.c @@ -70,6 +70,9 @@ wReference* ReferenceTable_GetFreeEntry(wReferenceTable* referenceTable) if (!found) { + if (!referenceTable->size) + return NULL; + referenceTable->size *= 2; referenceTable->array = (wReference*) realloc(referenceTable->array, sizeof(wReference) * referenceTable->size); From d80214c7fdcd5b1ca66d446883766a7ecff3b14d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 14:18:49 +0200 Subject: [PATCH 071/202] Added clang specific compiler warning suppression. --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a38dd3a19..b85a9a130 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,10 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() -if(CMAKE_COMPILER_IS_CLANG) +if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything -Wno-unused-parameter") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-c11-extensions -Wno-gnu") if(WITH_SSE2) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mssse3") endif() From 2a7ab454ba4b61145156038a4130846866fcc81a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 14:19:09 +0200 Subject: [PATCH 072/202] Fixed static library compilation, using -fPIC now to allow linking to dynamic lib. --- winpr/tools/makecert/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/winpr/tools/makecert/CMakeLists.txt b/winpr/tools/makecert/CMakeLists.txt index c31d08cef..22b0fb9e5 100644 --- a/winpr/tools/makecert/CMakeLists.txt +++ b/winpr/tools/makecert/CMakeLists.txt @@ -27,6 +27,11 @@ include_directories(${OPENSSL_INCLUDE_DIR}) add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) +# This line compiles the static libraries with -fPIC to allow linking +# to shared libraries later on... +# TODO: Remove this non portable way of linking. +set_target_properties(${MODULE_NAME} PROPERTIES COMPILE_FLAGS "-fPIC") + set(${MODULE_PREFIX}_LIBS ${ZLIB_LIBRARIES} ${OPENSSL_LIBRARIES}) From e5c138a5b988cb6e978c3f6723a40bccb3c78c55 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 14:19:50 +0200 Subject: [PATCH 073/202] Fixed various memory leaks, allocation size issues and API misuse warnings shown by clang as well as some compiler warnings. --- channels/rdpsnd/client/rdpsnd_main.c | 4 ++- .../smartcard/client/smartcard_operations.c | 8 +++++- channels/urbdrc/client/urbdrc_main.c | 7 +++++ client/Sample/freerdp.c | 5 ++-- client/X11/generate_argument_docbook.c | 15 ++++++----- client/X11/xf_client.c | 24 ++++++++--------- libfreerdp/codec/mppc_dec.c | 24 ++++++++++++----- libfreerdp/codec/rfx.c | 15 ++++++++--- libfreerdp/core/gateway/http.c | 6 ++++- libfreerdp/core/gateway/tsg.c | 6 +++++ libfreerdp/core/window.c | 12 +++++++-- libfreerdp/crypto/crypto.c | 11 +++++--- libfreerdp/crypto/tls.c | 7 +++++ libfreerdp/rail/icon.c | 7 +++-- server/Sample/sfreerdp.c | 6 ++--- server/X11/xf_interface.c | 3 +-- winpr/include/winpr/collections.h | 6 ++--- winpr/include/winpr/platform.h | 4 +-- winpr/libwinpr/handle/handle.c | 3 +-- winpr/libwinpr/input/scancode.c | 8 +++--- winpr/libwinpr/input/virtualkey.c | 4 +-- winpr/libwinpr/path/shell.c | 3 ++- .../pipe/test/TestPipeCreateNamedPipe.c | 22 +++++++++++++++ .../test/TestPipeCreateNamedPipeOverlapped.c | 27 +++++++++++++++++++ winpr/libwinpr/sspi/sspi.c | 3 +++ winpr/libwinpr/sysinfo/sysinfo.c | 4 +-- .../utils/collections/ListDictionary.c | 2 +- 27 files changed, 180 insertions(+), 66 deletions(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index f8d612276..5047ed76a 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -146,8 +146,10 @@ void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; - rdpsnd->ClientFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * rdpsnd->NumberOfServerFormats); + if (!rdpsnd->NumberOfServerFormats) + return; + rdpsnd->ClientFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * rdpsnd->NumberOfServerFormats); for (index = 0; index < (int) rdpsnd->NumberOfServerFormats; index++) { serverFormat = &rdpsnd->ServerFormats[index]; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index e36b6d8a4..c72f38d47 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1234,7 +1234,10 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); if (!readerStates) + { + free(pAtrMasks); return smartcard_output_return(irp, SCARD_E_NO_MEMORY); + } for (i = 0; i < readerCount; i++) { @@ -1284,6 +1287,8 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + free(readerStates); + free(pAtrMasks); return smartcard_output_return(irp, status); } @@ -1313,7 +1318,7 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) Stream_Write_UINT32(irp->output, 0x00084dd8); Stream_Write_UINT32(irp->output, readerCount); - for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++) + for (i = 0, cur = readerStates; i < readerCount; i++, cur++) { Stream_Write_UINT32(irp->output, cur->dwCurrentState); Stream_Write_UINT32(irp->output, cur->dwEventState); @@ -1328,6 +1333,7 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) smartcard_output_alignment(irp, 8); free(readerStates); + free(pAtrMasks); return status; } diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index d7628f343..e010bba10 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -18,6 +18,7 @@ * limitations under the License. */ +#include #include #include #include @@ -287,6 +288,9 @@ static int urdbrc_send_virtual_channel_add(IWTSVirtualChannel* channel, UINT32 M LLOGLN(10, ("urdbrc_send_virtual_channel_add")); + assert(NULL != channel); + assert(NULL != channel->Write); + InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_DEVICE_SINK); out_size = 12; @@ -830,7 +834,10 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, transfer_data = (TRANSFER_DATA*) malloc(sizeof(TRANSFER_DATA)); if (transfer_data == NULL) + { fprintf(stderr, "transfer_data is NULL!!"); + return 0; + } transfer_data->callback = callback; transfer_data->urbdrc = urbdrc; diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 989281193..87e4eb148 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -206,9 +206,6 @@ int tfreerdp_run(freerdp* instance) fd_set wfds_set; rdpChannels* channels; - ZeroMemory(rfds, sizeof(rfds)); - ZeroMemory(wfds, sizeof(wfds)); - channels = instance->context->channels; freerdp_connect(instance); @@ -218,6 +215,8 @@ int tfreerdp_run(freerdp* instance) rcount = 0; wcount = 0; + ZeroMemory(rfds, sizeof(rfds)); + ZeroMemory(wfds, sizeof(wfds)); if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { printf("Failed to get FreeRDP file descriptor\n"); diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 0c1da21a8..09ac6a36b 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -11,7 +11,7 @@ LPSTR tmp = NULL; -LPCSTR tr_esc_str(LPCSTR arg) +LPSTR tr_esc_str(LPSTR arg) { size_t cs = 0, x, ds; size_t s; @@ -26,7 +26,8 @@ LPCSTR tr_esc_str(LPCSTR arg) s--; /* Prepare a initial buffer with the size of the result string. */ - tmp = malloc(s * sizeof(LPCSTR)); + if (s) + tmp = (LPSTR)malloc(s * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not allocate string buffer."); @@ -41,7 +42,7 @@ LPCSTR tr_esc_str(LPCSTR arg) { case '<': ds += 3; - tmp = realloc(tmp, ds * sizeof(LPCSTR)); + tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not reallocate string buffer."); @@ -54,7 +55,7 @@ LPCSTR tr_esc_str(LPCSTR arg) break; case '>': ds += 3; - tmp = realloc(tmp, ds * sizeof(LPCSTR)); + tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not reallocate string buffer."); @@ -67,7 +68,7 @@ LPCSTR tr_esc_str(LPCSTR arg) break; case '\'': ds += 5; - tmp = realloc(tmp, ds * sizeof(LPCSTR)); + tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not reallocate string buffer."); @@ -82,7 +83,7 @@ LPCSTR tr_esc_str(LPCSTR arg) break; case '"': ds += 5; - tmp = realloc(tmp, ds * sizeof(LPCSTR)); + tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not reallocate string buffer."); @@ -97,7 +98,7 @@ LPCSTR tr_esc_str(LPCSTR arg) break; case '&': ds += 4; - tmp = realloc(tmp, ds * sizeof(LPCSTR)); + tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if( NULL == tmp ) { fprintf(stderr, "Could not reallocate string buffer."); diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 886c3a8d2..4e4bf107f 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1650,7 +1650,7 @@ void xf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e) } } -void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e) +static void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e) { xfContext* xfc = (xfContext*) context; @@ -1668,12 +1668,12 @@ void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChange xf_transform_window(xfc); { - ResizeWindowEventArgs e; + ResizeWindowEventArgs ev; - EventArgsInit(&e, "xfreerdp"); - e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor; - e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor; - PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e); + EventArgsInit(&ev, "xfreerdp"); + ev.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor; + ev.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor; + PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &ev); } xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE); @@ -1683,19 +1683,19 @@ void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChange * Client Interface */ -void xfreerdp_client_global_init() +static void xfreerdp_client_global_init() { setlocale(LC_ALL, ""); freerdp_handle_signals(); freerdp_channels_global_init(); } -void xfreerdp_client_global_uninit() +static void xfreerdp_client_global_uninit() { freerdp_channels_global_uninit(); } -int xfreerdp_client_start(rdpContext* context) +static int xfreerdp_client_start(rdpContext* context) { xfContext* xfc = (xfContext*) context; @@ -1712,7 +1712,7 @@ int xfreerdp_client_start(rdpContext* context) return 0; } -int xfreerdp_client_stop(rdpContext* context) +static int xfreerdp_client_stop(rdpContext* context) { xfContext* xfc = (xfContext*) context; @@ -1735,7 +1735,7 @@ int xfreerdp_client_stop(rdpContext* context) return 0; } -int xfreerdp_client_new(freerdp* instance, rdpContext* context) +static int xfreerdp_client_new(freerdp* instance, rdpContext* context) { xfContext* xfc; rdpSettings* settings; @@ -1791,7 +1791,7 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context) return 0; } -void xfreerdp_client_free(freerdp* instance, rdpContext* context) +static void xfreerdp_client_free(freerdp* instance, rdpContext* context) { xfContext* xfc = (xfContext*) context; diff --git a/libfreerdp/codec/mppc_dec.c b/libfreerdp/codec/mppc_dec.c index ebd8fdc29..b8bd8c4b7 100644 --- a/libfreerdp/codec/mppc_dec.c +++ b/libfreerdp/codec/mppc_dec.c @@ -22,6 +22,7 @@ #include "config.h" #endif +#include #include #include #include @@ -179,8 +180,8 @@ int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U BYTE* src_ptr; /* used while copying compressed data */ BYTE* cptr; /* points to next byte in cbuf */ BYTE cur_byte; /* last byte fetched from cbuf */ - int bits_left; /* bits left in d34 for processing */ - int cur_bits_left; /* bits left in cur_byte for processing */ + unsigned int bits_left; /* bits left in d34 for processing */ + unsigned int cur_bits_left; /* bits left in cur_byte for processing */ int tmp; UINT32 i32; @@ -330,6 +331,7 @@ int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U */ /* how may bits do we need to get? */ + assert(bits_left <= 32); tmp = 32 - bits_left; while (tmp) @@ -338,7 +340,7 @@ int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U { /* we have less bits than we need */ i32 = cur_byte >> (8 - cur_bits_left); - d32 |= i32 << ((32 - bits_left) - cur_bits_left); + d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF; bits_left += cur_bits_left; tmp -= cur_bits_left; if (cptr < cbuf + len) @@ -527,6 +529,8 @@ int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U */ /* how may bits do we need to get? */ + assert(bits_left <= 32); + assert(cur_bits_left <= bits_left); tmp = 32 - bits_left; while (tmp) @@ -535,7 +539,7 @@ int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U { /* we have less bits than we need */ i32 = cur_byte >> (8 - cur_bits_left); - d32 |= i32 << ((32 - bits_left) - cur_bits_left); + d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF; bits_left += cur_bits_left; tmp -= cur_bits_left; if (cptr < cbuf + len) @@ -769,6 +773,8 @@ int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U */ /* how may bits do we need to get? */ + assert(bits_left <= 32); + assert(cur_bits_left <= bits_left); tmp = 32 - bits_left; while (tmp) @@ -777,7 +783,7 @@ int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U { /* we have less bits than we need */ i32 = cur_byte >> (8 - cur_bits_left); - d32 |= i32 << ((32 - bits_left) - cur_bits_left); + d32 |= (32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF; bits_left += cur_bits_left; tmp -= cur_bits_left; if (cptr < cbuf + len) @@ -990,6 +996,8 @@ int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U */ /* how may bits do we need to get? */ + assert(bits_left <= 32); + assert(cur_bits_left <= bits_left); tmp = 32 - bits_left; while (tmp) @@ -998,7 +1006,7 @@ int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U { /* we have less bits than we need */ i32 = cur_byte >> (8 - cur_bits_left); - d32 |= i32 << ((32 - bits_left) - cur_bits_left); + d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF; bits_left += cur_bits_left; tmp -= cur_bits_left; if (cptr < cbuf + len) @@ -1322,6 +1330,8 @@ int decompress_rdp_6(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U */ /* how may bits do we need to get? */ + assert(bits_left <= 32); + assert(cur_bits_left <= bits_left); tmp = 32 - bits_left; while (tmp) @@ -1330,7 +1340,7 @@ int decompress_rdp_6(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U { /* we have less bits than we need */ i32 = cur_byte >> (8 - cur_bits_left); - d32 |= i32 << ((32 - bits_left) - cur_bits_left); + d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF; bits_left += cur_bits_left; tmp -= cur_bits_left; if (cptr < cbuf + len) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 00e6adea6..6cc6e7f14 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include #include @@ -756,6 +757,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (context->priv->UseThreads) { + assert(params); + params[i].context = context; params[i].tile = message->tiles[i]; @@ -1116,15 +1119,19 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, numTilesY = (height + 63) / 64; message->numTiles = numTilesX * numTilesY; - message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE) * message->numTiles); - ZeroMemory(message->tiles, sizeof(RFX_TILE) * message->numTiles); + if (message->numTiles) + { + message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->numTiles); + ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->numTiles); + } DEBUG_RFX("x: %d y: %d width: %d height: %d scanline: %d BytesPerPixel: %d", rect->x, rect->y, width, height, scanline, BytesPerPixel); if (context->priv->UseThreads) { - work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles); + if (message->numTiles) + work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles); if (!work_objects) { free(message); @@ -1181,6 +1188,8 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, if (context->priv->UseThreads) { + assert(params); + params[i].context = context; params[i].tile = tile; diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index aebaa736f..d35a2c869 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -503,7 +503,11 @@ HttpResponse* http_response_recv(rdpTls* tls) } http_response->count = count; - http_response->lines = (char**) malloc(sizeof(char*) * http_response->count); + if (count) + { + http_response->lines = (char**) malloc(sizeof(char*) * http_response->count); + ZeroMemory(http_response->lines, sizeof(char*) * http_response->count); + } count = 0; line = strtok((char*) buffer, "\r\n"); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 3a2008c24..7ff6faa6e 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -295,6 +295,9 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", versionCaps->tsgHeader.ComponentId); + free(packetCapsResponse); + free(versionCaps); + free(packet); return FALSE; } @@ -324,6 +327,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) free(tsgCaps); free(versionCaps); free(packetCapsResponse); + free(packet); return FALSE; } @@ -399,6 +403,8 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", versionCaps->tsgHeader.ComponentId); + free(versionCaps); + free(packetQuarEncResponse); free(packet); return FALSE; } diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 7422f5b1f..ea0a40ff6 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -64,9 +64,17 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* icon_info) /* colorTable */ if (icon_info->colorTable == NULL) - icon_info->colorTable = (BYTE*) malloc(icon_info->cbColorTable); - else + { + if (icon_info->cbColorTable) + icon_info->colorTable = (BYTE*) malloc(icon_info->cbColorTable); + } + else if (icon_info->cbColorTable) icon_info->colorTable = (BYTE*) realloc(icon_info->colorTable, icon_info->cbColorTable); + else + { + free(icon_info->colorTable); + icon_info->colorTable = NULL; + } Stream_Read(s, icon_info->colorTable, icon_info->cbColorTable); /* bitsColor */ diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index f227e9736..e84712ba0 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -395,8 +395,8 @@ char* crypto_cert_subject_common_name(X509* xcert, int* length) char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths) { int index; - int length; - char** strings; + int length = 0; + char** strings = NULL; BYTE* string; int num_subject_alt_names; GENERAL_NAMES* subject_alt_names; @@ -409,8 +409,11 @@ char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths) return NULL; num_subject_alt_names = sk_GENERAL_NAME_num(subject_alt_names); - strings = (char**) malloc(sizeof(char*) * num_subject_alt_names); - *lengths = (int*) malloc(sizeof(int*) * num_subject_alt_names); + if (num_subject_alt_names) + { + strings = (char**) malloc(sizeof(char*) * num_subject_alt_names); + *lengths = (int*) malloc(sizeof(int) * num_subject_alt_names); + } for (index = 0; index < num_subject_alt_names; ++index) { diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 401ef43a1..4eea0d3d6 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include @@ -717,6 +719,9 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name { int index; + assert(NULL != hostname); + assert(NULL != common_name); + fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); fprintf(stderr, "@ WARNING: CERTIFICATE NAME MISMATCH! @\n"); fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); @@ -726,11 +731,13 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name fprintf(stderr, "\t%s\n", common_name ? common_name : "no CN found in certificate"); if (alt_names_count > 1) { + assert(NULL != alt_names); fprintf(stderr, "Alternative names:\n"); if (alt_names_count > 1) { for (index = 0; index < alt_names_count; index++) { + assert(alt_names[index]); fprintf(stderr, "\t %s\n", alt_names[index]); } } diff --git a/libfreerdp/rail/icon.c b/libfreerdp/rail/icon.c index 0dbaab096..04cef8e93 100644 --- a/libfreerdp/rail/icon.c +++ b/libfreerdp/rail/icon.c @@ -93,8 +93,11 @@ rdpIconCache* icon_cache_new(rdpRail* rail) for (i = 0; i < cache->numCaches; i++) { - cache->caches[i].entries = malloc(cache->numCacheEntries * sizeof(rdpIconCache)); - ZeroMemory(cache->caches[i].entries, cache->numCacheEntries * sizeof(rdpIconCache)); + if (cache->numCacheEntries) + { + cache->caches[i].entries = malloc(cache->numCacheEntries * sizeof(rdpIcon)); + ZeroMemory(cache->caches[i].entries, cache->numCacheEntries * sizeof(rdpIcon)); + } } } diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index e988a2e70..b38fe468d 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -658,8 +658,6 @@ static void* test_peer_mainloop(void* arg) testPeerContext* context; freerdp_peer* client = (freerdp_peer*) arg; - memset(rfds, 0, sizeof(rfds)); - test_peer_init(client); /* Initialize the real server settings here */ @@ -694,6 +692,7 @@ static void* test_peer_mainloop(void* arg) { rcount = 0; + memset(rfds, 0, sizeof(rfds)); if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE) { printf("Failed to get FreeRDP file descriptor\n"); @@ -779,12 +778,11 @@ static void test_server_mainloop(freerdp_listener* instance) void* rfds[32]; fd_set rfds_set; - memset(rfds, 0, sizeof(rfds)); - while (1) { rcount = 0; + memset(rfds, 0, sizeof(rfds)); if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) { printf("Failed to get FreeRDP file descriptor\n"); diff --git a/server/X11/xf_interface.c b/server/X11/xf_interface.c index 1c93b5e4e..22e0386fd 100644 --- a/server/X11/xf_interface.c +++ b/server/X11/xf_interface.c @@ -42,8 +42,6 @@ void* xf_server_thread(void* param) xfServer* server; freerdp_listener* listener; - ZeroMemory(rfds, sizeof(rfds)); - server = (xfServer*) param; listener = server->listener; @@ -51,6 +49,7 @@ void* xf_server_thread(void* param) { rcount = 0; + ZeroMemory(rfds, sizeof(rfds)); if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE) { fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 2730ffeca..f06d30458 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -475,9 +475,9 @@ typedef struct _wEventType wEventType; #define DEFINE_EVENT_END(_name) \ } _name ## EventArgs; \ DEFINE_EVENT_HANDLER(_name); \ - DEFINE_EVENT_RAISE(_name); \ - DEFINE_EVENT_SUBSCRIBE(_name); \ - DEFINE_EVENT_UNSUBSCRIBE(_name); + DEFINE_EVENT_RAISE(_name) \ + DEFINE_EVENT_SUBSCRIBE(_name) \ + DEFINE_EVENT_UNSUBSCRIBE(_name) #define DEFINE_EVENT_ENTRY(_name) \ { #_name, { sizeof( _name ## EventArgs) }, 0, { \ diff --git a/winpr/include/winpr/platform.h b/winpr/include/winpr/platform.h index f178b0c95..ad2f6187c 100644 --- a/winpr/include/winpr/platform.h +++ b/winpr/include/winpr/platform.h @@ -156,7 +156,7 @@ /* Mac OS X (__MACOSX__) */ -#if (__APPLE__ && __MACH__) +#if (defined(__APPLE__) && defined(__MACH__)) #ifndef __MACOSX__ #define __MACOSX__ 1 #endif @@ -164,7 +164,7 @@ /* iOS (__IOS__)*/ -#if (__APPLE__ && TARGET_OS_IPHONE) +#if (defined(__APPLE__) && defined(TARGET_OS_IPHONE)) #ifndef __IOS__ #define __IOS__ 1 #endif diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index 3031b032c..31ac5641b 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -48,8 +48,7 @@ BOOL CloseHandle(HANDLE hObject) WINPR_THREAD* thread; thread = (WINPR_THREAD*) Object; - - free(Object); + free(thread); return TRUE; } diff --git a/winpr/libwinpr/input/scancode.c b/winpr/libwinpr/input/scancode.c index e543fa81d..fe08882d5 100644 --- a/winpr/libwinpr/input/scancode.c +++ b/winpr/libwinpr/input/scancode.c @@ -33,7 +33,7 @@ * Keyboard Type 4 */ -DWORD KBD4T[128] = +static DWORD KBD4T[128] = { KBD4_T00, KBD4_T01, @@ -165,7 +165,7 @@ DWORD KBD4T[128] = KBD4_T7F }; -DWORD KBD4X[128] = +static DWORD KBD4X[128] = { VK_NONE, VK_NONE, @@ -301,7 +301,7 @@ DWORD KBD4X[128] = * Keyboard Type 7 */ -DWORD KBD7T[128] = +static DWORD KBD7T[128] = { KBD7_T00, KBD7_T01, @@ -433,7 +433,7 @@ DWORD KBD7T[128] = KBD7_T7F }; -DWORD KBD7X[128] = +static DWORD KBD7X[128] = { VK_NONE, VK_NONE, diff --git a/winpr/libwinpr/input/virtualkey.c b/winpr/libwinpr/input/virtualkey.c index d5f8dd17b..64f71f056 100644 --- a/winpr/libwinpr/input/virtualkey.c +++ b/winpr/libwinpr/input/virtualkey.c @@ -437,7 +437,7 @@ char* GetVirtualKeyName(DWORD vkcode) DWORD GetVirtualKeyCodeFromName(const char* vkname) { - int i; + unsigned long i; for (i = 0; i < ARRAYSIZE(VIRTUAL_KEY_CODE_TABLE); i++) { @@ -453,7 +453,7 @@ DWORD GetVirtualKeyCodeFromName(const char* vkname) DWORD GetVirtualKeyCodeFromXkbKeyName(const char* xkbname) { - int i; + unsigned long i; for (i = 0; i < ARRAYSIZE(XKB_KEYNAME_TABLE); i++) { diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index ff1b2cf70..573ee0320 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -290,7 +290,8 @@ char* GetCombinedPath(char* basePath, char* subPath) if (!path) return NULL; - CopyMemory(path, basePath, basePathLength); + if (basePath) + CopyMemory(path, basePath, basePathLength); path[basePathLength] = '\0'; PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE); diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c index 5204217fa..a6d4686b6 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c @@ -55,6 +55,11 @@ static void* named_pipe_client_thread(void* arg) if (!fSuccess || (lpNumberOfBytesWritten == 0)) { printf("Client NamedPipe WriteFile failure\n"); + + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); return NULL; } @@ -68,6 +73,10 @@ static void* named_pipe_client_thread(void* arg) if (!fSuccess || (lpNumberOfBytesRead == 0)) { printf("Client NamedPipe ReadFile failure\n"); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); return NULL; } @@ -120,6 +129,8 @@ static void* named_pipe_server_thread(void* arg) if (!fConnected) { printf("ConnectNamedPipe failure\n"); + + CloseHandle(hNamedPipe); return NULL; } @@ -136,6 +147,10 @@ static void* named_pipe_server_thread(void* arg) if (!fSuccess || (lpNumberOfBytesRead == 0)) { printf("Server NamedPipe ReadFile failure\n"); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); return NULL; } @@ -152,6 +167,10 @@ static void* named_pipe_server_thread(void* arg) if (!fSuccess || (lpNumberOfBytesWritten == 0)) { printf("Server NamedPipe WriteFile failure\n"); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); return NULL; } @@ -176,6 +195,9 @@ int TestPipeCreateNamedPipe(int argc, char* argv[]) WaitForSingleObject(ClientThread, INFINITE); WaitForSingleObject(ServerThread, INFINITE); + CloseHandle(ClientThread); + CloseHandle(ServerThread); + return 0; } diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c index f5524c3f8..fe71bff6a 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c @@ -63,6 +63,11 @@ static void* named_pipe_client_thread(void* arg) if (!fSuccess) { printf("Client NamedPipe WriteFile failure: %d\n", GetLastError()); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); + CloseHandle(hEvent); return NULL; } @@ -85,6 +90,11 @@ static void* named_pipe_client_thread(void* arg) if (!fSuccess) { printf("Client NamedPipe ReadFile failure: %d\n", GetLastError()); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); + CloseHandle(hEvent); return NULL; } @@ -160,6 +170,10 @@ static void* named_pipe_server_thread(void* arg) if (!fConnected) { printf("ConnectNamedPipe failure: %d\n", GetLastError()); + + CloseHandle(hNamedPipe); + CloseHandle(hEvent); + return NULL; } @@ -178,6 +192,12 @@ static void* named_pipe_server_thread(void* arg) if (!fSuccess) { printf("Server NamedPipe ReadFile failure: %d\n", GetLastError()); + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); + CloseHandle(hEvent); + return NULL; } @@ -203,6 +223,13 @@ static void* named_pipe_server_thread(void* arg) if (!fSuccess) { printf("Server NamedPipe WriteFile failure: %d\n", GetLastError()); + + free(lpReadBuffer); + free(lpWriteBuffer); + + CloseHandle(hNamedPipe); + CloseHandle(hEvent); + return NULL; } diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index 96c959995..c0562bd56 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -140,10 +140,13 @@ void sspi_ContextBufferAllocTableNew() void sspi_ContextBufferAllocTableGrow() { size_t size; + ContextBufferAllocTable.entries = NULL; ContextBufferAllocTable.cEntries = 0; ContextBufferAllocTable.cMaxEntries *= 2; size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries; + if (!size) + return; ContextBufferAllocTable.entries = realloc(ContextBufferAllocTable.entries, size); ZeroMemory((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], size / 2); diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index 356b0a9b8..9091c5e84 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -90,7 +90,7 @@ defined(__OpenBSD__) || defined(__DragonFly__) #include #endif -DWORD GetProcessorArchitecture() +static DWORD GetProcessorArchitecture() { DWORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN; @@ -113,7 +113,7 @@ DWORD GetProcessorArchitecture() return cpuArch; } -DWORD GetNumberOfProcessors() +static DWORD GetNumberOfProcessors() { DWORD numCPUs = 1; diff --git a/winpr/libwinpr/utils/collections/ListDictionary.c b/winpr/libwinpr/utils/collections/ListDictionary.c index cb7ba420a..aa817a50d 100644 --- a/winpr/libwinpr/utils/collections/ListDictionary.c +++ b/winpr/libwinpr/utils/collections/ListDictionary.c @@ -248,7 +248,7 @@ void ListDictionary_Remove(wListDictionary* listDictionary, void* key) void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key) { void* value = NULL; - wListDictionaryItem* item; + wListDictionaryItem* item = NULL; if (listDictionary->synchronized) EnterCriticalSection(&listDictionary->lock); From b190a16c5d0dc955b3da9e155d4de688adfc9b98 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 14:47:00 +0200 Subject: [PATCH 074/202] Fixed argument checks, now NULL pointer are no longer dereferenced in functions. --- libfreerdp/codec/color.c | 12 ++++++-- libfreerdp/gdi/16bpp.c | 47 ++++++++++++++++++++++++++++- libfreerdp/gdi/32bpp.c | 64 +++++++++++++++++++++++++++++++++++----- libfreerdp/gdi/8bpp.c | 47 ++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 12 deletions(-) diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 69a237511..8c9499c68 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -909,7 +909,11 @@ BYTE* freerdp_icon_convert(BYTE* srcData, BYTE* dstData, BYTE* mask, int width, for (bit = 0; bit < 8; bit++) if ((bmask & (0x80 >> bit)) == 0) - *(icon + (height - y - 1) * width + x + bit) |= 0xFF000000; + { + UINT32 *tmp = (icon + (height - y - 1) * width + x + bit); + if (tmp) + *tmp |= 0xFF000000; + } } if ((width % 8) != 0) @@ -918,7 +922,11 @@ BYTE* freerdp_icon_convert(BYTE* srcData, BYTE* dstData, BYTE* mask, int width, for (bit = 0; bit < width % 8; bit++) if ((bmask & (0x80 >> bit)) == 0) - *(icon + (height - y - 1) * width + x + bit) |= 0xFF000000; + { + UINT32 *tmp = (icon + (height - y - 1) * width + x + bit); + if (tmp) + *tmp |= 0xFF000000; + } } /* Skip padding */ diff --git a/libfreerdp/gdi/16bpp.c b/libfreerdp/gdi/16bpp.c index 9437ea6d6..c634ae6d3 100644 --- a/libfreerdp/gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -143,6 +143,9 @@ static int BitBlt_SRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) { @@ -204,6 +207,9 @@ static int BitBlt_NOTSRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -251,6 +257,9 @@ static int BitBlt_SRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -276,6 +285,9 @@ static int BitBlt_NOTSRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -301,6 +313,9 @@ static int BitBlt_SRCINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -326,6 +341,9 @@ static int BitBlt_SRCAND_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -351,6 +369,9 @@ static int BitBlt_SRCPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -379,6 +400,9 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT16 color16; HGDI_BITMAP hSrcBmp; + if (!hdcDst || !hdcSrc) + return 1; + /* D = (S & P) | (~S & D) */ /* DSPDxax, used to draw glyphs */ @@ -420,6 +444,9 @@ static int BitBlt_PSDPxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT16* patp; UINT16 color16; + if (!hdcSrc || !hdcDest) + return 1; + /* D = (S & D) | (~S & P) */ if (hdcDest->brush->style == GDI_BS_SOLID) @@ -473,6 +500,9 @@ static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT16* dstp; UINT16* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -548,6 +578,9 @@ static int BitBlt_DSna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -575,6 +608,9 @@ static int BitBlt_MERGECOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n UINT16* dstp; UINT16* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -601,6 +637,9 @@ static int BitBlt_MERGEPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT16* srcp; UINT16* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -732,6 +771,9 @@ static int BitBlt_PATPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT16* dstp; UINT16* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -769,7 +811,10 @@ int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh } gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); - + + if (!hdcDest) + return 1; + switch (rop) { case GDI_BLACKNESS: diff --git a/libfreerdp/gdi/32bpp.c b/libfreerdp/gdi/32bpp.c index d3d91c0b9..39803f266 100644 --- a/libfreerdp/gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -160,6 +160,9 @@ static int BitBlt_SRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* srcp; BYTE* dstp; + if (!hdcDst || !hdcSrc) + return 1; + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) { @@ -220,7 +223,10 @@ static int BitBlt_NOTSRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int int x, y; UINT32* srcp; UINT32* dstp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -267,7 +273,10 @@ static int BitBlt_SRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW int x, y; UINT32* srcp; UINT32* dstp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -292,7 +301,10 @@ static int BitBlt_NOTSRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int int x, y; UINT32* srcp; UINT32* dstp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -317,7 +329,10 @@ static int BitBlt_SRCINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n int x, y; UINT32* srcp; UINT32* dstp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -342,7 +357,10 @@ static int BitBlt_SRCAND_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid int x, y; UINT32* srcp; UINT32* dstp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -368,6 +386,9 @@ static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT32* srcp; UINT32* dstp; + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -398,6 +419,9 @@ static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32 color32; HGDI_BITMAP hSrcBmp; + if (!hdcDst || !hdcSrc) + return 1; + /* D = (S & P) | (~S & D) */ color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor); @@ -460,6 +484,9 @@ static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32* patp; UINT32 color32; + if (!hdcDst || !hdcSrc) + return 1; + /* D = (S & D) | (~S & P) */ if (hdcDest->brush->style == GDI_BS_SOLID) @@ -514,6 +541,9 @@ static int BitBlt_SPDSxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32* patp; UINT32 color32; + if (!hdcDst || !hdcSrc) + return 1; + /* D = S ^ (P & (D ^ S)) */ if (hdcDest->brush->style == GDI_BS_SOLID) @@ -566,7 +596,10 @@ static int BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT32* srcp; UINT32* dstp; UINT32* patp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -594,6 +627,9 @@ static int BitBlt_DSna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT32* srcp; UINT32* dstp; + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -670,6 +706,9 @@ static int BitBlt_MERGECOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n UINT32* dstp; UINT32* patp; + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -697,6 +736,9 @@ static int BitBlt_MERGEPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT32* srcp; UINT32* dstp; + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -827,7 +869,10 @@ static int BitBlt_PATPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT32* srcp; UINT32* dstp; UINT32* patp; - + + if (!hdcDst || !hdcSrc) + return 1; + for (y = 0; y < nHeight; y++) { srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -865,7 +910,10 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh } gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); - + + if (!hdcDest) + return 1; + switch (rop) { case GDI_BLACKNESS: diff --git a/libfreerdp/gdi/8bpp.c b/libfreerdp/gdi/8bpp.c index c4966cece..0999cedcb 100644 --- a/libfreerdp/gdi/8bpp.c +++ b/libfreerdp/gdi/8bpp.c @@ -88,6 +88,9 @@ static int BitBlt_SRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) { @@ -149,6 +152,9 @@ static int BitBlt_NOTSRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -196,6 +202,9 @@ static int BitBlt_SRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -221,6 +230,9 @@ static int BitBlt_NOTSRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -246,6 +258,9 @@ static int BitBlt_SRCINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -271,6 +286,9 @@ static int BitBlt_SRCAND_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidt BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -296,6 +314,9 @@ static int BitBlt_SRCPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -317,6 +338,9 @@ static int BitBlt_SRCPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) { + if (!hdcSrc || !hdcDest) + return 1; + /* TODO: Implement 8bpp DSPDxax BitBlt */ return 0; } @@ -329,6 +353,9 @@ static int BitBlt_PSDPxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid BYTE* patp; BYTE color8; + if (!hdcSrc || !hdcDest) + return 1; + /* D = (S & D) | (~S & P) */ if (hdcDest->brush->style == GDI_BS_SOLID) @@ -382,6 +409,9 @@ static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, BYTE* dstp; BYTE* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -461,6 +491,9 @@ static int BitBlt_DSna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -487,6 +520,9 @@ static int BitBlt_MERGECOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW BYTE* dstp; BYTE* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -515,6 +551,9 @@ static int BitBlt_MERGEPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n BYTE* srcp; BYTE* dstp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -646,6 +685,9 @@ static int BitBlt_PATPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* dstp; BYTE* patp; + if (!hdcSrc || !hdcDest) + return 1; + for (y = 0; y < nHeight; y++) { srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); @@ -682,7 +724,10 @@ int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight } gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); - + + if (!hdcDest) + return 1; + switch (rop) { case GDI_BLACKNESS: From 4331fa1f8b750f531709164840809c6fb9262fa4 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 16:29:25 +0200 Subject: [PATCH 075/202] Fixed invalid API usage, ... --- libfreerdp/gdi/16bpp.c | 2 +- libfreerdp/gdi/32bpp.c | 30 ++++++------- winpr/libwinpr/file/pattern.c | 3 ++ winpr/libwinpr/registry/registry_reg.c | 62 ++++++++++++++++++-------- winpr/libwinpr/registry/registry_reg.h | 5 +++ 5 files changed, 67 insertions(+), 35 deletions(-) diff --git a/libfreerdp/gdi/16bpp.c b/libfreerdp/gdi/16bpp.c index c634ae6d3..3f96425e6 100644 --- a/libfreerdp/gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -400,7 +400,7 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT16 color16; HGDI_BITMAP hSrcBmp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; /* D = (S & P) | (~S & D) */ diff --git a/libfreerdp/gdi/32bpp.c b/libfreerdp/gdi/32bpp.c index 39803f266..33e1d19d9 100644 --- a/libfreerdp/gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -160,7 +160,7 @@ static int BitBlt_SRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi BYTE* srcp; BYTE* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; if ((hdcDest->selectedObject != hdcSrc->selectedObject) || @@ -224,7 +224,7 @@ static int BitBlt_NOTSRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -274,7 +274,7 @@ static int BitBlt_SRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -302,7 +302,7 @@ static int BitBlt_NOTSRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -330,7 +330,7 @@ static int BitBlt_SRCINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -358,7 +358,7 @@ static int BitBlt_SRCAND_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -386,7 +386,7 @@ static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -419,7 +419,7 @@ static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32 color32; HGDI_BITMAP hSrcBmp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; /* D = (S & P) | (~S & D) */ @@ -484,7 +484,7 @@ static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32* patp; UINT32 color32; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; /* D = (S & D) | (~S & P) */ @@ -541,7 +541,7 @@ static int BitBlt_SPDSxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi UINT32* patp; UINT32 color32; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; /* D = S ^ (P & (D ^ S)) */ @@ -597,7 +597,7 @@ static int BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT32* dstp; UINT32* patp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -627,7 +627,7 @@ static int BitBlt_DSna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -706,7 +706,7 @@ static int BitBlt_MERGECOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n UINT32* dstp; UINT32* patp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -736,7 +736,7 @@ static int BitBlt_MERGEPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int UINT32* srcp; UINT32* dstp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) @@ -870,7 +870,7 @@ static int BitBlt_PATPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW UINT32* dstp; UINT32* patp; - if (!hdcDst || !hdcSrc) + if (!hdcDest || !hdcSrc) return 1; for (y = 0; y < nHeight; y++) diff --git a/winpr/libwinpr/file/pattern.c b/winpr/libwinpr/file/pattern.c index ff319a1c9..8e158058b 100644 --- a/winpr/libwinpr/file/pattern.c +++ b/winpr/libwinpr/file/pattern.c @@ -86,6 +86,9 @@ BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName, size_t cchFileName, { LPSTR lpMatch; + if (!lpFileName) + return FALSE; + if (*lpWildcard == '*') { /* diff --git a/winpr/libwinpr/registry/registry_reg.c b/winpr/libwinpr/registry/registry_reg.c index e986346b1..559c4a904 100644 --- a/winpr/libwinpr/registry/registry_reg.c +++ b/winpr/libwinpr/registry/registry_reg.c @@ -31,8 +31,8 @@ #define WINPR_HKLM_HIVE "/etc/winpr/HKLM.reg" -void reg_print_key(Reg* reg, RegKey* key); -void reg_print_value(Reg* reg, RegVal* value); +static void reg_print_key(Reg* reg, RegKey* key); +static void reg_print_value(Reg* reg, RegVal* value); struct reg_data_type { @@ -41,7 +41,7 @@ struct reg_data_type DWORD type; }; -struct reg_data_type REG_DATA_TYPE_TABLE[] = +static struct reg_data_type REG_DATA_TYPE_TABLE[] = { { "\"", 1, REG_SZ }, { "dword:", 6, REG_DWORD }, @@ -55,7 +55,7 @@ struct reg_data_type REG_DATA_TYPE_TABLE[] = { NULL, 0, 0 } }; -char* REG_DATA_TYPE_STRINGS[] = +static char* REG_DATA_TYPE_STRINGS[] = { "REG_NONE", "REG_SZ", @@ -71,7 +71,7 @@ char* REG_DATA_TYPE_STRINGS[] = "REG_QWORD" }; -void reg_load_start(Reg* reg) +static void reg_load_start(Reg* reg) { long int file_size; @@ -79,6 +79,10 @@ void reg_load_start(Reg* reg) file_size = ftell(reg->fp); fseek(reg->fp, 0, SEEK_SET); + reg->line = NULL; + reg->next_line = NULL; + reg->buffer = NULL; + if (file_size < 1) return; @@ -87,24 +91,41 @@ void reg_load_start(Reg* reg) if (fread(reg->buffer, file_size, 1, reg->fp) != 1) { free(reg->buffer); + reg->buffer = NULL; return; } reg->buffer[file_size] = '\n'; reg->buffer[file_size + 1] = '\0'; - reg->line = NULL; reg->next_line = strtok(reg->buffer, "\n"); } -void reg_load_finish(Reg* reg) +static void reg_load_finish(Reg* reg) { - free(reg->buffer); - reg->buffer = NULL; - reg->line = NULL; + if (!reg) + return; + + if (reg->buffer) + { + free(reg->buffer); + reg->buffer = NULL; + } + + if (reg->line) + { + free(reg->line); + reg->line = NULL; + } + + if (reg->next_line) + { + free(reg->next_line); + reg->next_line = NULL; + } } -RegVal* reg_load_value(Reg* reg, RegKey* key) +static RegVal* reg_load_value(Reg* reg, RegKey* key) { int index; char* p[5]; @@ -181,16 +202,19 @@ RegVal* reg_load_value(Reg* reg, RegKey* key) return value; } -BOOL reg_load_has_next_line(Reg* reg) +static BOOL reg_load_has_next_line(Reg* reg) { if (!reg) - return FALSE; + return 0; return (reg->next_line != NULL) ? 1 : 0; } -char* reg_load_get_next_line(Reg* reg) +static char* reg_load_get_next_line(Reg* reg) { + if (!reg) + return NULL; + reg->line = reg->next_line; reg->next_line = strtok(NULL, "\n"); reg->line_length = strlen(reg->line); @@ -198,12 +222,12 @@ char* reg_load_get_next_line(Reg* reg) return reg->line; } -char* reg_load_peek_next_line(Reg* reg) +static char* reg_load_peek_next_line(Reg* reg) { return reg->next_line; } -void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) +static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) { char* name; char* path; @@ -229,7 +253,7 @@ void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) free(path); } -RegKey* reg_load_key(Reg* reg, RegKey* key) +static RegKey* reg_load_key(Reg* reg, RegKey* key) { char* p[2]; int length; @@ -303,7 +327,7 @@ void reg_load(Reg* reg) reg_load_finish(reg); } -void reg_unload_value(Reg* reg, RegVal* value) +static void reg_unload_value(Reg* reg, RegVal* value) { if (value->type == REG_DWORD) { @@ -321,7 +345,7 @@ void reg_unload_value(Reg* reg, RegVal* value) free(value); } -void reg_unload_key(Reg* reg, RegKey* key) +static void reg_unload_key(Reg* reg, RegKey* key) { RegVal* pValue; RegVal* pValueNext; diff --git a/winpr/libwinpr/registry/registry_reg.h b/winpr/libwinpr/registry/registry_reg.h index ac5192629..0c07e5c7a 100644 --- a/winpr/libwinpr/registry/registry_reg.h +++ b/winpr/libwinpr/registry/registry_reg.h @@ -16,6 +16,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef REGISTRY_REG_H_ +#define REGISTRY_REG_H_ #include @@ -62,3 +64,6 @@ struct _reg_key }; Reg* reg_open(BOOL read_only); +void reg_close(Reg *reg); + +#endif From 7bc0cbdabf491ff25274487fa5c76bfe216ae654 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 16:30:27 +0200 Subject: [PATCH 076/202] Fixed clang issues. --- .../smartcard/client/smartcard_operations.c | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index c72f38d47..695e53344 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -23,13 +23,11 @@ #include "config.h" #endif +#include #include #include #include -#include #include -#include -#include #define BOOL PCSC_BOOL #include @@ -153,6 +151,7 @@ static void smartcard_output_buffer_limit(IRP* irp, char* buffer, unsigned int l } else { + assert(NULL != buffer); if (header < length) length = header; @@ -485,6 +484,11 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); + if (!cur->szReader) + { + DEBUG_WARN("cur->szReader=%p", cur->szReader); + continue; + } if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } @@ -966,15 +970,19 @@ static UINT32 handle_Transmit(IRP* irp) Stream_Write_UINT32(irp->output, 0); /* pioRecvPci 0x00; */ - smartcard_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ - - smartcard_output_buffer(irp, (char*) recvBuf, cbRecvLength); + if (recvBuf) + { + smartcard_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ + smartcard_output_buffer(irp, (char*) recvBuf, cbRecvLength); + } } smartcard_output_alignment(irp, 8); - free(sendBuf); - free(recvBuf); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); return status; } @@ -1277,6 +1285,11 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); + if (!cur->szReader) + { + DEBUG_WARN("cur->szReader=%p", cur->szReader); + continue; + } if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } From ef91766cf34b2e996f8912d42505ad028ae95d44 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 16:31:23 +0200 Subject: [PATCH 077/202] Fixed clang issues. --- libfreerdp/core/rdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 867fd5c1b..4b66e6555 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -784,7 +784,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) UINT16 pduType; UINT16 pduLength; UINT16 pduSource; - UINT16 channelId; + UINT16 channelId = 0; UINT16 securityFlags; int nextPosition; From e2e96b8c55ad8ac92a207a2ac346c50cb3fbc252 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Aug 2013 16:31:40 +0200 Subject: [PATCH 078/202] Fixed clang issues. --- libfreerdp/core/window.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index ea0a40ff6..652aa536d 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -75,7 +75,8 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* icon_info) free(icon_info->colorTable); icon_info->colorTable = NULL; } - Stream_Read(s, icon_info->colorTable, icon_info->cbColorTable); + if (icon_info->colorTable) + Stream_Read(s, icon_info->colorTable, icon_info->cbColorTable); /* bitsColor */ if (icon_info->bitsColor == NULL) From 62356e667c0de5f8df97d589333ddfefe1f5c8bd Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 09:12:33 +0200 Subject: [PATCH 079/202] Fixed erroneous patch. --- winpr/libwinpr/sspi/sspi.c | 2 +- winpr/libwinpr/synch/semaphore.c | 2 +- winpr/libwinpr/utils/collections/Reference.c | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index c0562bd56..1869baca4 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -128,6 +128,7 @@ void sspi_ContextBufferAllocTableNew() { size_t size; + ContextBufferAllocTable.entries = NULL; ContextBufferAllocTable.cEntries = 0; ContextBufferAllocTable.cMaxEntries = 4; @@ -140,7 +141,6 @@ void sspi_ContextBufferAllocTableNew() void sspi_ContextBufferAllocTableGrow() { size_t size; - ContextBufferAllocTable.entries = NULL; ContextBufferAllocTable.cEntries = 0; ContextBufferAllocTable.cMaxEntries *= 2; diff --git a/winpr/libwinpr/synch/semaphore.c b/winpr/libwinpr/synch/semaphore.c index 9cff8b6e0..aad257e8c 100644 --- a/winpr/libwinpr/synch/semaphore.c +++ b/winpr/libwinpr/synch/semaphore.c @@ -64,7 +64,7 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti close(semaphore->pipe_fd[0]); close(semaphore->pipe_fd[1]); free(semaphore); - return FALSE; + return NULL; } lInitialCount--; diff --git a/winpr/libwinpr/utils/collections/Reference.c b/winpr/libwinpr/utils/collections/Reference.c index ab62c366e..c2df4773f 100644 --- a/winpr/libwinpr/utils/collections/Reference.c +++ b/winpr/libwinpr/utils/collections/Reference.c @@ -71,10 +71,16 @@ wReference* ReferenceTable_GetFreeEntry(wReferenceTable* referenceTable) if (!found) { if (!referenceTable->size) + { + if (referenceTable->array) + free(referenceTable->array); + referenceTable->array = NULL; return NULL; + } referenceTable->size *= 2; - referenceTable->array = (wReference*) realloc(referenceTable->array, sizeof(wReference) * referenceTable->size); + referenceTable->array = (wReference*) realloc(referenceTable->array, + sizeof(wReference) * referenceTable->size); ZeroMemory(&referenceTable->array[(referenceTable->size / 2)], sizeof(wReference) * (referenceTable->size / 2)); From 854aa3fcfa1b01c3bdc0b2df416e39827afb25a3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 10:57:33 +0200 Subject: [PATCH 080/202] Fixed memory leak. --- channels/rdpsnd/client/rdpsnd_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 5047ed76a..5b7d36af4 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -381,7 +381,10 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) { - MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) wave, NULL); + RDPSND_WAVE *copy = malloc(sizeof(RDPSND_WAVE)); + CopyMemory(copy, wave, sizeof(RDPSND_WAVE)); + + MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) copy, NULL); } static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) @@ -444,6 +447,7 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS; rdpsnd->device->WaveConfirm(rdpsnd->device, wave); } + free(wave); } static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd) From f553b04bf098be5ccb25fa94a68e6aa3e8d96fa3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 10:57:44 +0200 Subject: [PATCH 081/202] Fixed memory leak. --- libfreerdp/cache/brush.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libfreerdp/cache/brush.c b/libfreerdp/cache/brush.c index 8b991a395..b4e5373c1 100644 --- a/libfreerdp/cache/brush.c +++ b/libfreerdp/cache/brush.c @@ -22,7 +22,7 @@ #endif #include - +#include #include #include @@ -73,7 +73,7 @@ void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) brush->style = style; } -void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) +static void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) { int length; void* data = NULL; @@ -91,6 +91,9 @@ void* brush_cache_get(rdpBrushCache* brush, UINT32 index, UINT32* bpp) { void* entry; + assert(brush); + assert(bpp); + if (*bpp == 1) { if (index >= brush->maxMonoEntries) @@ -132,6 +135,8 @@ void brush_cache_put(rdpBrushCache* brush, UINT32 index, void* entry, UINT32 bpp if (index >= brush->maxMonoEntries) { fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + if (entry) + free(entry); return; } @@ -148,6 +153,8 @@ void brush_cache_put(rdpBrushCache* brush, UINT32 index, void* entry, UINT32 bpp if (index >= brush->maxEntries) { fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + if (entry) + free(entry); return; } From ddb664d6e7c56b379b16792333deefdf4bec7a99 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 10:58:07 +0200 Subject: [PATCH 082/202] Fixed memory leak. --- libfreerdp/codec/rfx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 6cc6e7f14..75b097359 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -297,6 +297,12 @@ RFX_CONTEXT* rfx_context_new(void) void rfx_context_free(RFX_CONTEXT* context) { + assert(NULL != context); + assert(NULL != context->quants); + assert(NULL != context->priv); + assert(NULL != context->priv->TilePool); + assert(NULL != context->priv->BufferPool); + free(context->quants); ObjectPool_Free(context->priv->TilePool); @@ -1141,6 +1147,8 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); if (!params) { + if (message->tiles) + free(message->tiles); free(message); free(work_objects); return NULL; From 35a558be9e8817d15716c72b52a7ebb711a80072 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 10:58:19 +0200 Subject: [PATCH 083/202] Fixed memory leak. --- libfreerdp/cache/palette.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libfreerdp/cache/palette.c b/libfreerdp/cache/palette.c index 0e249ec3c..0d93b1ab8 100644 --- a/libfreerdp/cache/palette.c +++ b/libfreerdp/cache/palette.c @@ -27,7 +27,8 @@ #include -void update_gdi_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table) +static void update_gdi_cache_color_table(rdpContext* context, + CACHE_COLOR_TABLE_ORDER* cache_color_table) { UINT32* colorTable; rdpCache* cache = context->cache; @@ -49,7 +50,6 @@ void* palette_cache_get(rdpPaletteCache* palette_cache, UINT32 index) } entry = palette_cache->entries[index].entry; - if (entry == NULL) { fprintf(stderr, "invalid color table at index: 0x%04X\n", index); @@ -64,9 +64,14 @@ void palette_cache_put(rdpPaletteCache* palette_cache, UINT32 index, void* entry if (index >= palette_cache->maxEntries) { fprintf(stderr, "invalid color table index: 0x%04X\n", index); + if (entry) + free(entry); return; } + if(NULL == palette_cache->entries[index].entry) + free(palette_cache->entries[index].entry); + palette_cache->entries[index].entry = entry; } @@ -97,6 +102,13 @@ void palette_cache_free(rdpPaletteCache* palette_cache) { if (palette_cache != NULL) { + int i; + + for (i=0; imaxEntries; i++) + { + if (palette_cache->entries[i].entry) + free(palette_cache->entries[i].entry); + } free(palette_cache->entries); free(palette_cache); } From 6ac0b10158f1d3df269af04a72a7922e30739c3d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 12:47:21 +0200 Subject: [PATCH 084/202] Removed buffer copy, still fixes memory leak. --- channels/rdpsnd/client/rdpsnd_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 5b7d36af4..9411380aa 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -381,10 +381,7 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) { - RDPSND_WAVE *copy = malloc(sizeof(RDPSND_WAVE)); - CopyMemory(copy, wave, sizeof(RDPSND_WAVE)); - - MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) copy, NULL); + MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) wave, NULL); } static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) @@ -447,7 +444,8 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS; rdpsnd->device->WaveConfirm(rdpsnd->device, wave); } - free(wave); + else + free(wave); } static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd) From 61c0c98dac1d9f447ecd7f9f2272d411b21f6d3a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 15:06:25 +0200 Subject: [PATCH 085/202] Fixed missing free for subbuffers of packet. --- libfreerdp/core/gateway/tsg.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 7ff6faa6e..33ce77173 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -694,6 +694,7 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSER BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { + BOOL rc = TRUE; BYTE* buffer; UINT32 length; UINT32 offset; @@ -799,15 +800,22 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) default: fprintf(stderr, "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", SwitchValue); - free(packet); - return FALSE; + rc = FALSE; break; } if (packet) + { + if (packet->tsgPacket.packetMsgResponse) + { + if (packet->tsgPacket.packetMsgResponse->messagePacket.reauthMessage) + free(packet->tsgPacket.packetMsgResponse->messagePacket.reauthMessage); + free(packet->tsgPacket.packetMsgResponse); + } free(packet); + } - return TRUE; + return rc; } BOOL TsProxyMakeTunnelCall(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext, From 853bf403214896d3471191bf09c364826e457984 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 15:07:39 +0200 Subject: [PATCH 086/202] Fixed memory cleanup issue --- libfreerdp/codec/rfx.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 75b097359..e1d5f9def 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -590,6 +590,7 @@ void CALLBACK rfx_process_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, wStream* s) { + BOOL rc; int i, close_cnt; int pos; BYTE quant; @@ -705,6 +706,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa /* tiles */ close_cnt = 0; + rc = TRUE; for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); @@ -713,11 +715,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa if (Stream_GetRemainingLength(s) < 6) { DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->numTiles); - if (work_objects) - free(work_objects); - if (params) - free(params); - return FALSE; + rc = FALSE; + break; } Stream_Read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ @@ -727,11 +726,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa { DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->numTiles, blockLen); - if (work_objects) - free(work_objects); - if (params) - free(params); - return FALSE; + rc = FALSE; + break; } pos = Stream_GetPosition(s) - 6 + blockLen; @@ -803,7 +799,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa tile->YData = tile->CbData = tile->CrData = NULL; } - return TRUE; + return rc; } RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) From ddab90ece4b9bdefa04e7c55ade5462fdf58cdef Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 2 Sep 2013 16:14:22 +0200 Subject: [PATCH 087/202] Fixed alt_names free, now using cleanup function to wrap details. --- include/freerdp/crypto/crypto.h | 5 ++++- libfreerdp/crypto/crypto.c | 20 ++++++++++++++++++++ libfreerdp/crypto/tls.c | 5 ++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/freerdp/crypto/crypto.h b/include/freerdp/crypto/crypto.h index b939e2060..e9130dbef 100644 --- a/include/freerdp/crypto/crypto.h +++ b/include/freerdp/crypto/crypto.h @@ -118,7 +118,10 @@ FREERDP_API CryptoCert crypto_cert_read(BYTE* data, UINT32 length); FREERDP_API char* crypto_cert_fingerprint(X509* xcert); FREERDP_API char* crypto_cert_subject(X509* xcert); FREERDP_API char* crypto_cert_subject_common_name(X509* xcert, int* length); -FREERDP_API char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths); +FREERDP_API char** crypto_cert_subject_alt_name(X509* xcert, int* count, + int** lengths); +FREERDP_API void crypto_cert_subject_alt_name_free(int count, int *lengths, + char** alt_name); FREERDP_API char* crypto_cert_issuer(X509* xcert); FREERDP_API void crypto_cert_print_info(X509* xcert); FREERDP_API void crypto_cert_free(CryptoCert cert); diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index e84712ba0..64c42e91e 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -392,6 +392,26 @@ char* crypto_cert_subject_common_name(X509* xcert, int* length) return (char*) common_name; } +FREERDP_API void crypto_cert_subject_alt_name_free(int count, int *lengths, + char** alt_name) +{ + int i; + + if (lengths) + free(lengths); + + if (alt_name) + { + for (i=0; i Date: Mon, 2 Sep 2013 16:25:34 +0200 Subject: [PATCH 088/202] Simplified code for FindFirstFileA, now always using FindClose for cleanup. --- winpr/libwinpr/file/file.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 3df76f3d1..b296d34ee 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -444,13 +444,13 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) if (lstat(pFileSearch->lpPath, &fileStat) < 0) { - free(pFileSearch); + FindClose(pFileSearch); return INVALID_HANDLE_VALUE; /* stat error */ } if (S_ISDIR(fileStat.st_mode) == 0) { - free(pFileSearch); + FindClose(pFileSearch); return INVALID_HANDLE_VALUE; /* not a directory */ } @@ -460,7 +460,7 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) if (!pFileSearch->pDir) { - free(pFileSearch); + FindClose(pFileSearch); return INVALID_HANDLE_VALUE; /* failed to open directory */ } @@ -479,7 +479,7 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) } } - free(pFileSearch); + FindClose(pFileSearch); return INVALID_HANDLE_VALUE; } @@ -535,13 +535,20 @@ BOOL FindClose(HANDLE hFindFile) pFileSearch = (WIN32_FILE_SEARCH*) hFindFile; - free(pFileSearch->lpPath); - free(pFileSearch->lpPattern); - closedir(pFileSearch->pDir); + if (pFileSearch) + { + if (pFileSearch->lpPath) + free(pFileSearch->lpPath); + if (pFileSearch->lpPattern) + free(pFileSearch->lpPattern); + if (pFileSearch->pDir) + closedir(pFileSearch->pDir); + free(pFileSearch); - free(pFileSearch); + return TRUE; + } - return TRUE; + return FALSE; } BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) From 07139276b5a6f730d4bece78b8e6debf1acb28c3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 4 Sep 2013 16:24:27 +0200 Subject: [PATCH 089/202] Added newlines at end of file, prevents clang from crashing... --- channels/audin/client/pulse/audin_pulse.c | 1 + winpr/libwinpr/utils/trio/trio.c | 1 + 2 files changed, 2 insertions(+) diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index 787f208bd..b6d2bbb42 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -540,3 +540,4 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt return 0; } + diff --git a/winpr/libwinpr/utils/trio/trio.c b/winpr/libwinpr/utils/trio/trio.c index 55eb76458..08b02240a 100644 --- a/winpr/libwinpr/utils/trio/trio.c +++ b/winpr/libwinpr/utils/trio/trio.c @@ -7855,3 +7855,4 @@ TRIO_ARGS1((errorcode), #ifdef _WIN32 #pragma warning(pop) #endif + From 3b54ba3449e933e021185ef6a080e15a282949a6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:38:35 +0200 Subject: [PATCH 090/202] Fixed thread handling. --- channels/audin/server/audin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 564630d8c..b597150fa 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -419,7 +419,9 @@ static BOOL audin_server_close(audin_server_context* context) SetEvent(audin->stopEvent); WaitForSingleObject(audin->thread, INFINITE); CloseHandle(audin->thread); + CloseHandle(audin->stopEvent); audin->thread = NULL; + audin->stopEvent = NULL; } if (audin->audin_channel) From 1d416ff387ec0eedc9a8ee57ed97e072140d0601 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:38:47 +0200 Subject: [PATCH 091/202] Fixed thread handling. --- channels/drive/client/drive_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index d4baee68c..809123290 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -633,17 +633,18 @@ static void drive_process_irp_list(DRIVE_DEVICE* disk) static void* drive_thread_func(void* arg) { DRIVE_DEVICE* disk = (DRIVE_DEVICE*) arg; + HANDLE hdl[] = {disk->irpEvent, disk->stopEvent}; while (1) { - WaitForSingleObject(disk->irpEvent, INFINITE); - - if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0) + DWORD rc = WaitForMultipleObjects(2, hdl, FALSE, INFINITE); + if (rc == WAIT_OBJECT_0 + 1) break; ResetEvent(disk->irpEvent); drive_process_irp_list(disk); } + ExitThread(0); return NULL; } @@ -664,8 +665,10 @@ static void drive_free(DEVICE* device) DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device; SetEvent(disk->stopEvent); + WaitForSingleObject(disk->thread, INFINITE); CloseHandle(disk->thread); CloseHandle(disk->irpEvent); + CloseHandle(disk->stopEvent); while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL) irp->Discard(irp); @@ -727,7 +730,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk); - ResumeThread(disk->thread); + ResumeThread(disk->thread); } } From d2fec8f612735943e2df6278d754bb3b7072d217 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:38:56 +0200 Subject: [PATCH 092/202] Fixed thread handling. --- channels/printer/client/printer_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 3826b7c3a..b3b17fb04 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -200,6 +200,8 @@ static void* printer_thread_func(void* arg) printer_process_irp(printer_dev, irp); } + ExitThread(0); + return NULL; } @@ -219,11 +221,14 @@ static void printer_free(DEVICE* device) SetEvent(printer_dev->stopEvent); WaitForSingleObject(printer_dev->thread, INFINITE); - CloseHandle(printer_dev->thread); while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL) irp->Discard(irp); + CloseHandle(printer_dev->thread); + CloseHandle(printer_dev->stopEvent); + CloseHandle(printer_dev->event); + _aligned_free(printer_dev->pIrpList); if (printer_dev->printer) From 733a39779c075672498f8b0cf77cb7c490e0cd42 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:05 +0200 Subject: [PATCH 093/202] Fixed thread handling. --- channels/rdpei/client/rdpei_main.c | 41 ++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 81099e6d8..b332cec5e 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include #include @@ -97,6 +98,7 @@ struct _RDPEI_PLUGIN RDPINPUT_CONTACT_POINT* contactPoints; HANDLE event; + HANDLE stopEvent; HANDLE thread; CRITICAL_SECTION lock; @@ -156,10 +158,16 @@ static void* rdpei_schedule_thread(void* arg) DWORD status; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg; RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface; + HANDLE hdl[] = {rdpei->event, rdpei->stopEvent}; + + assert(NULL != rdpei); + assert(NULL != context); while (1) { - status = WaitForSingleObject(rdpei->event, 20); + status = WaitForMultipleObjects(2, hdl, FALSE, 20); + if (status == WAIT_OBJECT_0 + 1) + break; EnterCriticalSection(&rdpei->lock); @@ -174,6 +182,8 @@ static void* rdpei_schedule_thread(void* arg) LeaveCriticalSection(&rdpei->lock); } + ExitThread(0); + return NULL; } @@ -218,13 +228,6 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) Stream_SealLength(s); - if (!rdpei->thread) - { - InitializeCriticalSection(&rdpei->lock); - rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL); - rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL); - } - status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength); Stream_Free(s, TRUE); @@ -487,6 +490,12 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)); rdpei->listener->pInterface = rdpei->iface.pInterface; + + InitializeCriticalSection(&rdpei->lock); + rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL); + rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) + rdpei_schedule_thread, (void*) rdpei, 0, NULL); return status; } @@ -497,6 +506,22 @@ static int rdpei_plugin_terminated(IWTSPlugin* pPlugin) DEBUG_DVC(""); + assert(NULL != pPlugin); + + SetEvent(rdpei->stopEvent); + EnterCriticalSection(&rdpei->lock); + + WaitForSingleObject(rdpei->thread, INFINITE); + + CloseHandle(rdpei->stopEvent); + CloseHandle(rdpei->event); + CloseHandle(rdpei->thread); + + DeleteCriticalSection(&rdpei->lock); + + if (rdpei->listener_callback) + free(rdpei->listener_callback); + free(rdpei); return 0; From d7d5869cb60d8bb26f751b4a5d5dea0196f2037f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:15 +0200 Subject: [PATCH 094/202] Fixed thread handling. --- channels/rdpsnd/server/rdpsnd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/channels/rdpsnd/server/rdpsnd.c b/channels/rdpsnd/server/rdpsnd.c index 57a9593a2..2735156c9 100644 --- a/channels/rdpsnd/server/rdpsnd.c +++ b/channels/rdpsnd/server/rdpsnd.c @@ -541,6 +541,9 @@ void rdpsnd_server_context_free(rdpsnd_server_context* context) SetEvent(rdpsnd->StopEvent); WaitForSingleObject(rdpsnd->thread, INFINITE); + CloseHandle(rdpsnd->StopEvent); + CloseHandle(rdpsnd->thread); + if (rdpsnd->rdpsnd_channel) WTSVirtualChannelClose(rdpsnd->rdpsnd_channel); From e828cef9813dc5be125bfa4692d2bd2f5a8b74f9 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:24 +0200 Subject: [PATCH 095/202] Fixed thread handling. --- server/X11/xf_peer.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 7b08eff1a..de6397398 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include #include @@ -175,6 +176,17 @@ int xf_xshm_init(xfInfo* xfi) return 0; } +void xf_info_free(xfInfo *info) +{ + assert(NULL != info); + + if (info->display) + XCloseDisplay(info->display); + + freerdp_clrconv_free(info->clrconv); + free(info); +} + xfInfo* xf_info_init() { int i; @@ -313,6 +325,11 @@ void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) { if (context) { + xf_info_free(context->info); + + CloseHandle(context->updateReadyEvent); + CloseHandle(context->updateSentEvent); + Stream_Free(context->s, TRUE); rfx_context_free(context->rfx_context); } @@ -508,6 +525,8 @@ static void* xf_peer_main_loop(void* arg) struct timeval timeout; freerdp_peer* client = (freerdp_peer*) arg; + assert(NULL != client); + ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(&timeout, sizeof(struct timeval)); @@ -598,6 +617,8 @@ static void* xf_peer_main_loop(void* arg) freerdp_peer_context_free(client); freerdp_peer_free(client); + ExitThread(0); + return NULL; } From 8ae13cdace7c58b23bdfc8ebabebe64f3a207b20 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:32 +0200 Subject: [PATCH 096/202] Fixed thread hanling. --- libfreerdp/utils/svc_plugin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index f0869a6c6..e07e8b353 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -185,6 +185,8 @@ static void* svc_plugin_thread_func(void* arg) DEBUG_SVC("in"); + assert(NULL != plugin); + IFCALL(plugin->connect_callback, plugin); while (1) @@ -212,6 +214,8 @@ static void* svc_plugin_thread_func(void* arg) DEBUG_SVC("out"); + ExitThread(0); + return 0; } From c5a632d8f9b263560c0f837a2ba2c4f61826d20f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:43 +0200 Subject: [PATCH 097/202] Fixed thread handling. --- client/Windows/wf_interface.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 9ae2de7df..b69c29794 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -569,7 +569,10 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) rdpChannels* channels; instance = (freerdp*) lpParam; + assert(NULL != instance); + wfc = (wfContext*) instance->context; + assert(NULL != wfc); ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); @@ -690,13 +693,13 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) } /* cleanup */ - wfc->mainThreadId = 0; - freerdp_channels_close(channels, instance); freerdp_disconnect(instance); printf("Main thread exited.\n"); + ExitThread(0); + return 0; } @@ -708,6 +711,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) HHOOK hook_handle; wfc = (wfContext*) lpParam; + assert(NULL != wfc); hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance, 0); @@ -734,9 +738,9 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) fprintf(stderr, "failed to install keyboard hook\n"); } - wfc->keyboardThreadId = 0; printf("Keyboard thread exited.\n"); + ExitThread(0); return (DWORD) NULL; } @@ -1078,12 +1082,27 @@ int wfreerdp_client_stop(rdpContext* context) { wfContext* wfc = (wfContext*) context; - if (wfc->mainThreadId) + if (wfc->thread) + { PostThreadMessage(wfc->mainThreadId, WM_QUIT, 0, 0); - if (wfc->keyboardThreadId) + WaitForSingleObject(wfc->thread, INFINITE); + CloseHandle(wfc->thread); + wfc->thread = NULL; + wfc->mainThreadId = 0; + } + + if (wfc->keyboardThread) + { PostThreadMessage(wfc->keyboardThreadId, WM_QUIT, 0, 0); + WaitForSingleObject(wfc->keyboardThread, INFINITE); + CloseHandle(wfc->keyboardThread); + + wfc->keyboardThread = NULL; + wfc->keyboardThreadId = 0; + } + return 0; } From 2283a5ccdf8430e26af5e1f28a3f55de1b061bc2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:39:54 +0200 Subject: [PATCH 098/202] Fixed thread handling. --- server/X11/xf_interface.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/server/X11/xf_interface.c b/server/X11/xf_interface.c index 1c93b5e4e..b4e95fd7a 100644 --- a/server/X11/xf_interface.c +++ b/server/X11/xf_interface.c @@ -17,6 +17,7 @@ * limitations under the License. */ +#include #include #include #include @@ -93,7 +94,7 @@ void* xf_server_thread(void* param) } } - listener->Close(listener); + ExitThread(0); return NULL; } @@ -115,9 +116,13 @@ int freerdp_server_global_uninit() int freerdp_server_start(xfServer* server) { + assert(NULL != server); + + server->thread = NULL; if (server->listener->Open(server->listener, NULL, 3389)) { - server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_server_thread, (void*) server, 0, NULL); + server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) + xf_server_thread, (void*) server, 0, NULL); } return 0; @@ -125,6 +130,17 @@ int freerdp_server_start(xfServer* server) int freerdp_server_stop(xfServer* server) { + if (server->thread) + { + /* ATTENTION: Terminate thread kills a thread, assure + * no resources are allocated during thread execution, + * as they will not be freed! */ + TerminateThread(server->thread, 0); + WaitForSingleObject(server->thread, INFINITE); + CloseHandle(server->thread); + + server->listener->Close(server->listener); + } return 0; } From 777d8c353506b3b021b5ed48813b4267063caf61 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:40:04 +0200 Subject: [PATCH 099/202] Fixed thread handling. --- libfreerdp/core/transport.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 9aa30fd71..17c7be411 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -85,6 +85,14 @@ BOOL transport_disconnect(rdpTransport* transport) status &= tcp_disconnect(transport->TcpIn); } + if (transport->async) + { + SetEvent(transport->stopEvent); + WaitForSingleObject(transport->thread, INFINITE); + + CloseHandle(transport->thread); + CloseHandle(transport->stopEvent); + } return status; } @@ -793,8 +801,14 @@ static void* transport_client_thread(void* arg) rdpTransport* transport; transport = (rdpTransport*) arg; + assert(NULL != transport); + assert(NULL != transport->settings); + instance = (freerdp*) transport->settings->instance; + assert(NULL != instance); + context = instance->context; + assert(NULL != instance->context); while (1) { @@ -802,26 +816,21 @@ static void* transport_client_thread(void* arg) events[nCount++] = transport->stopEvent; events[nCount] = transport->connectedEvent; - status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE); - - if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) - { - break; - } - - transport_get_read_handles(transport, (HANDLE*) &events, &nCount); - status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - - if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) - { + if (status == WAIT_OBJECT_0) + break; + + transport_get_read_handles(transport, (HANDLE*) events, &nCount); + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + if (status == WAIT_OBJECT_0) break; - } if (!freerdp_check_fds(instance)) break; } + ExitThread(0); + return NULL; } From 6c7ad722952683310b19700ddc92adf27599361d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:40:16 +0200 Subject: [PATCH 100/202] Fixed thread handling. --- channels/smartcard/client/smartcard_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 855df3ff0..90eed80aa 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -112,13 +112,16 @@ struct _SMARTCARD_IRP_WORKER }; typedef struct _SMARTCARD_IRP_WORKER SMARTCARD_IRP_WORKER; -static void smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker) +static void *smartcard_process_irp_thread_func(SMARTCARD_IRP_WORKER* irpWorker) { smartcard_process_irp(irpWorker->smartcard, irpWorker->irp); CloseHandle(irpWorker->thread); free(irpWorker); + + ExitThread(0); + return NULL; } static void* smartcard_thread_func(void* arg) From 8e6b79376cafe0edaadc0b91514167287db67d9e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:41:32 +0200 Subject: [PATCH 101/202] Fixed possible race found by bmiklautz --- channels/audin/client/alsa/audin_alsa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index c5213799e..31dea232d 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -332,15 +332,15 @@ static void audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* us alsa->receive = receive; alsa->user_data = user_data; - alsa->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - alsa->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL); - rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; alsa->buffer = (BYTE*) malloc(tbytes_per_frame * alsa->frames_per_packet); ZeroMemory(alsa->buffer, tbytes_per_frame * alsa->frames_per_packet); alsa->buffer_frames = 0; + + alsa->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + alsa->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL); } static void audin_alsa_close(IAudinDevice* device) From 214807731fc265083e4f4b80fd9ae846379babc2 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:44:12 +0200 Subject: [PATCH 102/202] Added missing assert include. --- libfreerdp/core/transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 17c7be411..933ad428b 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include #include From 5f539e9dad0b69e12f2d95661e0dcb94e1b5c769 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 13:45:49 +0200 Subject: [PATCH 103/202] Fixed missing assert include. --- libfreerdp/utils/svc_plugin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index e07e8b353..4cb3d6d7a 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -22,6 +22,7 @@ #include "config.h" #endif +#include #include #include #include From 8442c79e106f59024c7186bc780e5208e2ae7b8a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 14:27:34 +0200 Subject: [PATCH 104/202] Added assertions and ExitThread calls. --- channels/serial/client/serial_main.c | 5 +++++ client/X11/xf_client.c | 31 +++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 5f8002008..f06803dea 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -22,6 +22,7 @@ #include "config.h" #endif +#include #include #include #include @@ -346,6 +347,7 @@ void* serial_thread_mfunc(void* arg) { SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg; + assert(NULL != serial); while(1) { int sl; @@ -366,6 +368,7 @@ void* serial_thread_mfunc(void* arg) } } + ExitThread(0); return NULL; } @@ -376,6 +379,7 @@ static void* serial_thread_func(void* arg) SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg; HANDLE ev[] = {serial->stopEvent, Queue_Event(serial->queue), serial->newEvent}; + assert(NULL != serial); while (1) { status = WaitForMultipleObjects(3, ev, FALSE, INFINITE); @@ -401,6 +405,7 @@ static void* serial_thread_func(void* arg) serial_check_fds(serial); } + ExitThread(0); return NULL; } diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 886c3a8d2..9151bb4c8 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -773,12 +773,12 @@ BOOL xf_pre_connect(freerdp* instance) if (settings->Username == NULL) { fprintf(stderr, "--authonly, but no -u username. Please provide one.\n"); - exit(1); + return FALSE; } if (settings->Password == NULL) { fprintf(stderr, "--authonly, but no -p password. Please provide one.\n"); - exit(1); + return FALSE; } fprintf(stderr, "%s:%d: Authentication only. Don't connect to X.\n", __FILE__, __LINE__); /* Avoid XWindows initialization and configuration below. */ @@ -1224,6 +1224,8 @@ void* xf_update_thread(void* arg) wMessageQueue* queue; freerdp* instance = (freerdp*) arg; + assert( NULL != instance); + status = 1; queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); @@ -1241,6 +1243,7 @@ void* xf_update_thread(void* arg) break; } + ExitThread(0); return NULL; } @@ -1253,8 +1256,10 @@ void* xf_input_thread(void* arg) int pending_status = 1; int process_status = 1; freerdp* instance = (freerdp*) arg; + assert(NULL != instance); xfc = (xfContext*) instance->context; + assert(NULL != xfc); event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); @@ -1291,6 +1296,7 @@ void* xf_input_thread(void* arg) queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); MessageQueue_PostQuit(queue, 0); + ExitThread(0); return NULL; } @@ -1301,8 +1307,10 @@ void* xf_channels_thread(void* arg) HANDLE event; rdpChannels* channels; freerdp* instance = (freerdp*) arg; + assert(NULL != instance); xfc = (xfContext*) instance->context; + assert(NULL != xfc); channels = instance->context->channels; event = freerdp_channels_get_event_handle(instance); @@ -1313,6 +1321,7 @@ void* xf_channels_thread(void* arg) xf_process_channel_event(channels, instance); } + ExitThread(0); return NULL; } @@ -1356,6 +1365,7 @@ void* xf_thread(void* param) input_event = NULL; instance = (freerdp*) param; + assert(NULL != instance); ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); @@ -1364,6 +1374,7 @@ void* xf_thread(void* param) status = freerdp_connect(instance); xfc = (xfContext*) instance->context; + assert(NULL != xfc); /* Connection succeeded. --authonly ? */ if (instance->settings->AuthenticationOnly) @@ -1535,6 +1546,18 @@ void* xf_thread(void* param) CloseHandle(update_thread); } + if (async_input) + { + WaitForSingleObject(input_thread, INFINITE); + CloseHandle(input_thread); + } + + if (async_channels) + { + WaitForSingleObject(channels_thread, INFINITE); + CloseHandle(channels_thread); + } + FILE* fin = fopen("/tmp/tsmf.tid", "rt"); if (fin) @@ -1707,7 +1730,8 @@ int xfreerdp_client_start(rdpContext* context) return -1; } - xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, context->instance, 0, NULL); + xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, + context->instance, 0, NULL); return 0; } @@ -1716,6 +1740,7 @@ int xfreerdp_client_stop(rdpContext* context) { xfContext* xfc = (xfContext*) context; + assert(NULL != context); if (context->settings->AsyncInput) { wMessageQueue* queue; From 4c1708e2906d6debdcfda9662d0d77a39e9567d1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 14:36:06 +0200 Subject: [PATCH 105/202] Fixed channel closing before waiting for thread to quit. --- client/X11/xf_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 9151bb4c8..249f57af1 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1548,10 +1548,13 @@ void* xf_thread(void* param) if (async_input) { + wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); + MessageQueue_PostQuit(input_queue, 0); WaitForSingleObject(input_thread, INFINITE); CloseHandle(input_thread); } + freerdp_channels_close(channels, instance); if (async_channels) { WaitForSingleObject(channels_thread, INFINITE); @@ -1594,7 +1597,6 @@ void* xf_thread(void* param) if (!exit_code) exit_code = freerdp_error_info(instance); - freerdp_channels_close(channels, instance); freerdp_channels_free(channels); freerdp_disconnect(instance); gdi_free(instance); From f2bc161f1301c4b5e9e095128a0eca1b2808e788 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 14:44:35 +0200 Subject: [PATCH 106/202] Fixed duplicate WaitForSingleObject on client thread. --- client/X11/xf_client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 249f57af1..df2161e55 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1756,8 +1756,11 @@ int xfreerdp_client_stop(rdpContext* context) xfc->disconnect = TRUE; } - WaitForSingleObject(xfc->thread, INFINITE); - CloseHandle(xfc->thread); + if (xfc->thread) + { + CloseHandle(xfc->thread); + xfc->thread = NULL; + } return 0; } From 5731725712c33cb76e56639780ef97796bdfd127 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 15:40:09 +0200 Subject: [PATCH 107/202] Fixed malloc warning, now casting to void *. --- libfreerdp/utils/event.c | 52 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/libfreerdp/utils/event.c b/libfreerdp/utils/event.c index 8b9e25e07..60c62b03e 100644 --- a/libfreerdp/utils/event.c +++ b/libfreerdp/utils/event.c @@ -35,56 +35,68 @@ static wMessage* freerdp_cliprdr_event_new(UINT16 event_type) { - wMessage* event = NULL; + union + { + wMessage* m; + void *v; + } event; + event.m = NULL; switch (event_type) { case CliprdrChannel_MonitorReady: - event = (wMessage*) malloc(sizeof(RDP_CB_MONITOR_READY_EVENT)); - ZeroMemory(event, sizeof(RDP_CB_MONITOR_READY_EVENT)); - event->id = MakeMessageId(CliprdrChannel, MonitorReady); + event.v = malloc(sizeof(RDP_CB_MONITOR_READY_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_MONITOR_READY_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, MonitorReady); break; case CliprdrChannel_FormatList: - event = (wMessage*) malloc(sizeof(RDP_CB_FORMAT_LIST_EVENT)); - ZeroMemory(event, sizeof(RDP_CB_FORMAT_LIST_EVENT)); - event->id = MakeMessageId(CliprdrChannel, FormatList); + event.v = malloc(sizeof(RDP_CB_FORMAT_LIST_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_FORMAT_LIST_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, FormatList); break; case CliprdrChannel_DataRequest: - event = (wMessage*) malloc(sizeof(RDP_CB_DATA_REQUEST_EVENT)); - ZeroMemory(event, sizeof(RDP_CB_DATA_REQUEST_EVENT)); - event->id = MakeMessageId(CliprdrChannel, DataRequest); + event.v = malloc(sizeof(RDP_CB_DATA_REQUEST_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_DATA_REQUEST_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, DataRequest); break; case CliprdrChannel_DataResponse: - event = (wMessage*) malloc(sizeof(RDP_CB_DATA_RESPONSE_EVENT)); - ZeroMemory(event, sizeof(RDP_CB_DATA_RESPONSE_EVENT)); - event->id = MakeMessageId(CliprdrChannel, DataResponse); + event.v = malloc(sizeof(RDP_CB_DATA_RESPONSE_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_DATA_RESPONSE_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, DataResponse); break; } - return event; + return event.v; } static wMessage* freerdp_tsmf_event_new(UINT16 event_type) { - wMessage* event = NULL; + union + { + void *v; + wMessage* m; + } event; + event.m = NULL; switch (event_type) { case TsmfChannel_VideoFrame: - event = (wMessage*) malloc(sizeof(RDP_VIDEO_FRAME_EVENT)); - ZeroMemory(event, sizeof(RDP_VIDEO_FRAME_EVENT)); + event.v = malloc(sizeof(RDP_VIDEO_FRAME_EVENT)); + ZeroMemory(event.v, sizeof(RDP_VIDEO_FRAME_EVENT)); + event.m->id = MakeMessageId(TsmfChannel, VideoFrame); break; case TsmfChannel_Redraw: - event = (wMessage*) malloc(sizeof(RDP_REDRAW_EVENT)); - ZeroMemory(event, sizeof(RDP_REDRAW_EVENT)); + event.v = malloc(sizeof(RDP_REDRAW_EVENT)); + ZeroMemory(event.v, sizeof(RDP_REDRAW_EVENT)); + event.m->id = MakeMessageId(TsmfChannel, Redraw); break; } - return event; + return event.v; } static wMessage* freerdp_rail_event_new(UINT16 event_type) From 9a3b4ac6c22e5f56cd6bb025f0603210b0a5a2e6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 5 Sep 2013 17:17:54 +0200 Subject: [PATCH 108/202] Fixed invalid event number. --- libfreerdp/core/transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 933ad428b..e06e92893 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -817,11 +817,11 @@ static void* transport_client_thread(void* arg) events[nCount++] = transport->stopEvent; events[nCount] = transport->connectedEvent; - status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + status = WaitForMultipleObjects(nCount + 1, events, FALSE, INFINITE); if (status == WAIT_OBJECT_0) break; - transport_get_read_handles(transport, (HANDLE*) events, &nCount); + transport_get_read_handles(transport, (HANDLE*) &events, &nCount); status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_OBJECT_0) break; From a0e09e6273ab6bb79b0b5020bffe54549e35d21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 5 Sep 2013 18:53:55 -0400 Subject: [PATCH 109/202] libfreerdp-core: fix server-side licensing sequence --- libfreerdp/core/info.c | 2 ++ libfreerdp/core/license.c | 6 +++++- libfreerdp/core/peer.c | 9 +++++++++ libfreerdp/core/rdp.c | 20 ++++++++++---------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index e8a04af9b..0d8606bc5 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -120,6 +120,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) if (Stream_GetRemainingLength(s) < 4) return FALSE; + Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily */ Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress */ @@ -149,6 +150,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) if (Stream_GetRemainingLength(s) < 10) return FALSE; + Stream_Seek_UINT32(s); /* clientSessionId, should be set to 0 */ Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 88d039eb8..04de4d81e 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -191,11 +191,15 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type) sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; + flags = PREAMBLE_VERSION_3_0; + /** * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when * running in server mode! This flag seems to be incorrectly documented. */ - flags = PREAMBLE_VERSION_3_0 | EXTENDED_ERROR_MSG_SUPPORTED; + + if (!license->rdp->settings->ServerMode) + flags |= EXTENDED_ERROR_MSG_SUPPORTED; rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, sec_flags); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 5b38c905e..64a54ff4b 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -30,6 +30,10 @@ #include "peer.h" +#ifdef WITH_DEBUG_RDP +extern const char* DATA_PDU_TYPE_STRINGS[80]; +#endif + static BOOL freerdp_peer_initialize(freerdp_peer* client) { client->context->rdp->settings->ServerMode = TRUE; @@ -85,6 +89,11 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return FALSE; +#ifdef WITH_DEBUG_RDP + printf("recv %s Data PDU (0x%02X), length: %d\n", + type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); +#endif + switch (type) { case DATA_PDU_TYPE_SYNCHRONIZE: diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 867fd5c1b..61a0f8cba 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -31,7 +31,7 @@ #include #ifdef WITH_DEBUG_RDP -static const char* const DATA_PDU_TYPE_STRINGS[] = +const char* DATA_PDU_TYPE_STRINGS[80] = { "?", "?", /* 0x00 - 0x01 */ "Update", /* 0x02 */ @@ -65,7 +65,7 @@ static const char* const DATA_PDU_TYPE_STRINGS[] = "?", "?", "?", /* 0x33 - 0x35 */ "Status Info", /* 0x36 */ "Monitor Layout" /* 0x37 */ - "?", "?", "?", /* 0x38 - 0x40 */ + "FrameAcknowledge", "?", "?", /* 0x38 - 0x40 */ "?", "?", "?", "?", "?", "?" /* 0x41 - 0x46 */ }; #endif @@ -133,20 +133,21 @@ void rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT Stream_Write_UINT16(s, channel_id); /* pduSource */ } -BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* share_id, - BYTE *compressed_type, UINT16 *compressed_len) +BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* shareId, + BYTE *compressedType, UINT16 *compressedLen) { if (Stream_GetRemainingLength(s) < 12) return FALSE; /* Share Data Header */ - Stream_Read_UINT32(s, *share_id); /* shareId (4 bytes) */ + Stream_Read_UINT32(s, *shareId); /* shareId (4 bytes) */ Stream_Seek_UINT8(s); /* pad1 (1 byte) */ Stream_Seek_UINT8(s); /* streamId (1 byte) */ Stream_Read_UINT16(s, *length); /* uncompressedLength (2 bytes) */ Stream_Read_UINT8(s, *type); /* pduType2, Data PDU Type (1 byte) */ - Stream_Read_UINT8(s, *compressed_type); /* compressedType (1 byte) */ - Stream_Read_UINT16(s, *compressed_len); /* compressedLength (2 bytes) */ + Stream_Read_UINT8(s, *compressedType); /* compressedType (1 byte) */ + Stream_Read_UINT16(s, *compressedLen); /* compressedLength (2 bytes) */ + return TRUE; } @@ -567,9 +568,8 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) } #ifdef WITH_DEBUG_RDP - /* if (type != DATA_PDU_TYPE_UPDATE) */ - DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d", - type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); + printf("recv %s Data PDU (0x%02X), length: %d\n", + type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif switch (type) From 81a5e727d6d7c24ef3e75d6033071b24d6b1e992 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 09:02:46 +0200 Subject: [PATCH 110/202] Added proper thread sync for input thread. Channels thread now listening to message pipe quit signal posted when shutting down the channel. --- channels/client/channels.c | 13 +++++++++++-- client/X11/xf_client.c | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/channels/client/channels.c b/channels/client/channels.c index bf886dba4..c0739e653 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -631,8 +631,9 @@ FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* eve /** * called only from main thread */ -static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instance) +static int freerdp_channels_process_sync(rdpChannels* channels, freerdp* instance) { + int rc = TRUE; wMessage message; wMessage* event; rdpChannel* channel; @@ -642,7 +643,10 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan while (MessageQueue_Peek(channels->MsgPipe->Out, &message, TRUE)) { if (message.id == WMQ_QUIT) + { + rc = FALSE; break; + } if (message.id == 0) { @@ -677,6 +681,8 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan */ } } + + return rc; } /** @@ -730,7 +736,7 @@ int freerdp_channels_process_pending_messages(freerdp* instance) if (WaitForSingleObject(MessageQueue_Event(channels->MsgPipe->Out), 0) == WAIT_OBJECT_0) { - freerdp_channels_process_sync(channels, instance); + return freerdp_channels_process_sync(channels, instance); } return TRUE; @@ -782,4 +788,7 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance) if (pChannelClientData->pChannelInitEventProc) pChannelClientData->pChannelInitEventProc(pChannelClientData->pInitHandle, CHANNEL_EVENT_TERMINATED, 0, 0); } + + /* Emit a quit signal to the internal message pipe. */ + MessagePipe_PostQuit(channels->MsgPipe, 0); } diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index df2161e55..a2ac2287e 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1250,7 +1250,7 @@ void* xf_update_thread(void* arg) void* xf_input_thread(void* arg) { xfContext* xfc; - HANDLE event; + HANDLE event[2]; XEvent xevent; wMessageQueue* queue; int pending_status = 1; @@ -1261,9 +1261,11 @@ void* xf_input_thread(void* arg) xfc = (xfContext*) instance->context; assert(NULL != xfc); - event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); + queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); + event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); + event[1] = MessageQueue_Event(queue); - while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) + while (WaitForMultipleObjects(2, event, FALSE, INFINITE) == WAIT_OBJECT_0) { do { @@ -1293,9 +1295,6 @@ void* xf_input_thread(void* arg) break; } - queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - MessageQueue_PostQuit(queue, 0); - ExitThread(0); return NULL; } @@ -1318,6 +1317,9 @@ void* xf_channels_thread(void* arg) while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) { status = freerdp_channels_process_pending_messages(instance); + if (!status) + break; + xf_process_channel_event(channels, instance); } @@ -1538,6 +1540,10 @@ void* xf_thread(void* param) } } + /* Close the channels first. This will signal the internal message pipes + * that the threads should quit. */ + freerdp_channels_close(channels, instance); + if (async_update) { wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); @@ -1554,7 +1560,6 @@ void* xf_thread(void* param) CloseHandle(input_thread); } - freerdp_channels_close(channels, instance); if (async_channels) { WaitForSingleObject(channels_thread, INFINITE); From f39995103113651ee68f65e0d1f4ad7655167d50 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 09:41:00 +0200 Subject: [PATCH 111/202] Fixed input thread shutdown caused by previous commit. --- client/X11/xf_client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index a2ac2287e..98ad7f3df 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1250,7 +1250,7 @@ void* xf_update_thread(void* arg) void* xf_input_thread(void* arg) { xfContext* xfc; - HANDLE event[2]; + HANDLE event; XEvent xevent; wMessageQueue* queue; int pending_status = 1; @@ -1262,10 +1262,9 @@ void* xf_input_thread(void* arg) assert(NULL != xfc); queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); - event[1] = MessageQueue_Event(queue); + event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); - while (WaitForMultipleObjects(2, event, FALSE, INFINITE) == WAIT_OBJECT_0) + while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) { do { @@ -1295,6 +1294,7 @@ void* xf_input_thread(void* arg) break; } + MessageQueue_PostQuit(queue, 0); ExitThread(0); return NULL; } From c986f30c4a60d81bc20f4e8b983fd2b7139a5419 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 10:55:26 +0200 Subject: [PATCH 112/202] Fixed smartcard related issues with double free. --- channels/smartcard/client/smartcard_main.c | 21 +++++++++++++++++++++ libfreerdp/codec/rfx.c | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 855df3ff0..0199d815f 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -35,6 +35,11 @@ #include +#define BOOL PCSC_BOOL +#include +#include +#include +#undef BOOL #include "smartcard_main.h" static void smartcard_free(DEVICE* dev) @@ -320,6 +325,22 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) name = device->Name; path = device->Path; + { + LONG rc; + DWORD proto = SCARD_PROTOCOL_RAW | SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; + SCARDHANDLE card = NULL; + DWORD scope = SCARD_SCOPE_SYSTEM; + SCARDCONTEXT hContext; + + rc = SCardEstablishContext(scope, NULL, NULL, &hContext); + fprintf(stderr, "%s SCardEstablishContext %s\n", __func__, pcsc_stringify_error(rc)); + rc = SCardConnect(hContext, name, 0, 0, &card, &proto); + fprintf(stderr, "%s SCardConnect %s\n", __func__, pcsc_stringify_error(rc)); + rc = SCardDisconnect(card, 0); + fprintf(stderr, "%s SCardDisconnect %s\n", __func__, pcsc_stringify_error(rc)); + rc = SCardReleaseContext(hContext); + fprintf(stderr, "%s SCardReleaseContext %s\n", __func__, pcsc_stringify_error(rc)); + } if (name) { /* TODO: check if server supports sc redirect (version 5.1) */ diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index e1d5f9def..decf2f07d 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -298,12 +298,12 @@ RFX_CONTEXT* rfx_context_new(void) void rfx_context_free(RFX_CONTEXT* context) { assert(NULL != context); - assert(NULL != context->quants); assert(NULL != context->priv); assert(NULL != context->priv->TilePool); assert(NULL != context->priv->BufferPool); - free(context->quants); + if (context->quants) + free(context->quants); ObjectPool_Free(context->priv->TilePool); From 4e0c7d251d5f1ecd6d55b7663032015245e9f1ce Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 11:07:33 +0200 Subject: [PATCH 113/202] Fixed double free. --- libfreerdp/core/nego.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index f3370e6e8..de082bc75 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -293,7 +293,10 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego) Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) + { + Stream_Free(s, TRUE); return FALSE; + } Stream_Free(s, TRUE); @@ -486,7 +489,6 @@ BOOL nego_recv_response(rdpNego* nego) if (status < 0) return FALSE; - Stream_Free(s, TRUE); return TRUE; } @@ -712,7 +714,10 @@ BOOL nego_send_negotiation_request(rdpNego* nego) Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) + { + Stream_Free(s, TRUE); return FALSE; + } Stream_Free(s, TRUE); @@ -871,7 +876,10 @@ BOOL nego_send_negotiation_response(rdpNego* nego) Stream_SealLength(s); if (transport_write(nego->transport, s) < 0) + { + Stream_Free(s, TRUE); return FALSE; + } Stream_Free(s, TRUE); From 3b931a9d69fe1940dd58eab7392b4de8434895d5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 11:08:45 +0200 Subject: [PATCH 114/202] Reverted accidental commit. --- channels/smartcard/client/smartcard_main.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 0199d815f..855df3ff0 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -35,11 +35,6 @@ #include -#define BOOL PCSC_BOOL -#include -#include -#include -#undef BOOL #include "smartcard_main.h" static void smartcard_free(DEVICE* dev) @@ -325,22 +320,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) name = device->Name; path = device->Path; - { - LONG rc; - DWORD proto = SCARD_PROTOCOL_RAW | SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; - SCARDHANDLE card = NULL; - DWORD scope = SCARD_SCOPE_SYSTEM; - SCARDCONTEXT hContext; - - rc = SCardEstablishContext(scope, NULL, NULL, &hContext); - fprintf(stderr, "%s SCardEstablishContext %s\n", __func__, pcsc_stringify_error(rc)); - rc = SCardConnect(hContext, name, 0, 0, &card, &proto); - fprintf(stderr, "%s SCardConnect %s\n", __func__, pcsc_stringify_error(rc)); - rc = SCardDisconnect(card, 0); - fprintf(stderr, "%s SCardDisconnect %s\n", __func__, pcsc_stringify_error(rc)); - rc = SCardReleaseContext(hContext); - fprintf(stderr, "%s SCardReleaseContext %s\n", __func__, pcsc_stringify_error(rc)); - } if (name) { /* TODO: check if server supports sc redirect (version 5.1) */ From 1f4205a04e619ee9a2a2dbbbe56caad30469b54a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 11:35:54 +0200 Subject: [PATCH 115/202] Fixed unchecked free in glyph.c (related to #1428) --- libfreerdp/cache/glyph.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index 14f2f69dd..e8650fcd7 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -403,7 +403,8 @@ void glyph_cache_put(rdpGlyphCache* glyph_cache, UINT32 id, UINT32 index, rdpGly if (prevGlyph != NULL) { Glyph_Free(glyph_cache->context, prevGlyph); - free(prevGlyph->aj); + if (NULL != prevGlyph->aj) + free(prevGlyph->aj); free(prevGlyph); } @@ -498,12 +499,14 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache) if (glyph != NULL) { Glyph_Free(glyph_cache->context, glyph); - free(glyph->aj); + if (glyph->aj) + free(glyph->aj); free(glyph); glyph_cache->glyphCache[i].entries[j] = NULL; } } free(glyph_cache->glyphCache[i].entries); + glyph_cache->glyphCache[i].entries = NULL; } for (i = 0; i < 255; i++) From be495e54e2b440a1920fe69d99c07e6a1d667166 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 6 Sep 2013 12:35:33 +0200 Subject: [PATCH 116/202] Fixed NULL check in freerdp_device_collection_find --- libfreerdp/common/settings.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index f790bd260..67e801c14 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -154,6 +154,9 @@ RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* { device = (RDPDR_DEVICE*) settings->DeviceArray[index]; + if (NULL == device->Name) + continue; + if (strcmp(device->Name, name) == 0) return device; } From 4274b266c0459fd967b1d947a63b2a379906af3e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 9 Sep 2013 16:07:14 +0200 Subject: [PATCH 117/202] Fixed command line parser, now printing help, if an invalid option is detected. --- client/common/cmdline.c | 24 ++++++++++++++++-------- client/common/compatibility.c | 18 ++++++++++++------ winpr/libwinpr/utils/cmdline.c | 21 ++++++++++++++++----- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 0faf2f6f2..f201689ce 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -870,6 +870,8 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* detect_status = 0; CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + if (status < 0) + return status; arg = args; @@ -903,6 +905,8 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c detect_status = 0; CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + if (status < 0) + return status; arg = args; @@ -945,7 +949,8 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) *flags = COMMAND_LINE_SEPARATOR_COLON; *flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS; } - else + /* Ignore legacy parsing in case there is an error in the command line. */ + else if (old_cli_status >= 0) { if ((old_cli_status == 1) || ((old_cli_count > posix_cli_count) && (old_cli_status != -1))) { @@ -966,12 +971,7 @@ int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* { COMMAND_LINE_ARGUMENT_A* arg; - if (status == COMMAND_LINE_STATUS_PRINT_HELP) - { - freerdp_client_print_command_line_help(argc, argv); - return COMMAND_LINE_STATUS_PRINT_HELP; - } - else if (status == COMMAND_LINE_STATUS_PRINT_VERSION) + if (status == COMMAND_LINE_STATUS_PRINT_VERSION) { freerdp_client_print_version(); return COMMAND_LINE_STATUS_PRINT_VERSION; @@ -1015,6 +1015,11 @@ int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* return COMMAND_LINE_STATUS_PRINT; } + else if (status < 0) + { + freerdp_client_print_command_line_help(argc, argv); + return COMMAND_LINE_STATUS_PRINT_HELP; + } return 0; } @@ -1043,6 +1048,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); + if (status < 0) + return status; } @@ -1624,7 +1631,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin } CommandLineSwitchDefault(arg) { - + fprintf(stderr, "Unknown argument %s\n", __func__, arg->Name); + return COMMAND_LINE_ERROR; } CommandLineSwitchEnd(arg) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 40f7a326e..e5f21b091 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -309,6 +309,8 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) CommandLineClearArgumentsA(old_args); status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings, freerdp_client_old_command_line_pre_filter, NULL); + if (status < 0) + return status; arg = old_args; @@ -374,12 +376,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings, freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter); - if (status == COMMAND_LINE_STATUS_PRINT_HELP) - { - freerdp_client_print_command_line_help(argc, argv); - return COMMAND_LINE_STATUS_PRINT_HELP; - } - else if (status == COMMAND_LINE_STATUS_PRINT_VERSION) + if (status == COMMAND_LINE_STATUS_PRINT_VERSION) { freerdp_client_print_version(); return COMMAND_LINE_STATUS_PRINT_VERSION; @@ -388,6 +385,15 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe { return COMMAND_LINE_STATUS_PRINT; } + else if (status < 0) + { + if (status != COMMAND_LINE_STATUS_PRINT_HELP) + { + + } + freerdp_client_print_command_line_help(argc, argv); + return COMMAND_LINE_STATUS_PRINT_HELP; + } arg = old_args; diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 0c998ea4c..fe1c2b25a 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -53,7 +53,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int count; int length; int index; - BOOL match; + BOOL match, found, argument = FALSE; char* sigil; int sigil_length; int sigil_index; @@ -86,7 +86,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* if (preFilter) { count = preFilter(context, i, argc, argv); - if (count < 0) { status = COMMAND_LINE_ERROR; @@ -133,9 +132,9 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* } else { - continue; + return COMMAND_LINE_ERROR; } - + if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE)) { if (length < (sigil_length + 1)) @@ -192,6 +191,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_length = 0; } + found = FALSE; for (j = 0; options[j].Name != NULL; j++) { match = FALSE; @@ -214,6 +214,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* if (!match) continue; + found = match; options[j].Index = index; if ((flags & COMMAND_LINE_SEPARATOR_SPACE) && ((i + 1) < argc)) @@ -238,7 +239,12 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_present = 0; } - if (value_present) + if (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) + argument = TRUE; + else + argument = FALSE; + + if (value_present && argument) { i++; value_index = 0; @@ -247,6 +253,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value = (char*) &argv[i][value_index]; value_length = (length - value_index); } + else + return COMMAND_LINE_ERROR; } if (!(flags & COMMAND_LINE_SEPARATOR_SPACE)) @@ -320,6 +328,9 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* else if (options[j].Flags & COMMAND_LINE_PRINT_VERSION) return COMMAND_LINE_STATUS_PRINT_VERSION; } + + if (!found) + return COMMAND_LINE_ERROR_NO_KEYWORD; } } From a7a7bab61988a4a202cb9b17bd69e8584cc9333e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 9 Sep 2013 17:21:15 +0200 Subject: [PATCH 118/202] Fixed optional argument parsing. --- winpr/libwinpr/utils/cmdline.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index fe1c2b25a..4e66ec94d 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -239,7 +239,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_present = 0; } - if (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) + if ((options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) || + (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) argument = TRUE; else argument = FALSE; @@ -253,7 +254,13 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value = (char*) &argv[i][value_index]; value_length = (length - value_index); } - else + else if (!value_present && (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) + { + value_index = 0; + value = NULL; + value_length = 0; + } + else if (!value_present && argument) return COMMAND_LINE_ERROR; } From a2ce4815861979c495fec7e0a15ee2527134bc1c Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 9 Sep 2013 18:41:57 +0200 Subject: [PATCH 119/202] x11/client: win8/server 2k12 fix for kbd sync Keyboard indicator sync (caps lock/num lock/..) didn't work properly on reconnect for windows 8 and windows 2012 server. fixes #773 --- client/X11/xf_client.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 886c3a8d2..338bcf3d4 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1407,9 +1407,15 @@ void* xf_thread(void* param) rcount = 0; wcount = 0; + /* + * win8 and server 2k12 seem to have some timing issue/race condition + * when a initial sync request is send to sync the keyboard inidcators + * sending the sync event twice fixed this problem + */ if (freerdp_focus_required(instance)) { xf_kbd_focus_in(xfc); + xf_kbd_focus_in(xfc); } if (!async_transport) From 21127ec33b72c06d94bcad3ec4d5f3e1c4edf3aa Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 10 Sep 2013 10:29:45 +0200 Subject: [PATCH 120/202] Added a new flag to indicate the presence of a single not escaped argument allowing the legacy command line : syntax. --- client/common/compatibility.c | 2 ++ winpr/include/winpr/cmdline.h | 1 + winpr/libwinpr/utils/cmdline.c | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index e5f21b091..89db353e0 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -302,6 +302,7 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) detect_status = 0; flags = COMMAND_LINE_SEPARATOR_SPACE; flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH; + flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED; settings = (rdpSettings*) malloc(sizeof(rdpSettings)); ZeroMemory(settings, sizeof(rdpSettings)); @@ -372,6 +373,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe flags = COMMAND_LINE_SEPARATOR_SPACE; flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH; flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE; + flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED; status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings, freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter); diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h index bc67d4f52..ca7ae7292 100644 --- a/winpr/include/winpr/cmdline.h +++ b/winpr/include/winpr/cmdline.h @@ -53,6 +53,7 @@ #define COMMAND_LINE_SIGIL_DOUBLE_DASH 0x00000008 #define COMMAND_LINE_SIGIL_PLUS_MINUS 0x00000010 #define COMMAND_LINE_SIGIL_ENABLE_DISABLE 0x00000020 +#define COMMAND_LINE_SIGIL_NOT_ESCAPED 0x00000040 #define COMMAND_LINE_SEPARATOR_COLON 0x00000100 #define COMMAND_LINE_SEPARATOR_EQUAL 0x00000200 diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 4e66ec94d..1e6c45079 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -54,6 +54,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int length; int index; BOOL match, found, argument = FALSE; + BOOL notescaped = FALSE; char* sigil; int sigil_length; int sigil_index; @@ -81,6 +82,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* for (i = 1; i < argc; i++) { + BOOL escaped = TRUE; index = i; if (preFilter) @@ -130,12 +132,21 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* { sigil_length = 0; } + else if (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED) + { + if (notescaped) + return COMMAND_LINE_ERROR; + sigil_length = 0; + escaped = FALSE; + notescaped = TRUE; + } else { return COMMAND_LINE_ERROR; } - if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE)) + if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE) || + (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)) { if (length < (sigil_length + 1)) return COMMAND_LINE_ERROR_NO_KEYWORD; @@ -191,6 +202,9 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_length = 0; } + if (!escaped) + continue; + found = FALSE; for (j = 0; options[j].Name != NULL; j++) { From 8c796e9afc496c23ea1ae059ad4aec898a7854af Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 10 Sep 2013 10:38:23 +0200 Subject: [PATCH 121/202] winpr/synch: link against librt --- winpr/libwinpr/synch/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/synch/CMakeLists.txt b/winpr/libwinpr/synch/CMakeLists.txt index fbc607292..3beea6d5a 100644 --- a/winpr/libwinpr/synch/CMakeLists.txt +++ b/winpr/libwinpr/synch/CMakeLists.txt @@ -55,7 +55,7 @@ set(${MODULE_PREFIX}_LIBS ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) -if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) +if((NOT WIN32) AND (NOT APPLE) AND (NOT ANDROID)) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rt) endif() From 4fbebba5280839f18bbed0e51cd51873f0fad0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 11 Sep 2013 19:00:32 -0400 Subject: [PATCH 122/202] libwinpr-wait: add support for waiting on named pipes (non-standard) --- winpr/libwinpr/synch/wait.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index bfb221315..8fab17203 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -45,6 +45,8 @@ #include "../handle/handle.h" +#include "../pipe/pipe.h" + static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds) { ts->tv_sec += dwMilliseconds / 1000L; @@ -241,6 +243,31 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) return WAIT_FAILED; #endif } + else if (Type == HANDLE_TYPE_NAMED_PIPE) + { + int status; + fd_set rfds; + struct timeval timeout; + WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; + + FD_ZERO(&rfds); + FD_SET(pipe->clientfd, &rfds); + ZeroMemory(&timeout, sizeof(timeout)); + + if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) + { + timeout.tv_usec = dwMilliseconds * 1000; + } + + status = select(pipe->clientfd + 1, &rfds, NULL, NULL, + (dwMilliseconds == INFINITE) ? NULL : &timeout); + + if (status < 0) + return WAIT_FAILED; + + if (status != 1) + return WAIT_TIMEOUT; + } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); @@ -302,6 +329,11 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl WINPR_TIMER* timer = (WINPR_TIMER*) Object; fd = timer->fd; } + else if (Type == HANDLE_TYPE_NAMED_PIPE) + { + WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; + fd = pipe->clientfd; + } else { return WAIT_FAILED; @@ -347,6 +379,11 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl WINPR_TIMER* timer = (WINPR_TIMER*) Object; fd = timer->fd; } + else if (Type == HANDLE_TYPE_NAMED_PIPE) + { + WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; + fd = pipe->clientfd; + } if (FD_ISSET(fd, &fds)) { From 9455c4fa5df9f89832212e9a8e13ba3ef5f0fe7c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 12:18:35 +0200 Subject: [PATCH 123/202] Fixed smartcard argument checks. Fixed smartcard package reading. --- .../smartcard/client/smartcard_operations.c | 985 +++++++++++++++--- client/common/cmdline.c | 23 +- 2 files changed, 869 insertions(+), 139 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 695e53344..f43b4a4ee 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -81,6 +81,319 @@ #define WIN_FILE_DEVICE_SMARTCARD 0x00000031 +static UINT32 handle_CommonTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +{ + UINT8 version; + UINT8 endianess; + UINT16 header_length; + + assert(scard); + assert(irp); + assert(irp->input); + assert(inlen); + + if (Stream_GetRemainingLength(irp->input) < 8) + { + DEBUG_WARN("length violation %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + /* Process CommonTypeHeader */ + Stream_Read_UINT8(irp->input, version); + Stream_Read_UINT8(irp->input, endianess); + Stream_Read_UINT16(irp->input, header_length); + Stream_Seek(irp->input, 4); + + if (0x01 != version) + { + DEBUG_WARN("unsupported header version %d", version); + return SCARD_F_INTERNAL_ERROR; + } + if (0x10 != endianess) + { + DEBUG_WARN("unsupported endianess %d", endianess); + return SCARD_F_INTERNAL_ERROR; + } + if (0x08 != header_length) + { + DEBUG_WARN("unsupported header length %d", header_length); + return SCARD_F_INTERNAL_ERROR; + } + + assert(*inlen >= 8); + *inlen -= 8; + + return 0; +} + +static UINT32 handle_PrivateTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +{ + UINT32 len; + + assert(scard); + assert(irp); + assert(irp->input); + assert(inlen); + + if (Stream_GetRemainingLength(irp->input) < 8) + { + DEBUG_WARN("Length violation"); + return SCARD_F_INTERNAL_ERROR; + } + + /* Process PrivateTypeHeader */ + Stream_Read_UINT32(irp->input, len); + Stream_Seek_UINT32(irp->input); + + /* Assure the remaining length is as expected. */ + if (len < Stream_GetRemainingLength(irp->input)) + { + DEBUG_WARN("missing payload %d [%d]", + len, Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + assert(*inlen >= 8); + *inlen -= 8; + + return 0; +} + +static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +{ + UINT32 len; + + assert(scard); + assert(irp); + assert(irp->input); + assert(inlen); + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("Length violation"); + return SCARD_F_INTERNAL_ERROR; + } + + /* Process PrivateTypeHeader */ + Stream_Read_UINT32(irp->input, len); + if (Stream_GetRemainingLength(irp->input) < len) + { + DEBUG_WARN("Length violation"); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Seek(irp->input, len); + + if (len > Stream_GetRemainingLength(irp->input)) + { + DEBUG_WARN("Length violation missing payload"); + return SCARD_F_INTERNAL_ERROR; + } + + assert(*inlen >= 4 + len); + *inlen -= 4; + *inlen -= len; + + return 0; +} + +static UINT32 handle_CardHandle(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) +{ + UINT32 status; + UINT32 len; + + assert(scard); + assert(irp); + assert(irp->input); + assert(inlen); + + status = handle_Context(scard, irp, inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(irp->input, len); + if (Stream_GetRemainingLength(irp->input) < len) + { + DEBUG_WARN("length violation %d [%d]", len, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Seek(irp->input, len); + + assert(*inlen >= len + 4); + *inlen -= len + 4; + + return 0; +} + +static UINT32 handle_RedirContextRef(SMARTCARD_DEVICE* scard, IRP* irp, + size_t *inlen, SCARDCONTEXT* hContext) +{ + UINT32 len; + + assert(scard); + assert(irp); + assert(irp->input); + assert(inlen); + assert(hContext); + + /* Extract context handle. */ + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(irp->input, len); + if (len != 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(irp->input, *hContext); + DEBUG_SCARD("hContext=%p", *hContext); + + assert(*inlen >= 8); + *inlen -= 8; + + return 0; +} + +static UINT32 handle_RedirHandleRef(SMARTCARD_DEVICE* scard, IRP* irp, + size_t *inlen, SCARDCONTEXT* hContext, SCARDHANDLE *hHandle) +{ + UINT32 len, status; + + status = handle_RedirContextRef(scard, irp, inlen, hContext); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(irp->input, len); + if (len != 4) + { + DEBUG_WARN("length field violation %d [%d]", 4, len); + return SCARD_F_INTERNAL_ERROR; + } + + if (Stream_GetRemainingLength(irp->input) < len) + { + DEBUG_WARN("length violation %d [%d]", len, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(irp->input, *hHandle); + DEBUG_SCARD("hCard=%p", *hHandle); + + assert(*inlen >= len + 4); + *inlen -= len + 4; + + return 0; +} + +static BOOL check_reader_is_forwarded(SMARTCARD_DEVICE *scard, const char *readerName) +{ + BOOL rc = TRUE; + char *name = _strdup(readerName); + char *str, *strpos=NULL, *strstatus=NULL; + long pos, status, cpos, ret; + + assert(scard); + assert(readerName); + + /* Extract the name, position and status from the data provided. */ + str = strtok(name, " "); + while(str) + { + strpos = strstatus; + strstatus = str; + str = strtok(NULL, " "); + } + + pos = strtol(strpos, NULL, 10); + status = strtol(strstatus, NULL, 10); + + if ( strpos && strstatus ) + { + /* Check, if the name of the reader matches. */ + if (scard->name && strncmp(scard->name, readerName, strlen(scard->name))) + rc = FALSE; + + /* Check, if the position matches. */ + if (scard->path) + { + ret = sscanf(scard->path, "%ld", &cpos); + if ((1 == ret) && (cpos != pos)) + rc = FALSE; + } + } + else + DEBUG_WARN("unknown reader format '%s'", readerName); + + free(name); + + if (!rc) + DEBUG_WARN("reader '%s' not forwarded", readerName); + + return rc; +} + +static BOOL check_handle_is_forwarded(SMARTCARD_DEVICE *scard, + SCARDHANDLE hCard, SCARDCONTEXT hContext) +{ + BOOL rc = FALSE; + LONG status; + DWORD state = 0, protocol = 0; + DWORD readerLen; + DWORD atrLen = MAX_ATR_SIZE; + char* readerName = NULL; + BYTE pbAtr[MAX_ATR_SIZE]; + + assert(scard); + assert(hCard); + +#ifdef SCARD_AUTOALLOCATE + readerLen = SCARD_AUTOALLOCATE; +#else + readerLen = 256; + readerName = malloc(readerLen); +#endif + + status = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); + if (status == SCARD_S_SUCCESS) + { + rc = check_reader_is_forwarded(scard, readerName); + if (!rc) + DEBUG_WARN("Reader '%s' not forwarded!", readerName); + } + +#ifdef SCARD_AUTOALLOCATE + SCardFreeMemory(hContext, readerName); +#else + free(readerName); +#endif + + return rc; +} static UINT32 smartcard_output_string(IRP* irp, char* src, BOOL wide) { @@ -214,15 +527,34 @@ static void smartcard_input_repos(IRP* irp, UINT32 read) Stream_Seek(irp->input, add); } -static void smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide) +static UINT32 smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide) { UINT32 dataLength; + assert(irp); + assert(dest); + + if (Stream_GetRemainingLength(irp->input) < 12) + { + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Seek(irp->input, 8); Stream_Read_UINT32(irp->input, dataLength); + if (Stream_GetRemainingLength(irp->input) < dataLength) + { + DEBUG_WARN("length violation %d [%d]", dataLength, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + DEBUG_SCARD("datalength %d", dataLength); smartcard_input_repos(irp, smartcard_input_string(irp, dest, dataLength, wide)); + + return 0; } static void smartcard_input_skip_linked(IRP* irp) @@ -259,20 +591,29 @@ static UINT32 smartcard_map_state(UINT32 state) return state; } -static UINT32 handle_EstablishContext(IRP* irp) +static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { - UINT32 len; UINT32 status; UINT32 scope; SCARDCONTEXT hContext = -1; - Stream_Seek(irp->input, 8); - Stream_Read_UINT32(irp->input, len); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; - if (len != 8) + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + /* Ensure, that the capacity expected is actually available. */ + if (inlen < 4) + { + DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", + Stream_GetRemainingLength(irp->input), inlen); return SCARD_F_INTERNAL_ERROR; + } - Stream_Seek_UINT32(irp->input); + /* Read the scope from the stream. */ Stream_Read_UINT32(irp->input, scope); status = SCardEstablishContext(scope, NULL, NULL, &hContext); @@ -289,16 +630,26 @@ static UINT32 handle_EstablishContext(IRP* irp) return SCARD_S_SUCCESS; } -static UINT32 handle_ReleaseContext(IRP* irp) +static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { - UINT32 len, status; + UINT32 status; SCARDCONTEXT hContext = -1; - Stream_Seek(irp->input, 8); - Stream_Read_UINT32(irp->input, len); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; - Stream_Seek(irp->input, 0x10); - Stream_Read_UINT32(irp->input, hContext); + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; status = SCardReleaseContext(hContext); @@ -312,13 +663,26 @@ static UINT32 handle_ReleaseContext(IRP* irp) return status; } -static UINT32 handle_IsValidContext(IRP* irp) +static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { UINT32 status; SCARDCONTEXT hContext; - Stream_Seek(irp->input, 0x1C); - Stream_Read_UINT32(irp->input, hContext); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; status = SCardIsValidContext(hContext); @@ -326,31 +690,51 @@ static UINT32 handle_IsValidContext(IRP* irp) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); + if (status) + printf("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + else + printf("Success context: 0x%08x", (unsigned) hContext); smartcard_output_alignment(irp, 8); return status; } -static UINT32 handle_ListReaders(IRP* irp, BOOL wide) +static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, + size_t inlen, BOOL wide) { - UINT32 len, status; + UINT32 status; SCARDCONTEXT hContext; DWORD dwReaders; char *readerList = NULL, *walker; int elemLength, dataLength; - int pos, poslen1, poslen2; + int pos, poslen1, poslen2, allowed_pos; - Stream_Seek(irp->input, 8); - Stream_Read_UINT32(irp->input, len); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; - Stream_Seek(irp->input, 0x1c); - Stream_Read_UINT32(irp->input, len); + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; - if (len != 4) + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + /* Ensure, that the capacity expected is actually available. */ + if (inlen < 0x10) + { + DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", + Stream_GetRemainingLength(irp->input), inlen); return SCARD_F_INTERNAL_ERROR; + } + Stream_Seek(irp->input, 0x10); - Stream_Read_UINT32(irp->input, hContext); + /* Read RedirScardcontextRef */ + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ @@ -383,15 +767,27 @@ static UINT32 handle_ListReaders(IRP* irp, BOOL wide) walker = readerList; dataLength = 0; + /* Smartcards can be forwarded by position and name. */ + allowed_pos = -1; + if (scard->path) + if (1 != sscanf(scard->path, "%d", &allowed_pos)) + allowed_pos = -1; + + pos = 0; while (1) { elemLength = strlen(walker); if (elemLength == 0) break; - dataLength += smartcard_output_string(irp, walker, wide); + /* Ignore readers not forwarded. */ + if ((allowed_pos < 0) || (pos == allowed_pos)) + { + if (!scard->name || strstr(walker, scard->name)) + dataLength += smartcard_output_string(irp, walker, wide); + } walker += elemLength + 1; - elemLength = strlen(walker); + pos ++; } dataLength += smartcard_output_string(irp, "\0", wide); @@ -417,7 +813,7 @@ static UINT32 handle_ListReaders(IRP* irp, BOOL wide) return status; } -static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) +static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) { int i; LONG status; @@ -426,14 +822,38 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) DWORD readerCount = 0; SCARD_READERSTATE *readerStates, *cur; - Stream_Seek(irp->input, 0x18); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + /* Ensure, that the capacity expected is actually available. */ + if (inlen < 12) + { + DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", + Stream_GetRemainingLength(irp->input), inlen); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Read_UINT32(irp->input, dwTimeout); Stream_Read_UINT32(irp->input, readerCount); - Stream_Seek(irp->input, 8); + /* Skip reader state */ + Stream_Seek(irp->input, 4); - Stream_Read_UINT32(irp->input, hContext); + /* Get context */ + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; + /* Skip ReaderStateConformant */ Stream_Seek(irp->input, 4); DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", @@ -535,13 +955,26 @@ static UINT32 handle_GetStatusChange(IRP* irp, BOOL wide) return status; } -static UINT32 handle_Cancel(IRP *irp) +static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen) { LONG status; SCARDCONTEXT hContext; - Stream_Seek(irp->input, 0x1C); - Stream_Read_UINT32(irp->input, hContext); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; status = SCardCancel(hContext); @@ -555,7 +988,7 @@ static UINT32 handle_Cancel(IRP *irp) return status; } -static UINT32 handle_Connect(IRP* irp, BOOL wide) +static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) { LONG status; SCARDCONTEXT hContext; @@ -565,24 +998,61 @@ static UINT32 handle_Connect(IRP* irp, BOOL wide) DWORD dwActiveProtocol = 0; SCARDHANDLE hCard; - Stream_Seek(irp->input, 0x1c); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + /* Skip ptrReader */ + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("Length violadion %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Seek(irp->input, 4); + + /* Read common data */ + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 8) + { + DEBUG_WARN("Length violadion %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Read_UINT32(irp->input, dwShareMode); Stream_Read_UINT32(irp->input, dwPreferredProtocol); - smartcard_input_reader_name(irp, &readerName, wide); - - Stream_Seek(irp->input, 4); - Stream_Read_UINT32(irp->input, hContext); + status = smartcard_input_reader_name(irp, &readerName, wide); + if (status) + return status; + + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")", (unsigned) hContext, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, readerName ? readerName : "NULL"); + if (!check_reader_is_forwarded(scard, readerName)) + { + DEBUG_WARN("Reader '%s' not forwarded!", readerName); + return SCARD_E_INVALID_TARGET; + } + status = SCardConnect(hContext, readerName, (DWORD) dwShareMode, (DWORD) dwPreferredProtocol, &hCard, (DWORD *) &dwActiveProtocol); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s 0x%08x", pcsc_stringify_error(status), (unsigned) status); + DEBUG_WARN("Failure: %s 0x%08x", pcsc_stringify_error(status), (unsigned) status); else DEBUG_SCARD("Success 0x%08x", (unsigned) hCard); @@ -600,7 +1070,7 @@ static UINT32 handle_Connect(IRP* irp, BOOL wide) return status; } -static UINT32 handle_Reconnect(IRP* irp) +static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; SCARDCONTEXT hContext; @@ -610,20 +1080,39 @@ static UINT32 handle_Reconnect(IRP* irp) DWORD dwInitialization = 0; DWORD dwActiveProtocol = 0; - Stream_Seek(irp->input, 0x20); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 12) + return SCARD_F_INTERNAL_ERROR; + Stream_Read_UINT32(irp->input, dwShareMode); Stream_Read_UINT32(irp->input, dwPreferredProtocol); Stream_Read_UINT32(irp->input, dwInitialization); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, hContext); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, hCard); + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, share: 0x%08x, proto: 0x%08x, init: 0x%08x)", (unsigned) hContext, (unsigned) hCard, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, (unsigned) dwInitialization); + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + status = SCardReconnect(hCard, (DWORD) dwShareMode, (DWORD) dwPreferredProtocol, (DWORD) dwInitialization, (LPDWORD) &dwActiveProtocol); @@ -638,23 +1127,43 @@ static UINT32 handle_Reconnect(IRP* irp) return status; } -static UINT32 handle_Disconnect(IRP* irp) +static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; DWORD dwDisposition = 0; - Stream_Seek(irp->input, 0x20); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + return SCARD_F_INTERNAL_ERROR; + Stream_Read_UINT32(irp->input, dwDisposition); - Stream_Seek(irp->input, 4); - Stream_Read_UINT32(irp->input, hContext); - Stream_Seek(irp->input, 4); - Stream_Read_UINT32(irp->input, hCard); + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, disposition: 0x%08x)", (unsigned) hContext, (unsigned) hCard, (unsigned) dwDisposition); + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + status = SCardDisconnect(hCard, (DWORD) dwDisposition); if (status != SCARD_S_SUCCESS) @@ -667,13 +1176,37 @@ static UINT32 handle_Disconnect(IRP* irp) return status; } -static UINT32 handle_BeginTransaction(IRP* irp) +static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; - SCARDCONTEXT hCard; + SCARDHANDLE hCard; + SCARDCONTEXT hContext; - Stream_Seek(irp->input, 0x30); - Stream_Read_UINT32(irp->input, hCard); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + return SCARD_F_INTERNAL_ERROR; + Stream_Seek(irp->input, 4); + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; + + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } status = SCardBeginTransaction(hCard); @@ -687,17 +1220,38 @@ static UINT32 handle_BeginTransaction(IRP* irp) return status; } -static UINT32 handle_EndTransaction(IRP* irp) +static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; - SCARDCONTEXT hCard; + SCARDHANDLE hCard; + SCARDCONTEXT hContext; DWORD dwDisposition = 0; - Stream_Seek(irp->input, 0x20); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + return SCARD_F_INTERNAL_ERROR; Stream_Read_UINT32(irp->input, dwDisposition); - Stream_Seek(irp->input, 0x0C); - Stream_Read_UINT32(irp->input, hCard); + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; + + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } status = SCardEndTransaction(hCard, dwDisposition); @@ -711,10 +1265,11 @@ static UINT32 handle_EndTransaction(IRP* irp) return status; } -static UINT32 handle_State(IRP* irp) +static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; SCARDHANDLE hCard; + SCARDCONTEXT hContext; DWORD state = 0, protocol = 0; DWORD readerLen; DWORD atrLen = MAX_ATR_SIZE; @@ -725,12 +1280,34 @@ static UINT32 handle_State(IRP* irp) int i; #endif - Stream_Seek(irp->input, 0x24); - Stream_Seek_UINT32(irp->input); /* atrLen */ + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; - Stream_Seek(irp->input, 0x0c); - Stream_Read_UINT32(irp->input, hCard); - Stream_Seek(irp->input, 0x04); + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 8) + return SCARD_F_INTERNAL_ERROR; + + Stream_Seek(irp->input, 4); + Stream_Seek_UINT32(irp->input); /* atrLen */ + inlen -= 8; + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; + + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; @@ -772,7 +1349,7 @@ static UINT32 handle_State(IRP* irp) smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE - free(readerName); + SCardFreeMemory(hContext, readerName); #else free(readerName); #endif @@ -780,10 +1357,11 @@ static UINT32 handle_State(IRP* irp) return status; } -static DWORD handle_Status(IRP *irp, BOOL wide) +static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL wide) { LONG status; SCARDHANDLE hCard; + SCARDCONTEXT hContext; DWORD state, protocol; DWORD readerLen = 0; DWORD atrLen = 0; @@ -796,15 +1374,40 @@ static DWORD handle_Status(IRP *irp, BOOL wide) int i; #endif - Stream_Seek(irp->input, 0x24); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 12) + { + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Seek(irp->input, 4); Stream_Read_UINT32(irp->input, readerLen); Stream_Read_UINT32(irp->input, atrLen); - Stream_Seek(irp->input, 0x0c); - Stream_Read_UINT32(irp->input, hCard); - Stream_Seek(irp->input, 0x4); + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; atrLen = MAX_ATR_SIZE; + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; @@ -826,7 +1429,7 @@ static DWORD handle_Status(IRP *irp, BOOL wide) DEBUG_SCARD(" Reader: \"%s\"", readerName ? readerName : "NULL"); #ifdef WITH_DEBUG_SCARD - fprintf(stderr, " ATR: "); + stderr, " ATR: "); for (i = 0; i < atrLen; i++) fprintf(stderr, "%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); fprintf(stderr, "\n"); @@ -862,8 +1465,7 @@ static DWORD handle_Status(IRP *irp, BOOL wide) smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE - /* SCardFreeMemory(NULL, readerName); */ - free(readerName); + SCardFreeMemory(hContext, readerName); #else free(readerName); #endif @@ -871,35 +1473,48 @@ static DWORD handle_Status(IRP *irp, BOOL wide) return status; } -static UINT32 handle_Transmit(IRP* irp) +static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; - SCARDCONTEXT hCard; + SCARDHANDLE hCard; + SCARDCONTEXT hContext; UINT32 map[7], linkedLen; SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; - Stream_Seek(irp->input, 0x14); - Stream_Read_UINT32(irp->input, map[0]); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, map[1]); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 32) + { + DEBUG_WARN("length violation %d [%d]", 32, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); Stream_Read_UINT32(irp->input, pioSendPci.cbPciLength); - Stream_Read_UINT32(irp->input, map[2]); + Stream_Read_UINT32(irp->input, cbSendLength); Stream_Read_UINT32(irp->input, map[3]); Stream_Read_UINT32(irp->input, map[4]); Stream_Read_UINT32(irp->input, map[5]); Stream_Read_UINT32(irp->input, cbRecvLength); - if (map[0] & SCARD_INPUT_LINKED) - smartcard_input_skip_linked(irp); - - Stream_Seek(irp->input, 4); - Stream_Read_UINT32(irp->input, hCard); + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; if (map[2] & SCARD_INPUT_LINKED) { @@ -957,6 +1572,12 @@ static UINT32 handle_Transmit(IRP* irp) DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)", (long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength); + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + status = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, pPioRecvPci, recvBuf, &cbRecvLength); @@ -987,7 +1608,7 @@ static UINT32 handle_Transmit(IRP* irp) return status; } -static UINT32 handle_Control(IRP* irp) +static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; SCARDCONTEXT hContext; @@ -1001,19 +1622,34 @@ static UINT32 handle_Control(IRP* irp) DWORD nBytesReturned; DWORD outBufferSize; - Stream_Seek(irp->input, 0x14); - Stream_Read_UINT32(irp->input, map[0]); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, map[1]); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 20) + { + DEBUG_WARN("length violation %d [%d]", 20, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Read_UINT32(irp->input, controlCode); Stream_Read_UINT32(irp->input, recvLength); Stream_Read_UINT32(irp->input, map[2]); Stream_Seek(irp->input, 0x4); Stream_Read_UINT32(irp->input, outBufferSize); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, hContext); - Stream_Seek(irp->input, 0x4); - Stream_Read_UINT32(irp->input, hCard); + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; /* Translate Windows SCARD_CTL_CODE's to corresponding local code */ if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD) @@ -1045,6 +1681,12 @@ static UINT32 handle_Control(IRP* irp) return smartcard_output_return(irp, SCARD_E_NO_MEMORY); } + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + status = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength, sendBuffer, (DWORD) outBufferSize, &nBytesReturned); @@ -1071,25 +1713,52 @@ static UINT32 handle_Control(IRP* irp) return status; } -static UINT32 handle_GetAttrib(IRP* irp) +static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; SCARDHANDLE hCard; + SCARDCONTEXT hContext; DWORD dwAttrId = 0; DWORD dwAttrLen = 0; DWORD attrLen = 0; BYTE* pbAttr = NULL; - Stream_Seek(irp->input, 0x20); + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_CardHandle(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 12) + { + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Read_UINT32(irp->input, dwAttrId); Stream_Seek(irp->input, 0x4); Stream_Read_UINT32(irp->input, dwAttrLen); - Stream_Seek(irp->input, 0xC); - Stream_Read_UINT32(irp->input, hCard); + + status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); + if (status) + return status; DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)", (unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen); + if (!check_handle_is_forwarded(scard, hCard, hContext)) + { + DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + return SCARD_E_INVALID_TARGET; + } + #ifdef SCARD_AUTOALLOCATE if (dwAttrLen == 0) { @@ -1177,21 +1846,35 @@ static UINT32 handle_GetAttrib(IRP* irp) } smartcard_output_alignment(irp, 8); +#ifdef SCARD_AUTOALLOCATE + SCardFreeMemory(hContext, pbAttr); +#else free(pbAttr); +#endif return status; } -static UINT32 handle_AccessStartedEvent(IRP* irp) +static UINT32 handle_AccessStartedEvent(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) + { + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + Stream_Seek(irp->input, 4); + smartcard_output_alignment(irp, 8); + return SCARD_S_SUCCESS; } void scard_error(SMARTCARD_DEVICE* scard, IRP* irp, UINT32 ntstatus) { /* [MS-RDPESC] 3.1.4.4 */ - fprintf(stderr, "scard processing error %x\n", ntstatus); + DEBUG_WARN("scard processing error %x", ntstatus); Stream_SetPosition(irp->output, 0); /* CHECKME */ irp->IoStatus = ntstatus; @@ -1207,7 +1890,7 @@ typedef struct _SERVER_SCARD_ATRMASK } SERVER_SCARD_ATRMASK; -static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) +static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BOOL wide) { LONG status; int i, j, k; @@ -1220,6 +1903,30 @@ static UINT32 handle_LocateCardsByATR(IRP* irp, BOOL wide) SERVER_SCARD_ATRMASK* curAtr = NULL; SERVER_SCARD_ATRMASK* pAtrMasks = NULL; + status = handle_CommonTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_PrivateTypeHeader(scard, irp, &inlen); + if (status) + return status; + + status = handle_Context(scard, irp, &inlen); + if (status) + return status; + + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Seek(irp->input, 4); + status = handle_RedirContextRef(scard, irp, &inlen, &hContext); + if (status) + return status; + Stream_Seek(irp->input, 0x2C); Stream_Read_UINT32(irp->input, hContext); Stream_Read_UINT32(irp->input, atrMaskCount); @@ -1405,6 +2112,12 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) const UINT32 header_lengths = 16; /* MS-RPCE, Sections 2.2.6.1 and 2.2.6.2. */ + if (Stream_GetRemainingLength(irp->input) < 32) + { + DEBUG_WARN("Invalid IRP of length %d received, ignoring.", + Stream_GetRemainingLength(irp->input)); + return; + } Stream_Read_UINT32(irp->input, output_len); Stream_Read_UINT32(irp->input, input_len); @@ -1439,26 +2152,37 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) result_pos = Stream_GetPosition(irp->output); Stream_Seek(irp->output, 4); /* result */ - /* body */ + /* Ensure, that this package is fully available. */ + if (Stream_GetRemainingLength(irp->input) < input_len) + { + DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", + Stream_GetRemainingLength(irp->input), input_len); + return; + } + + /* body. input_len contains the length of the remaining data + * that can be read from the current position of irp->input, + * so pass it on ;) */ + DEBUG_SCARD("ioctl %08X", ioctl_code); switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: - result = handle_EstablishContext(irp); + result = handle_EstablishContext(scard, irp, input_len); break; case SCARD_IOCTL_IS_VALID_CONTEXT: - result = handle_IsValidContext(irp); + result = handle_IsValidContext(scard, irp, input_len); break; case SCARD_IOCTL_RELEASE_CONTEXT: - result = handle_ReleaseContext(irp); + result = handle_ReleaseContext(scard, irp, input_len); break; case SCARD_IOCTL_LIST_READERS: - result = handle_ListReaders(irp, 0); + result = handle_ListReaders(scard, irp, input_len, 0); break; case SCARD_IOCTL_LIST_READERS + 4: - result = handle_ListReaders(irp, 1); + result = handle_ListReaders(scard, irp, input_len, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: @@ -1468,76 +2192,77 @@ void smartcard_device_control(SMARTCARD_DEVICE* scard, IRP* irp) break; case SCARD_IOCTL_GET_STATUS_CHANGE: - result = handle_GetStatusChange(irp, 0); + result = handle_GetStatusChange(scard, irp, input_len, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: - result = handle_GetStatusChange(irp, 1); + result = handle_GetStatusChange(scard, irp, input_len, 1); break; case SCARD_IOCTL_CANCEL: - result = handle_Cancel(irp); + result = handle_Cancel(scard, irp, input_len); break; case SCARD_IOCTL_CONNECT: - result = handle_Connect(irp, 0); + result = handle_Connect(scard, irp, input_len, 0); break; case SCARD_IOCTL_CONNECT + 4: - result = handle_Connect(irp, 1); + result = handle_Connect(scard, irp, input_len, 1); break; case SCARD_IOCTL_RECONNECT: - result = handle_Reconnect(irp); + result = handle_Reconnect(scard, irp, input_len); break; case SCARD_IOCTL_DISCONNECT: - result = handle_Disconnect(irp); + result = handle_Disconnect(scard, irp, input_len); break; case SCARD_IOCTL_BEGIN_TRANSACTION: - result = handle_BeginTransaction(irp); + result = handle_BeginTransaction(scard, irp, input_len); break; case SCARD_IOCTL_END_TRANSACTION: - result = handle_EndTransaction(irp); + result = handle_EndTransaction(scard, irp, input_len); break; case SCARD_IOCTL_STATE: - result = handle_State(irp); + result = handle_State(scard, irp, input_len); break; case SCARD_IOCTL_STATUS: - result = handle_Status(irp, 0); + result = handle_Status(scard, irp, input_len, 0); break; case SCARD_IOCTL_STATUS + 4: - result = handle_Status(irp, 1); + result = handle_Status(scard, irp, input_len, 1); break; case SCARD_IOCTL_TRANSMIT: - result = handle_Transmit(irp); + result = handle_Transmit(scard, irp, input_len); break; case SCARD_IOCTL_CONTROL: - result = handle_Control(irp); + result = handle_Control(scard, irp, input_len); break; case SCARD_IOCTL_GETATTRIB: - result = handle_GetAttrib(irp); + result = handle_GetAttrib(scard, irp, input_len); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: - result = handle_AccessStartedEvent(irp); + result = handle_AccessStartedEvent(scard, irp, input_len); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: - result = handle_LocateCardsByATR(irp, 0); + result = handle_LocateCardsByATR(scard, irp, input_len, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: - result = handle_LocateCardsByATR(irp, 1); + result = handle_LocateCardsByATR(scard, irp, input_len, 1); break; default: result = 0xc0000001; - fprintf(stderr, "scard unknown ioctl 0x%x\n", ioctl_code); + DEBUG_WARN("scard unknown ioctl 0x%x [%d]\n", + ioctl_code, input_len); break; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index a681d3d2e..bf0de4acc 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -319,15 +319,15 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p { RDPDR_SMARTCARD* smartcard; - if (count < 2) + if (count < 1) return -1; smartcard = (RDPDR_SMARTCARD*) malloc(sizeof(RDPDR_SMARTCARD)); ZeroMemory(smartcard, sizeof(RDPDR_SMARTCARD)); smartcard->Type = RDPDR_DTYP_SMARTCARD; - smartcard->Name = _strdup(params[1]); - + if (count > 1) + smartcard->Name = _strdup(params[1]); if (count > 2) smartcard->Path = _strdup(params[2]); @@ -340,15 +340,17 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p { RDPDR_SERIAL* serial; - if (count < 2) + if (count < 1) return -1; serial = (RDPDR_SERIAL*) malloc(sizeof(RDPDR_SERIAL)); ZeroMemory(serial, sizeof(RDPDR_SERIAL)); serial->Type = RDPDR_DTYP_SERIAL; - serial->Name = _strdup(params[1]); - serial->Path = _strdup(params[2]); + if (count > 1) + serial->Name = _strdup(params[1]); + if (count > 2) + serial->Path = _strdup(params[2]); freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial); settings->DeviceRedirection = TRUE; @@ -359,15 +361,17 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p { RDPDR_PARALLEL* parallel; - if (count < 2) + if (count < 1) return -1; parallel = (RDPDR_PARALLEL*) malloc(sizeof(RDPDR_PARALLEL)); ZeroMemory(parallel, sizeof(RDPDR_PARALLEL)); parallel->Type = RDPDR_DTYP_PARALLEL; - parallel->Name = _strdup(params[1]); - parallel->Path = _strdup(params[2]); + if (count > 1) + parallel->Name = _strdup(params[1]); + if (count > 1) + parallel->Path = _strdup(params[2]); freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel); settings->DeviceRedirection = TRUE; @@ -546,6 +550,7 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT int count; p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count); + fprintf(stderr, "[%s] %d %s %s %s\n", __func__, count, p[0], p[1], arg->Value); p[0] = "smartcard"; freerdp_client_add_device_channel(settings, count, p); From 02abe530a8e3687d84d35fca406ad9faa617dfa7 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 12:30:46 +0200 Subject: [PATCH 124/202] Added debug output, if some message block could not be read. --- .../smartcard/client/smartcard_operations.c | 83 ++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index f43b4a4ee..d0a1faaa6 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1519,9 +1519,21 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (map[2] & SCARD_INPUT_LINKED) { /* sendPci */ + if (Stream_GetRemainingLength(irp->input) < 8) + { + DEBUG_WARN("length violation %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, linkedLen); - Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); + + if (Stream_GetRemainingLength(irp->input) < linkedLen - 4) + { + DEBUG_WARN("length violation %d [%d]", linkedLen - 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } Stream_Seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); @@ -1530,9 +1542,21 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (map[3] & SCARD_INPUT_LINKED) { + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } /* send buffer */ Stream_Read_UINT32(irp->input, linkedLen); + if (Stream_GetRemainingLength(irp->input) < linkedLen) + { + DEBUG_WARN("length violation %d [%d]", linkedLen, + Stream_GetRemainingLength(irp->input)); + return SCARD_F_INTERNAL_ERROR; + } sendBuf = malloc(linkedLen); Stream_Read(irp->input, sendBuf, linkedLen); smartcard_input_repos(irp, linkedLen); @@ -1543,19 +1567,70 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (map[4] & SCARD_INPUT_LINKED) { + if (Stream_GetRemainingLength(irp->input) < 8) + { + DEBUG_WARN("length violation %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); + return SCARD_F_INTERNAL_ERROR; + } /* recvPci */ Stream_Read_UINT32(irp->input, linkedLen); - Stream_Read_UINT32(irp->input, pioRecvPci.dwProtocol); + + if (Stream_GetRemainingLength(irp->input) < linkedLen - 4) + { + DEBUG_WARN("length violation %d [%d]", linkedLen - 4, + Stream_GetRemainingLength(irp->input)); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); + return SCARD_F_INTERNAL_ERROR; + } Stream_Seek(irp->input, linkedLen - 4); smartcard_input_repos(irp, linkedLen); + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); + return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, map[6]); if (map[6] & SCARD_INPUT_LINKED) { /* not sure what this is */ + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); + return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, linkedLen); + + if (Stream_GetRemainingLength(irp->input) < linkedLen) + { + DEBUG_WARN("length violation %d [%d]", linkedLen, + Stream_GetRemainingLength(irp->input)); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); + return SCARD_F_INTERNAL_ERROR; + } Stream_Seek(irp->input, linkedLen); smartcard_input_repos(irp, linkedLen); @@ -1575,6 +1650,10 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); + if (sendBuf) + free(sendBuf); + if (recvBuf) + free(recvBuf); return SCARD_E_INVALID_TARGET; } From c49a4f518e3a50db7fbb1689688f92982278e0e8 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 12:31:07 +0200 Subject: [PATCH 125/202] Debug printf now more verbose about location of the error. --- include/freerdp/utils/debug.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h index a62ec19a0..cc986e16d 100644 --- a/include/freerdp/utils/debug.h +++ b/include/freerdp/utils/debug.h @@ -24,16 +24,16 @@ #define DEBUG_NULL(fmt, ...) do { } while (0) #define DEBUG_PRINT(_dbg_str, fmt, ...) do { \ - fprintf(stderr, _dbg_str, __FUNCTION__, __LINE__); \ + fprintf(stderr, _dbg_str, __FUNCTION__, __FILE__, __LINE__); \ fprintf(stderr, fmt, ## __VA_ARGS__); \ fprintf(stderr, "\n"); \ } while( 0 ) -#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%d): ", fmt, ## __VA_ARGS__) -#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%d): ", fmt, ## __VA_ARGS__) +#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%s:%d): ", fmt, ## __VA_ARGS__) +#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%s:%d): ", fmt, ## __VA_ARGS__) #ifdef WITH_DEBUG -#define DEBUG_MSG(fmt, ...) DEBUG_PRINT("DBG %s (%d): ", fmt, ## __VA_ARGS__) +#define DEBUG_MSG(fmt, ...) DEBUG_PRINT("DBG %s (%s:%d): ", fmt, ## __VA_ARGS__) #else #define DEBUG_MSG(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif From c33821d026df3c23157bab4533396b6a9ced0380 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 13:53:15 +0200 Subject: [PATCH 126/202] Resource cleanup now done using goto Length now checked at all places. --- .../smartcard/client/smartcard_operations.c | 414 ++++++++++-------- 1 file changed, 228 insertions(+), 186 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index d0a1faaa6..b270ae2e1 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -73,8 +73,6 @@ #define SCARD_IOCTL_ACCESS_STARTED_EVENT 0x000900E0 /* SCardAccessStartedEvent */ #define SCARD_IOCTL_LOCATE_CARDS_BY_ATR 0x000900E8 /* LocateCardsByATR */ -#define SCARD_INPUT_LINKED 0xFFFFFFFF - /* Decode Win CTL_CODE values */ #define WIN_CTL_FUNCTION(ctl_code) ((ctl_code & 0x3FFC) >> 2) #define WIN_CTL_DEVICE_TYPE(ctl_code) (ctl_code >> 16) @@ -138,7 +136,8 @@ static UINT32 handle_PrivateTypeHeader(SMARTCARD_DEVICE* scard, IRP* irp, size_t if (Stream_GetRemainingLength(irp->input) < 8) { - DEBUG_WARN("Length violation"); + DEBUG_WARN("length violation %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -171,7 +170,8 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) if (Stream_GetRemainingLength(irp->input) < 4) { - DEBUG_WARN("Length violation"); + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -179,7 +179,8 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) Stream_Read_UINT32(irp->input, len); if (Stream_GetRemainingLength(irp->input) < len) { - DEBUG_WARN("Length violation"); + DEBUG_WARN("length violation %d [%d]", len, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -187,7 +188,8 @@ static UINT32 handle_Context(SMARTCARD_DEVICE* scard, IRP* irp, size_t *inlen) if (len > Stream_GetRemainingLength(irp->input)) { - DEBUG_WARN("Length violation missing payload"); + DEBUG_WARN("length violation %d [%d]", len, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -290,7 +292,7 @@ static UINT32 handle_RedirHandleRef(SMARTCARD_DEVICE* scard, IRP* irp, Stream_Read_UINT32(irp->input, len); if (len != 4) { - DEBUG_WARN("length field violation %d [%d]", 4, len); + DEBUG_WARN("length violation %d [%d]", len, 4); return SCARD_F_INTERNAL_ERROR; } @@ -557,18 +559,6 @@ static UINT32 smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide) return 0; } -static void smartcard_input_skip_linked(IRP* irp) -{ - UINT32 len; - Stream_Read_UINT32(irp->input, len); - - if (len > 0) - { - Stream_Seek(irp->input, len); - smartcard_input_repos(irp, len); - } -} - static UINT32 smartcard_map_state(UINT32 state) { /* is this mapping still needed? */ @@ -606,10 +596,10 @@ static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t return status; /* Ensure, that the capacity expected is actually available. */ - if (inlen < 4) + if (Stream_GetRemainingLength(irp->input) < 4) { - DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", - Stream_GetRemainingLength(irp->input), inlen); + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -712,29 +702,30 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_Context(scard, irp, &inlen); if (status) - return status; + goto finish; /* Ensure, that the capacity expected is actually available. */ - if (inlen < 0x10) + if (Stream_GetRemainingLength(irp->input) < 0x10) { - DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", - Stream_GetRemainingLength(irp->input), inlen); - return SCARD_F_INTERNAL_ERROR; + DEBUG_WARN("length violation %d [%d]", 0x10, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Seek(irp->input, 0x10); /* Read RedirScardcontextRef */ status = handle_RedirContextRef(scard, irp, &inlen, &hContext); if (status) - return status; + goto finish; /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ @@ -751,7 +742,7 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); - return status; + goto finish; } /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ @@ -804,11 +795,15 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, smartcard_output_repos(irp, dataLength); smartcard_output_alignment(irp, 8); +finish: + if (readerList) + { #ifdef SCARD_AUTOALLOCATE - SCardFreeMemory(hContext, readerList); + SCardFreeMemory(hContext, readerList); #else - free(readerList); + free(readerList); #endif + } return status; } @@ -820,26 +815,27 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i SCARDCONTEXT hContext; DWORD dwTimeout = 0; DWORD readerCount = 0; - SCARD_READERSTATE *readerStates, *cur; + SCARD_READERSTATE *readerStates = NULL, *cur; status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_Context(scard, irp, &inlen); if (status) - return status; + goto finish; /* Ensure, that the capacity expected is actually available. */ - if (inlen < 12) + if (Stream_GetRemainingLength(irp->input) < 12) { - DEBUG_WARN("Invalid IRP of length %d received, expected %d, ignoring.", - Stream_GetRemainingLength(irp->input), inlen); - return SCARD_F_INTERNAL_ERROR; + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); + status =SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Read_UINT32(irp->input, dwTimeout); @@ -851,9 +847,16 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i /* Get context */ status = handle_RedirContextRef(scard, irp, &inlen, &hContext); if (status) - return status; + goto finish; /* Skip ReaderStateConformant */ + if (Stream_GetRemainingLength(irp->input) < 4 ) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } Stream_Seek(irp->input, 4); DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", @@ -864,13 +867,18 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i readerStates = malloc(readerCount * sizeof(SCARD_READERSTATE)); ZeroMemory(readerStates, readerCount * sizeof(SCARD_READERSTATE)); - if (!readerStates) - return smartcard_output_return(irp, SCARD_E_NO_MEMORY); - for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; + if (Stream_GetRemainingLength(irp->input) < 52 ) + { + DEBUG_WARN("length violation %d [%d]", 52, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + Stream_Seek(irp->input, 4); /* @@ -895,9 +903,26 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i cur = &readerStates[i]; UINT32 dataLength; + if (Stream_GetRemainingLength(irp->input) < 12 ) + { + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + Stream_Seek(irp->input, 8); Stream_Read_UINT32(irp->input, dataLength); - smartcard_input_repos(irp, smartcard_input_string(irp, (char **) &cur->szReader, dataLength, wide)); + + if (Stream_GetRemainingLength(irp->input) < dataLength ) + { + DEBUG_WARN("length violation %d [%d]", dataLength, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + smartcard_input_repos(irp, smartcard_input_string(irp, + (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", @@ -951,7 +976,10 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, size_t i smartcard_output_alignment(irp, 8); - free(readerStates); +finish: + if (readerStates) + free(readerStates); + return status; } @@ -1000,31 +1028,33 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; /* Skip ptrReader */ if (Stream_GetRemainingLength(irp->input) < 4) { DEBUG_WARN("Length violadion %d [%d]", 4, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Seek(irp->input, 4); /* Read common data */ status = handle_Context(scard, irp, &inlen); if (status) - return status; + goto finish; if (Stream_GetRemainingLength(irp->input) < 8) { DEBUG_WARN("Length violadion %d [%d]", 8, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Read_UINT32(irp->input, dwShareMode); @@ -1032,11 +1062,11 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO status = smartcard_input_reader_name(irp, &readerName, wide); if (status) - return status; + goto finish; status = handle_RedirContextRef(scard, irp, &inlen, &hContext); if (status) - return status; + goto finish; DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")", (unsigned) hContext, (unsigned) dwShareMode, @@ -1045,7 +1075,8 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO if (!check_reader_is_forwarded(scard, readerName)) { DEBUG_WARN("Reader '%s' not forwarded!", readerName); - return SCARD_E_INVALID_TARGET; + status = SCARD_E_INVALID_TARGET; + goto finish; } status = SCardConnect(hContext, readerName, (DWORD) dwShareMode, @@ -1066,7 +1097,10 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen, BO smartcard_output_alignment(irp, 8); - free(readerName); +finish: + if (readerName) + free(readerName); + return status; } @@ -1093,7 +1127,11 @@ static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) return status; if (Stream_GetRemainingLength(irp->input) < 12) + { + DEBUG_WARN("length violation %d [%d]", 12, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, dwShareMode); Stream_Read_UINT32(irp->input, dwPreferredProtocol); @@ -1147,7 +1185,11 @@ static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) return status; if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, dwDisposition); @@ -1195,7 +1237,11 @@ static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t return status; if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; + } Stream_Seek(irp->input, 4); status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); @@ -1240,7 +1286,11 @@ static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp, size_t in return status; if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; + } Stream_Read_UINT32(irp->input, dwDisposition); status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); @@ -1282,18 +1332,23 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_CardHandle(scard, irp, &inlen); if (status) - return status; + goto finish; if (Stream_GetRemainingLength(irp->input) < 8) - return SCARD_F_INTERNAL_ERROR; + { + DEBUG_WARN("length violation %d [%d]", 8, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } Stream_Seek(irp->input, 4); Stream_Seek_UINT32(irp->input); /* atrLen */ @@ -1301,12 +1356,13 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); if (status) - return status; + goto finish; if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); - return SCARD_E_INVALID_TARGET; + status = SCARD_E_INVALID_TARGET; + goto finish; } #ifdef SCARD_AUTOALLOCATE @@ -1323,7 +1379,8 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); - return smartcard_output_return(irp, status); + status = smartcard_output_return(irp, status); + goto finish; } DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)", @@ -1348,11 +1405,15 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) smartcard_output_repos(irp, atrLen); smartcard_output_alignment(irp, 8); +finish: + if (readerName) + { #ifdef SCARD_AUTOALLOCATE - SCardFreeMemory(hContext, readerName); + SCardFreeMemory(hContext, readerName); #else - free(readerName); + free(readerName); #endif + } return status; } @@ -1376,21 +1437,22 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_CardHandle(scard, irp, &inlen); if (status) - return status; + goto finish; if (Stream_GetRemainingLength(irp->input) < 12) { DEBUG_WARN("length violation %d [%d]", 12, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Seek(irp->input, 4); Stream_Read_UINT32(irp->input, readerLen); @@ -1398,14 +1460,15 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); if (status) - return status; + goto finish; atrLen = MAX_ATR_SIZE; if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); - return SCARD_E_INVALID_TARGET; + status = SCARD_E_INVALID_TARGET; + goto finish; } #ifdef SCARD_AUTOALLOCATE @@ -1422,7 +1485,8 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); - return smartcard_output_return(irp, status); + status = smartcard_output_return(irp, status); + goto finish; } DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol); @@ -1464,11 +1528,15 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL smartcard_output_alignment(irp, 8); +finish: + if (readerName) + { #ifdef SCARD_AUTOALLOCATE - SCardFreeMemory(hContext, readerName); + SCardFreeMemory(hContext, readerName); #else - free(readerName); + free(readerName); #endif + } return status; } @@ -1478,165 +1546,128 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) LONG status; SCARDHANDLE hCard; SCARDCONTEXT hContext; - UINT32 map[7], linkedLen; + UINT32 pioSendPciBufferPtr; + UINT32 ptrSendBuffer; + UINT32 ptrIoRecvPciBuffer; + UINT32 recvBufferIsNULL; + UINT32 linkedLen; SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; - BYTE *sendBuf = NULL, *recvBuf = NULL; + BYTE *sendBuf = NULL, *recvBuf = NULL, *ioSendPci = NULL; status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_CardHandle(scard, irp, &inlen); if (status) - return status; + goto finish; if (Stream_GetRemainingLength(irp->input) < 32) { DEBUG_WARN("length violation %d [%d]", 32, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); Stream_Read_UINT32(irp->input, pioSendPci.cbPciLength); - Stream_Read_UINT32(irp->input, map[2]); + Stream_Read_UINT32(irp->input, pioSendPciBufferPtr); Stream_Read_UINT32(irp->input, cbSendLength); - Stream_Read_UINT32(irp->input, map[3]); - Stream_Read_UINT32(irp->input, map[4]); - Stream_Read_UINT32(irp->input, map[5]); + Stream_Read_UINT32(irp->input, ptrSendBuffer); + Stream_Read_UINT32(irp->input, ptrIoRecvPciBuffer); + Stream_Read_UINT32(irp->input, recvBufferIsNULL); Stream_Read_UINT32(irp->input, cbRecvLength); status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); if (status) - return status; + goto finish; - if (map[2] & SCARD_INPUT_LINKED) + /* Check, if there is data available from the ipSendPci element */ + if (pioSendPciBufferPtr) { - /* sendPci */ if (Stream_GetRemainingLength(irp->input) < 8) { DEBUG_WARN("length violation %d [%d]", 8, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Read_UINT32(irp->input, linkedLen); Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); - if (Stream_GetRemainingLength(irp->input) < linkedLen - 4) + if (Stream_GetRemainingLength(irp->input) < linkedLen) { - DEBUG_WARN("length violation %d [%d]", linkedLen - 4, + DEBUG_WARN("length violation %d [%d]", linkedLen, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } - Stream_Seek(irp->input, linkedLen - 4); - - smartcard_input_repos(irp, linkedLen); + /* Skip data... For details see 2.2.1.8 SCardIO_Request in MS-RDPESC */ + ioSendPci = malloc(linkedLen); + Stream_Read(irp->input, ioSendPci, linkedLen); } - pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); + else + pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); - if (map[3] & SCARD_INPUT_LINKED) + /* Check, if there is data available from the SendBufferPointer */ + if (ptrSendBuffer) { if (Stream_GetRemainingLength(irp->input) < 4) { DEBUG_WARN("length violation %d [%d]", 4, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } - /* send buffer */ Stream_Read_UINT32(irp->input, linkedLen); if (Stream_GetRemainingLength(irp->input) < linkedLen) { DEBUG_WARN("length violation %d [%d]", linkedLen, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } sendBuf = malloc(linkedLen); Stream_Read(irp->input, sendBuf, linkedLen); - smartcard_input_repos(irp, linkedLen); } - if (cbRecvLength) + /* Check, if a response is desired. */ + if (cbRecvLength && !recvBufferIsNULL) recvBuf = malloc(cbRecvLength); + else + cbRecvLength = 0; - if (map[4] & SCARD_INPUT_LINKED) + if (ptrIoRecvPciBuffer) { if (Stream_GetRemainingLength(irp->input) < 8) { DEBUG_WARN("length violation %d [%d]", 8, Stream_GetRemainingLength(irp->input)); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } /* recvPci */ Stream_Read_UINT32(irp->input, linkedLen); Stream_Read_UINT32(irp->input, pioRecvPci.dwProtocol); - if (Stream_GetRemainingLength(irp->input) < linkedLen - 4) + if (Stream_GetRemainingLength(irp->input) < linkedLen) { - DEBUG_WARN("length violation %d [%d]", linkedLen - 4, + DEBUG_WARN("length violation %d [%d]", linkedLen, Stream_GetRemainingLength(irp->input)); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } - Stream_Seek(irp->input, linkedLen - 4); - smartcard_input_repos(irp, linkedLen); - - if (Stream_GetRemainingLength(irp->input) < 4) - { - DEBUG_WARN("length violation %d [%d]", 4, - Stream_GetRemainingLength(irp->input)); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_F_INTERNAL_ERROR; - } - Stream_Read_UINT32(irp->input, map[6]); - if (map[6] & SCARD_INPUT_LINKED) - { - /* not sure what this is */ - if (Stream_GetRemainingLength(irp->input) < 4) - { - DEBUG_WARN("length violation %d [%d]", 4, - Stream_GetRemainingLength(irp->input)); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_F_INTERNAL_ERROR; - } - Stream_Read_UINT32(irp->input, linkedLen); - - if (Stream_GetRemainingLength(irp->input) < linkedLen) - { - DEBUG_WARN("length violation %d [%d]", linkedLen, - Stream_GetRemainingLength(irp->input)); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_F_INTERNAL_ERROR; - } - Stream_Seek(irp->input, linkedLen); - - smartcard_input_repos(irp, linkedLen); - } - pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST); - pPioRecvPci = &pioRecvPci; + /* Skip data */ + Stream_Seek(irp->input, linkedLen); } else { @@ -1650,11 +1681,8 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); - if (sendBuf) - free(sendBuf); - if (recvBuf) - free(recvBuf); - return SCARD_E_INVALID_TARGET; + status = SCARD_E_INVALID_TARGET; + goto finish; } status = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, @@ -1679,10 +1707,13 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) smartcard_output_alignment(irp, 8); +finish: if (sendBuf) free(sendBuf); if (recvBuf) free(recvBuf); + if (ioSendPci) + free(ioSendPci); return status; } @@ -1692,7 +1723,7 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) LONG status; SCARDCONTEXT hContext; SCARDHANDLE hCard; - UINT32 map[3]; + UINT32 pvInBuffer, fpvOutBufferIsNULL; UINT32 controlCode; UINT32 controlFunction; BYTE* recvBuffer = NULL; @@ -1703,32 +1734,33 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_PrivateTypeHeader(scard, irp, &inlen); if (status) - return status; + goto finish; status = handle_CardHandle(scard, irp, &inlen); if (status) - return status; + goto finish; if (Stream_GetRemainingLength(irp->input) < 20) { DEBUG_WARN("length violation %d [%d]", 20, Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; + goto finish; } Stream_Read_UINT32(irp->input, controlCode); Stream_Read_UINT32(irp->input, recvLength); - Stream_Read_UINT32(irp->input, map[2]); - Stream_Seek(irp->input, 0x4); + Stream_Read_UINT32(irp->input, pvInBuffer); + Stream_Read_UINT32(irp->input, fpvOutBufferIsNULL); Stream_Read_UINT32(irp->input, outBufferSize); status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); if (status) - return status; + goto finish; /* Translate Windows SCARD_CTL_CODE's to corresponding local code */ if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD) @@ -1738,32 +1770,39 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } DEBUG_SCARD("controlCode: 0x%08x", (unsigned) controlCode); - if (map[2] & SCARD_INPUT_LINKED) + if (pvInBuffer) { - /* read real input size */ + /* Get the size of the linked data. */ + if (Stream_GetRemainingLength(irp->input) < 4) + { + DEBUG_WARN("length violation %d [%d]", 4, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } Stream_Read_UINT32(irp->input, recvLength); + /* Check, if there is actually enough data... */ + if (Stream_GetRemainingLength(irp->input) < recvLength) + { + DEBUG_WARN("length violation %d [%d]", recvLength, + Stream_GetRemainingLength(irp->input)); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } recvBuffer = malloc(recvLength); - if (!recvBuffer) - return smartcard_output_return(irp, SCARD_E_NO_MEMORY); - Stream_Read(irp->input, recvBuffer, recvLength); } nBytesReturned = outBufferSize; sendBuffer = malloc(outBufferSize); - if (!sendBuffer) - { - free(recvBuffer); - return smartcard_output_return(irp, SCARD_E_NO_MEMORY); - } - if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); - return SCARD_E_INVALID_TARGET; + status = SCARD_E_INVALID_TARGET; + goto finish; } status = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength, @@ -1786,8 +1825,11 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) smartcard_output_alignment(irp, 8); - free(recvBuffer); - free(sendBuffer); +finish: + if (recvBuffer) + free(recvBuffer); + if (sendBuffer) + free(sendBuffer); return status; } From 27cb9ee604de84ff53d9783e7bc48eb9ab189a49 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 14:10:44 +0200 Subject: [PATCH 127/202] Now printing debug message for unhandled data. --- channels/smartcard/client/smartcard_operations.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index b270ae2e1..6cc374f3a 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1553,7 +1553,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) UINT32 linkedLen; SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; - BYTE *sendBuf = NULL, *recvBuf = NULL, *ioSendPci = NULL; + BYTE *sendBuf = NULL, *recvBuf = NULL; status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) @@ -1609,9 +1609,15 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = SCARD_F_INTERNAL_ERROR; goto finish; } + if (linkedLen < sizeof(pioSendPci)) + { + DEBUG_WARN("length violation %d [%d]", sizeof(pioSendPci), linkedLen); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } /* Skip data... For details see 2.2.1.8 SCardIO_Request in MS-RDPESC */ - ioSendPci = malloc(linkedLen); - Stream_Read(irp->input, ioSendPci, linkedLen); + DEBUG_WARN("unhandled buffer data of length %d", linkedLen); + Stream_Seek(irp->input, linkedLen); } else pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); @@ -1667,6 +1673,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } /* Skip data */ + DEBUG_WARN("unhandled buffer data of length %d", linkedLen); Stream_Seek(irp->input, linkedLen); } else @@ -1712,8 +1719,6 @@ finish: free(sendBuf); if (recvBuf) free(recvBuf); - if (ioSendPci) - free(ioSendPci); return status; } From 31abdb910323deeb8eeb7521350a2d85814e8cfa Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 14:34:18 +0200 Subject: [PATCH 128/202] Fixed setting of smartcard filter name and path. --- channels/smartcard/client/smartcard_main.c | 49 ++++++++++------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 855df3ff0..e1eeed90f 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -320,41 +320,38 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) name = device->Name; path = device->Path; - if (name) - { - /* TODO: check if server supports sc redirect (version 5.1) */ + /* TODO: check if server supports sc redirect (version 5.1) */ + smartcard = (SMARTCARD_DEVICE*) malloc(sizeof(SMARTCARD_DEVICE)); + ZeroMemory(smartcard, sizeof(SMARTCARD_DEVICE)); - smartcard = (SMARTCARD_DEVICE*) malloc(sizeof(SMARTCARD_DEVICE)); - ZeroMemory(smartcard, sizeof(SMARTCARD_DEVICE)); + smartcard->device.type = RDPDR_DTYP_SMARTCARD; + smartcard->device.name = "SCARD"; + smartcard->device.IRPRequest = smartcard_irp_request; + smartcard->device.Free = smartcard_free; - smartcard->device.type = RDPDR_DTYP_SMARTCARD; - smartcard->device.name = "SCARD"; - smartcard->device.IRPRequest = smartcard_irp_request; - smartcard->device.Free = smartcard_free; + length = strlen(smartcard->device.name); + smartcard->device.data = Stream_New(NULL, length + 1); - length = strlen(smartcard->device.name); - smartcard->device.data = Stream_New(NULL, length + 1); + for (i = 0; i <= length; i++) + Stream_Write_UINT8(smartcard->device.data, name[i] < 0 ? '_' : name[i]); - for (i = 0; i <= length; i++) - Stream_Write_UINT8(smartcard->device.data, name[i] < 0 ? '_' : name[i]); + smartcard->path = path; + smartcard->name = name; - smartcard->path = path; + smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(smartcard->pIrpList); - smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); - InitializeSListHead(smartcard->pIrpList); + smartcard->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + smartcard->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func, + smartcard, CREATE_SUSPENDED, NULL); - smartcard->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - smartcard->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func, - smartcard, CREATE_SUSPENDED, NULL); + smartcard->CompletionIds = list_new(); + smartcard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL); - smartcard->CompletionIds = list_new(); - smartcard->CompletionIdsMutex = CreateMutex(NULL, FALSE, NULL); + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard); - pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard); - - ResumeThread(smartcard->thread); - } + ResumeThread(smartcard->thread); return 0; } From 8f024d46cffa91c2f04529e20181db7622efffe3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 14:41:11 +0200 Subject: [PATCH 129/202] Fixed setting of name and path of smartcard, now determining on number of valid arguments. --- channels/smartcard/client/smartcard_main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index e1eeed90f..31fd9e28b 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -312,7 +312,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { char* name; char* path; - int i, length; + int i, length, ck; RDPDR_SMARTCARD* device; SMARTCARD_DEVICE* smartcard; @@ -335,8 +335,20 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) for (i = 0; i <= length; i++) Stream_Write_UINT8(smartcard->device.data, name[i] < 0 ? '_' : name[i]); - smartcard->path = path; - smartcard->name = name; + smartcard->name = NULL; + smartcard->path = NULL; + if (path) + { + smartcard->path = path; + smartcard->name = name; + } + else + { + if (1 == sscanf(name, "%d", &ck)) + smartcard->path = name; + else + smartcard->name = name; + } smartcard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); InitializeSListHead(smartcard->pIrpList); From 513c963670b6a6da92b8deb77188be58cf661e7b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 14:55:25 +0200 Subject: [PATCH 130/202] Smartcard arguments now optional. --- channels/smartcard/client/smartcard_main.c | 5 ++--- client/common/cmdline.c | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 31fd9e28b..8fd6ee26e 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -332,8 +332,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) length = strlen(smartcard->device.name); smartcard->device.data = Stream_New(NULL, length + 1); - for (i = 0; i <= length; i++) - Stream_Write_UINT8(smartcard->device.data, name[i] < 0 ? '_' : name[i]); + Stream_Write(smartcard->device.data, "SCARD", 6); smartcard->name = NULL; smartcard->path = NULL; @@ -342,7 +341,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard->path = path; smartcard->name = name; } - else + else if (name) { if (1 == sscanf(name, "%d", &ck)) smartcard->path = name; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index bf0de4acc..1614c27bb 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -86,7 +86,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "clipboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect clipboard" }, { "serial", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "tty", "Redirect serial device" }, { "parallel", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect parallel device" }, - { "smartcard", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect smartcard device" }, + { "smartcard", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect smartcard device" }, { "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" }, { "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" }, { "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" }, @@ -428,6 +428,9 @@ char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) nArgs = nCommas = 0; + if (!list) + return NULL; + for (index = 0; list[index]; index++) nCommas += (list[index] == ',') ? 1 : 0; @@ -550,7 +553,6 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT int count; p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count); - fprintf(stderr, "[%s] %d %s %s %s\n", __func__, count, p[0], p[1], arg->Value); p[0] = "smartcard"; freerdp_client_add_device_channel(settings, count, p); From 32a9bd366cd7bf7b253ace9a1c679caa88681c27 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 12 Sep 2013 15:50:12 +0200 Subject: [PATCH 131/202] Fixed reading of SCARD_IO_REQUEST structures in Transmit_Call. --- .../smartcard/client/smartcard_operations.c | 64 +++++++++++++------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 6cc374f3a..3e57ff26b 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1551,7 +1551,14 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) UINT32 ptrIoRecvPciBuffer; UINT32 recvBufferIsNULL; UINT32 linkedLen; - SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; + union + { + SCARD_IO_REQUEST *rq; + UINT32 *u32; + void *v; + } ioSendPci, ioRecvPci; + + SCARD_IO_REQUEST *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; @@ -1575,8 +1582,11 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; } - Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); - Stream_Read_UINT32(irp->input, pioSendPci.cbPciLength); + ioSendPci.v = malloc(sizeof(SCARD_IO_REQUEST)); + ioRecvPci.v = malloc(sizeof(SCARD_IO_REQUEST)); + + Stream_Read_UINT32(irp->input, ioSendPci.rq->dwProtocol); + Stream_Read_UINT32(irp->input, ioSendPci.rq->cbPciLength); Stream_Read_UINT32(irp->input, pioSendPciBufferPtr); Stream_Read_UINT32(irp->input, cbSendLength); @@ -1600,7 +1610,6 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; } Stream_Read_UINT32(irp->input, linkedLen); - Stream_Read_UINT32(irp->input, pioSendPci.dwProtocol); if (Stream_GetRemainingLength(irp->input) < linkedLen) { @@ -1609,18 +1618,22 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = SCARD_F_INTERNAL_ERROR; goto finish; } - if (linkedLen < sizeof(pioSendPci)) + + /* For details see 2.2.1.8 SCardIO_Request in MS-RDPESC and + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379807%28v=vs.85%29.aspx + */ + if (linkedLen != ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST)) { - DEBUG_WARN("length violation %d [%d]", sizeof(pioSendPci), linkedLen); + DEBUG_WARN("SCARD_IO_REQUEST with invalid extra byte length %d [%d]", + ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); status = SCARD_F_INTERNAL_ERROR; goto finish; } - /* Skip data... For details see 2.2.1.8 SCardIO_Request in MS-RDPESC */ - DEBUG_WARN("unhandled buffer data of length %d", linkedLen); - Stream_Seek(irp->input, linkedLen); + ioSendPci.v = realloc(ioSendPci.v, ioSendPci.rq->cbPciLength); + Stream_Read(irp->input, &ioSendPci.rq[1], linkedLen); } else - pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); + ioSendPci.rq->cbPciLength = sizeof(SCARD_IO_REQUEST); /* Check, if there is data available from the SendBufferPointer */ if (ptrSendBuffer) @@ -1662,7 +1675,17 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } /* recvPci */ Stream_Read_UINT32(irp->input, linkedLen); - Stream_Read_UINT32(irp->input, pioRecvPci.dwProtocol); + Stream_Read_UINT16(irp->input, ioRecvPci.rq->dwProtocol); + Stream_Read_UINT16(irp->input, ioRecvPci.rq->cbPciLength); + + if (linkedLen != ioSendPci.rq->cbPciLength) + { + DEBUG_WARN("SCARD_IO_REQUEST with invalid extra byte length %d [%d]", + ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + linkedLen -= 4; if (Stream_GetRemainingLength(irp->input) < linkedLen) { @@ -1672,15 +1695,16 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; } - /* Skip data */ - DEBUG_WARN("unhandled buffer data of length %d", linkedLen); - Stream_Seek(irp->input, linkedLen); + /* Read data, see + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379807%28v=vs.85%29.aspx + */ + ioRecvPci.v = realloc(ioRecvPci.v, ioRecvPci.rq->cbPciLength); + Stream_Read(irp->input, &ioRecvPci.rq[1], linkedLen); + + pPioRecvPci = ioRecvPci.rq; } else - { pPioRecvPci = NULL; - } - pPioRecvPci = NULL; DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)", (long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength); @@ -1692,7 +1716,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; } - status = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, + status = SCardTransmit(hCard, ioSendPci.rq, sendBuf, cbSendLength, pPioRecvPci, recvBuf, &cbRecvLength); if (status != SCARD_S_SUCCESS) @@ -1719,6 +1743,10 @@ finish: free(sendBuf); if (recvBuf) free(recvBuf); + if (ioSendPci.v) + free(ioSendPci.v); + if (ioRecvPci.v) + free(ioRecvPci.v); return status; } From 7cf95bcf6ea19e535921e7205dcffb9627c71855 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 13 Sep 2013 09:17:06 +0200 Subject: [PATCH 132/202] Fixed compile error. --- channels/smartcard/client/smartcard_operations.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 3e57ff26b..c9da2e15d 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1425,7 +1425,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL SCARDCONTEXT hContext; DWORD state, protocol; DWORD readerLen = 0; - DWORD atrLen = 0; + DWORD atrLen = MAX_ATR_SIZE; char* readerName; BYTE pbAtr[MAX_ATR_SIZE]; UINT32 dataLength; @@ -1462,8 +1462,6 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL if (status) goto finish; - atrLen = MAX_ATR_SIZE; - if (!check_handle_is_forwarded(scard, hCard, hContext)) { DEBUG_WARN("invalid handle %p [%p]", hCard, hContext); @@ -1493,7 +1491,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL DEBUG_SCARD(" Reader: \"%s\"", readerName ? readerName : "NULL"); #ifdef WITH_DEBUG_SCARD - stderr, " ATR: "); + fprintf(stderr, " ATR: "); for (i = 0; i < atrLen; i++) fprintf(stderr, "%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); fprintf(stderr, "\n"); From cbf5e7e3f85a9e0ffeb5f41b8fcbf1471f464cfb Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 13 Sep 2013 09:47:18 +0200 Subject: [PATCH 133/202] Fixed clang warnings. --- .../smartcard/client/smartcard_operations.c | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index c9da2e15d..1fe48bf5d 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -331,8 +331,10 @@ static BOOL check_reader_is_forwarded(SMARTCARD_DEVICE *scard, const char *reade str = strtok(NULL, " "); } + if (!strpos) + goto finally; + pos = strtol(strpos, NULL, 10); - status = strtol(strstatus, NULL, 10); if ( strpos && strstatus ) { @@ -351,6 +353,7 @@ static BOOL check_reader_is_forwarded(SMARTCARD_DEVICE *scard, const char *reade else DEBUG_WARN("unknown reader format '%s'", readerName); +finally: free(name); if (!rc) @@ -617,7 +620,7 @@ static UINT32 handle_EstablishContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t /* TODO: store hContext in allowed context list */ smartcard_output_alignment(irp, 8); - return SCARD_S_SUCCESS; + return status; } static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) @@ -729,7 +732,6 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ - status = SCARD_S_SUCCESS; #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; status = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); @@ -1323,7 +1325,7 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) DWORD state = 0, protocol = 0; DWORD readerLen; DWORD atrLen = MAX_ATR_SIZE; - char* readerName; + char* readerName = NULL; BYTE pbAtr[MAX_ATR_SIZE]; #ifdef WITH_DEBUG_SCARD @@ -1426,9 +1428,9 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL DWORD state, protocol; DWORD readerLen = 0; DWORD atrLen = MAX_ATR_SIZE; - char* readerName; - BYTE pbAtr[MAX_ATR_SIZE]; - UINT32 dataLength; + char* readerName = NULL; + BYTE *pbAtr = NULL; + UINT32 dataLength = 0; int pos, poslen1, poslen2; #ifdef WITH_DEBUG_SCARD @@ -1469,6 +1471,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL goto finish; } + pbAtr = malloc(sizeof(BYTE) * atrLen); #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; @@ -1513,7 +1516,8 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, size_t inlen, BOOL poslen2 = Stream_GetPosition(irp->output); Stream_Write_UINT32(irp->output, readerLen); - dataLength = smartcard_output_string(irp, readerName, wide); + if (readerName) + dataLength += smartcard_output_string(irp, readerName, wide); dataLength += smartcard_output_string(irp, "\0", wide); smartcard_output_repos(irp, dataLength); @@ -1536,6 +1540,9 @@ finish: #endif } + if (pbAtr) + free(pbAtr); + return status; } @@ -1549,6 +1556,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) UINT32 ptrIoRecvPciBuffer; UINT32 recvBufferIsNULL; UINT32 linkedLen; + void *tmp; union { SCARD_IO_REQUEST *rq; @@ -1556,10 +1564,13 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) void *v; } ioSendPci, ioRecvPci; - SCARD_IO_REQUEST *pPioRecvPci; + SCARD_IO_REQUEST *pPioRecvPci = NULL; DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; + ioSendPci.v = NULL; + ioRecvPci.v = NULL; + status = handle_CommonTypeHeader(scard, irp, &inlen); if (status) goto finish; @@ -1627,7 +1638,11 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = SCARD_F_INTERNAL_ERROR; goto finish; } - ioSendPci.v = realloc(ioSendPci.v, ioSendPci.rq->cbPciLength); + tmp = realloc(ioSendPci.v, ioSendPci.rq->cbPciLength); + if (!tmp) + goto finish; + ioSendPci.v = tmp; + Stream_Read(irp->input, &ioSendPci.rq[1], linkedLen); } else @@ -1696,7 +1711,11 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) /* Read data, see * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379807%28v=vs.85%29.aspx */ - ioRecvPci.v = realloc(ioRecvPci.v, ioRecvPci.rq->cbPciLength); + tmp = realloc(ioRecvPci.v, ioRecvPci.rq->cbPciLength); + if (!tmp) + goto finish; + ioRecvPci.v = tmp; + Stream_Read(irp->input, &ioRecvPci.rq[1], linkedLen); pPioRecvPci = ioRecvPci.rq; From 0729f3b7803970f17d0495a1e1535f0e78133987 Mon Sep 17 00:00:00 2001 From: Giacomo Rombaut Date: Fri, 13 Sep 2013 15:22:10 +0200 Subject: [PATCH 134/202] Respond to DYNVC_CLOSE like described in MS-RDPEDYC --- channels/drdynvc/client/drdynvc_main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index a605ba205..05600014a 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -284,10 +284,27 @@ static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStr static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { UINT32 ChannelId; + wStream* data_out; + int value; + int error; ChannelId = drdynvc_read_variable_uint(s, cbChId); DEBUG_DVC("ChannelId=%d", ChannelId); dvcman_close_channel(drdynvc->channel_mgr, ChannelId); + + data_out = Stream_New(NULL, 4); + value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x02); + Stream_Write_UINT8(data_out, value); + drdynvc_write_variable_uint(data_out, ChannelId); + error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); + + if (error != CHANNEL_RC_OK) + { + DEBUG_WARN("VirtualChannelWrite failed %d", error); + return 1; + } + + drdynvc->channel_error = error; return 0; } From 999c571335d2cc22142e5a8a6fcd8ffe65987b24 Mon Sep 17 00:00:00 2001 From: Todd McKinney Date: Fri, 13 Sep 2013 14:22:16 -0500 Subject: [PATCH 135/202] Modify Fit Screen option to not require global context object --- .../FreeRDPCore/res/values-es/strings.xml | 9 ++++--- .../FreeRDPCore/res/values-fr/strings.xml | 25 +++++++++++-------- .../FreeRDPCore/res/values-nl/strings.xml | 9 ++++--- .../freerdpcore/application/GlobalApp.java | 3 +++ .../application/GlobalSettings.java | 2 -- .../freerdpcore/domain/BookmarkBase.java | 8 +++--- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/client/Android/FreeRDPCore/res/values-es/strings.xml b/client/Android/FreeRDPCore/res/values-es/strings.xml index 620823ca6..e539660de 100644 --- a/client/Android/FreeRDPCore/res/values-es/strings.xml +++ b/client/Android/FreeRDPCore/res/values-es/strings.xml @@ -79,10 +79,12 @@ 1920x1080 1920x1200 + + - automatico - pantalla - manual + automatic + fitscreen + custom 640x480 720x480 800x600 @@ -92,6 +94,7 @@ 1920x1080 1920x1200 + Ancho Altura Rendimiento diff --git a/client/Android/FreeRDPCore/res/values-fr/strings.xml b/client/Android/FreeRDPCore/res/values-fr/strings.xml index 7c1ff6d14..ffd74bf32 100644 --- a/client/Android/FreeRDPCore/res/values-fr/strings.xml +++ b/client/Android/FreeRDPCore/res/values-fr/strings.xml @@ -78,19 +78,22 @@ "1920x1080" "1920x1200" + + - "Automatique" - "fenêtre" - "Personalisé" - "640x480" - "720x480" - "800x600" - "1024x768" - "1280x1024" - "1440x900" - "1920x1080" - "1920x1200" + automatic + fitscreen + custom + 640x480 + 720x480 + 800x600 + 1024x768 + 1280x1024 + 1440x900 + 1920x1080 + 1920x1200 + "Largeur" "Hauteur" "Performance" diff --git a/client/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml index 0ddc53697..03c694aa5 100644 --- a/client/Android/FreeRDPCore/res/values-nl/strings.xml +++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml @@ -79,10 +79,12 @@ 1920x1080 1920x1200 + + - Automatisch - Schermvullend - Aangepast + automatic + fitscreen + custom 640x480 720x480 800x600 @@ -92,6 +94,7 @@ 1920x1080 1920x1200 + Breedte Hoogte Prestatie diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java index aca737a4b..e280ae6ff 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java @@ -12,6 +12,7 @@ package com.freerdp.freerdpcore.application; import android.app.Application; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Resources; import android.util.Log; import java.util.*; @@ -50,6 +51,7 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener // timer for disconnecting sessions after the screen was turned off private static Timer disconnectTimer = null; + public static GlobalApp instance = null; // TimerTask for disconnecting sessions after screen was turned off private static class DisconnectTask extends TimerTask @@ -88,6 +90,7 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener quickConnectHistoryGateway = new QuickConnectHistoryGateway(historyDB); GlobalSettings.init(this); + instance = this; ConnectedTo3G = NetworkStateReceiver.isConnectedTo3G(this); // init screen receiver here (this can't be declared in AndroidManifest - refer to: diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java index e44a3e750..5b876dd94 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalSettings.java @@ -27,11 +27,9 @@ public class GlobalSettings { private static final String PREF_SECURITY_ACCEPTALLCERTIFICATES = "security.accept_certificates"; private static SharedPreferences settings; - public static Context initialContext; public static void init(Context context) { - initialContext = context; settings = PreferenceManager.getDefaultSharedPreferences(context); initValues(); } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java index 7c7c36389..87a65dd15 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java @@ -191,13 +191,13 @@ public class BookmarkBase implements Parcelable, Cloneable this.height = Integer.valueOf(dimensions[1]); this.resolution = PREDEFINED; } - else if (resolution.equalsIgnoreCase(GlobalSettings.initialContext.getResources().getString(R.string.resolution_custom))) + else if (resolution.equalsIgnoreCase("custom")) { this.width = width; this.height = height; this.resolution = CUSTOM; } - else if (resolution.equalsIgnoreCase(GlobalSettings.initialContext.getResources().getString(R.string.resolution_fit))) + else if (resolution.equalsIgnoreCase("fitscreen")) { this.width = this.height = 0; this.resolution = FITSCREEN; @@ -219,9 +219,7 @@ public class BookmarkBase implements Parcelable, Cloneable if (isPredefined()) return (width + "x" + height); - return (isFitScreen() ? GlobalSettings.initialContext.getResources().getString(R.string.resolution_fit) : - isAutomatic() ? GlobalSettings.initialContext.getResources().getString(R.string.resolution_automatic) : - GlobalSettings.initialContext.getResources().getString(R.string.resolution_custom)); + return (isFitScreen() ? "fitscreen" : isAutomatic() ? "automatic" : "custom"); } public boolean isPredefined() { From 311da0472091f57b88d60dfea3d45bbb378191f3 Mon Sep 17 00:00:00 2001 From: Todd McKinney Date: Fri, 13 Sep 2013 14:54:28 -0500 Subject: [PATCH 136/202] Modify Fit Screen option to not require global context object --- .../src/com/freerdp/freerdpcore/application/GlobalApp.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java index e280ae6ff..aca737a4b 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/application/GlobalApp.java @@ -12,7 +12,6 @@ package com.freerdp.freerdpcore.application; import android.app.Application; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; import android.util.Log; import java.util.*; @@ -51,7 +50,6 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener // timer for disconnecting sessions after the screen was turned off private static Timer disconnectTimer = null; - public static GlobalApp instance = null; // TimerTask for disconnecting sessions after screen was turned off private static class DisconnectTask extends TimerTask @@ -90,7 +88,6 @@ public class GlobalApp extends Application implements LibFreeRDP.EventListener quickConnectHistoryGateway = new QuickConnectHistoryGateway(historyDB); GlobalSettings.init(this); - instance = this; ConnectedTo3G = NetworkStateReceiver.isConnectedTo3G(this); // init screen receiver here (this can't be declared in AndroidManifest - refer to: From 6a8b5f228302be18191ab6b0d335bcdb534907e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 15 Sep 2013 15:46:02 -0400 Subject: [PATCH 137/202] libwinpr-utils: start implementing WinPR logger --- winpr/include/winpr/print.h | 4 + winpr/include/winpr/wlog.h | 59 +++++++++++ winpr/libwinpr/utils/CMakeLists.txt | 3 +- winpr/libwinpr/utils/print.c | 5 + winpr/libwinpr/utils/test/CMakeLists.txt | 1 + winpr/libwinpr/utils/test/TestWLog.c | 12 +++ winpr/libwinpr/utils/wlog.c | 128 +++++++++++++++++++++++ 7 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 winpr/include/winpr/wlog.h create mode 100644 winpr/libwinpr/utils/test/TestWLog.c create mode 100644 winpr/libwinpr/utils/wlog.c diff --git a/winpr/include/winpr/print.h b/winpr/include/winpr/print.h index d5e9cc724..5838fba76 100644 --- a/winpr/include/winpr/print.h +++ b/winpr/include/winpr/print.h @@ -20,6 +20,8 @@ #ifndef WINPR_UTILS_PRINT_H #define WINPR_UTILS_PRINT_H +#include + #include #include @@ -32,6 +34,8 @@ extern "C" { WINPR_API void winpr_HexDump(BYTE* data, int length); WINPR_API int wprintfx(const char *fmt, ...); +WINPR_API int wvprintfx(const char *fmt, va_list args); +WINPR_API int wvsnprintfx(char *buffer, size_t bufferSize, const char* fmt, va_list args); #ifdef __cplusplus } diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h new file mode 100644 index 000000000..c5c37d24e --- /dev/null +++ b/winpr/include/winpr/wlog.h @@ -0,0 +1,59 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_LOG_H +#define WINPR_LOG_H + +#include +#include + +#define WLOG_TRACE 0 +#define WLOG_DEBUG 1 +#define WLOG_INFO 2 +#define WLOG_WARN 3 +#define WLOG_ERROR 4 +#define WLOG_FATAL 5 + +WINPR_API void WLog_LogA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_TraceA(LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_DebugA(LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_InfoA(LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_WarnA(LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_ErrorA(LPCSTR loggerName, LPCSTR logMessage, ...); +WINPR_API void WLog_FatalA(LPCSTR loggerName, LPCSTR logMessage, ...); + +#ifdef UNICODE +#define WLog_Log WLog_LogW +#define WLog_Trace WLog_TraceW +#define WLog_Debug WLog_DebugW +#define WLog_Info WLog_InfoW +#define WLog_Warn WLog_WarnW +#define WLog_Error WLog_ErrorW +#define WLog_Fatal WLog_FatalW +#else +#define WLog_Log WLog_LogA +#define WLog_Trace WLog_TraceA +#define WLog_Debug WLog_DebugA +#define WLog_Info WLog_InfoA +#define WLog_Warn WLog_WarnA +#define WLog_Error WLog_ErrorA +#define WLog_Fatal WLog_FatalA +#endif + +#endif /* WINPR_WLOG_H */ diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index d7db7b6d6..1154dc3f0 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -51,7 +51,8 @@ set(${MODULE_PREFIX}_SRCS ntlm.c print.c stream.c - cmdline.c) + cmdline.c + wlog.c) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_COLLECTIONS_SRCS} diff --git a/winpr/libwinpr/utils/print.c b/winpr/libwinpr/utils/print.c index ed9f55af8..8d98b100f 100644 --- a/winpr/libwinpr/utils/print.c +++ b/winpr/libwinpr/utils/print.c @@ -76,3 +76,8 @@ int wprintfx(const char *fmt, ...) return status; } + +int wvsnprintfx(char *buffer, size_t bufferSize, const char* fmt, va_list args) +{ + return trio_vsnprintf(buffer, bufferSize, fmt, args); +} diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt index 31d1de762..841e1dea2 100644 --- a/winpr/libwinpr/utils/test/CMakeLists.txt +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS TestLinkedList.c TestListDictionary.c TestCmdLine.c + TestWLog.c TestBufferPool.c TestStreamPool.c TestMessageQueue.c diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c new file mode 100644 index 000000000..2129739cd --- /dev/null +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -0,0 +1,12 @@ + +#include +#include +#include + +int TestWLog(int argc, char* argv[]) +{ + WLog_TraceA("TEST", "this is a test"); + WLog_TraceA("TEST", "this is a %dnd %s", 2, "test"); + + return 0; +} diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c new file mode 100644 index 000000000..fb1fc279d --- /dev/null +++ b/winpr/libwinpr/utils/wlog.c @@ -0,0 +1,128 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include + +#define WLOG_BUFFER_SIZE 8192 + +void WLog_WriteA(int logLevel, LPCSTR loggerName, LPCSTR logMessage) +{ + switch (logLevel) + { + case WLOG_TRACE: + break; + + case WLOG_DEBUG: + break; + + case WLOG_INFO: + break; + + case WLOG_WARN: + break; + + case WLOG_ERROR: + break; + + case WLOG_FATAL: + break; + } + + printf("[%s]: %s\n", loggerName, logMessage); +} + +void WLog_LogVA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, va_list args) +{ + if (!strchr(logMessage, '%')) + { + WLog_WriteA(logLevel, loggerName, logMessage); + } + else + { + char formattedLogMessage[8192]; + wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage, args); + WLog_WriteA(logLevel, loggerName, formattedLogMessage); + } +} + +void WLog_LogA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(logLevel, loggerName, logMessage, args); + va_end(args); +} + +void WLog_TraceA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_TRACE, loggerName, logMessage, args); + va_end(args); +} + +void WLog_DebugA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_DEBUG, loggerName, logMessage, args); + va_end(args); +} + +void WLog_InfoA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_INFO, loggerName, logMessage, args); + va_end(args); +} + +void WLog_WarnA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_WARN, loggerName, logMessage, args); + va_end(args); +} + +void WLog_ErrorA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_ERROR, loggerName, logMessage, args); + va_end(args); +} + +void WLog_FatalA(LPCSTR loggerName, LPCSTR logMessage, ...) +{ + va_list args; + va_start(args, logMessage); + WLog_LogVA(WLOG_FATAL, loggerName, logMessage, args); + va_end(args); +} From 968ef14349af737a0e26730c41447a09afff92c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 15 Sep 2013 16:48:09 -0400 Subject: [PATCH 138/202] libwinpr-utils: introduce trace levels --- winpr/include/winpr/wlog.h | 38 ++++------ winpr/libwinpr/utils/test/TestWLog.c | 13 +++- winpr/libwinpr/utils/wlog.c | 109 ++++++++++++--------------- 3 files changed, 74 insertions(+), 86 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index c5c37d24e..70da16f05 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -29,31 +29,21 @@ #define WLOG_WARN 3 #define WLOG_ERROR 4 #define WLOG_FATAL 5 +#define WLOG_OFF 6 -WINPR_API void WLog_LogA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_TraceA(LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_DebugA(LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_InfoA(LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_WarnA(LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_ErrorA(LPCSTR loggerName, LPCSTR logMessage, ...); -WINPR_API void WLog_FatalA(LPCSTR loggerName, LPCSTR logMessage, ...); +struct _wLog +{ + LPSTR Name; + DWORD Level; +}; +typedef struct _wLog wLog; -#ifdef UNICODE -#define WLog_Log WLog_LogW -#define WLog_Trace WLog_TraceW -#define WLog_Debug WLog_DebugW -#define WLog_Info WLog_InfoW -#define WLog_Warn WLog_WarnW -#define WLog_Error WLog_ErrorW -#define WLog_Fatal WLog_FatalW -#else -#define WLog_Log WLog_LogA -#define WLog_Trace WLog_TraceA -#define WLog_Debug WLog_DebugA -#define WLog_Info WLog_InfoA -#define WLog_Warn WLog_WarnA -#define WLog_Error WLog_ErrorA -#define WLog_Fatal WLog_FatalA -#endif +WINPR_API void WLog_Print(wLog* log, DWORD logLevel, LPCSTR logMessage, ...); + +WINPR_API DWORD WLog_GetLogLevel(wLog* log); +WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel); + +WINPR_API wLog* WLog_New(LPCSTR name); +WINPR_API void WLog_Free(wLog* log); #endif /* WINPR_WLOG_H */ diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c index 2129739cd..5ded9417f 100644 --- a/winpr/libwinpr/utils/test/TestWLog.c +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -5,8 +5,17 @@ int TestWLog(int argc, char* argv[]) { - WLog_TraceA("TEST", "this is a test"); - WLog_TraceA("TEST", "this is a %dnd %s", 2, "test"); + wLog* log; + + log = WLog_New("TEST"); + + WLog_SetLogLevel(log, WLOG_INFO); + WLog_Print(log, WLOG_INFO, "this is a test"); + WLog_Print(log, WLOG_WARN, "this is a %dnd %s", 2, "test"); + WLog_Print(log, WLOG_ERROR, "this is an error"); + WLog_Print(log, WLOG_TRACE, "this is a trace output"); + + WLog_Free(log); return 0; } diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c index fb1fc279d..3b0650ff4 100644 --- a/winpr/libwinpr/utils/wlog.c +++ b/winpr/libwinpr/utils/wlog.c @@ -25,104 +25,93 @@ #include #include +#include #include #include #define WLOG_BUFFER_SIZE 8192 -void WLog_WriteA(int logLevel, LPCSTR loggerName, LPCSTR logMessage) +const char* WLOG_LEVELS[7] = { - switch (logLevel) - { - case WLOG_TRACE: - break; + "Trace", + "Debug", + "Info", + "Warn", + "Error", + "Fatal", + "Off" +}; - case WLOG_DEBUG: - break; +void WLog_WriteA(wLog* log, DWORD logLevel, LPCSTR logMessage) +{ + char* logLevelStr; - case WLOG_INFO: - break; + if (logLevel > log->Level) + return; - case WLOG_WARN: - break; + logLevelStr = (char*) WLOG_LEVELS[logLevel]; - case WLOG_ERROR: - break; - - case WLOG_FATAL: - break; - } - - printf("[%s]: %s\n", loggerName, logMessage); + printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage); } -void WLog_LogVA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, va_list args) +void WLog_LogVA(wLog* log, DWORD logLevel, LPCSTR logMessage, va_list args) { if (!strchr(logMessage, '%')) { - WLog_WriteA(logLevel, loggerName, logMessage); + WLog_WriteA(log, logLevel, logMessage); } else { char formattedLogMessage[8192]; wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage, args); - WLog_WriteA(logLevel, loggerName, formattedLogMessage); + WLog_WriteA(log, logLevel, formattedLogMessage); } } -void WLog_LogA(int logLevel, LPCSTR loggerName, LPCSTR logMessage, ...) +void WLog_Print(wLog* log, DWORD logLevel, LPCSTR logMessage, ...) { va_list args; va_start(args, logMessage); - WLog_LogVA(logLevel, loggerName, logMessage, args); + WLog_LogVA(log, logLevel, logMessage, args); va_end(args); } -void WLog_TraceA(LPCSTR loggerName, LPCSTR logMessage, ...) +DWORD WLog_GetLogLevel(wLog* log) { - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_TRACE, loggerName, logMessage, args); - va_end(args); + return log->Level; } -void WLog_DebugA(LPCSTR loggerName, LPCSTR logMessage, ...) +void WLog_SetLogLevel(wLog* log, DWORD logLevel) { - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_DEBUG, loggerName, logMessage, args); - va_end(args); + if (logLevel > WLOG_OFF) + logLevel = WLOG_OFF; + + log->Level = logLevel; } -void WLog_InfoA(LPCSTR loggerName, LPCSTR logMessage, ...) +wLog* WLog_New(LPCSTR name) { - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_INFO, loggerName, logMessage, args); - va_end(args); + wLog* log; + + log = (wLog*) malloc(sizeof(wLog)); + + if (log) + { + ZeroMemory(log, sizeof(wLog)); + + log->Name = _strdup(name); + log->Level = WLOG_TRACE; + } + + return log; } -void WLog_WarnA(LPCSTR loggerName, LPCSTR logMessage, ...) +void WLog_Free(wLog* log) { - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_WARN, loggerName, logMessage, args); - va_end(args); -} - -void WLog_ErrorA(LPCSTR loggerName, LPCSTR logMessage, ...) -{ - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_ERROR, loggerName, logMessage, args); - va_end(args); -} - -void WLog_FatalA(LPCSTR loggerName, LPCSTR logMessage, ...) -{ - va_list args; - va_start(args, logMessage); - WLog_LogVA(WLOG_FATAL, loggerName, logMessage, args); - va_end(args); + if (log) + { + free(log->Name); + free(log); + } } From 36e7c3914a235da22d02330ef6c9ab406ef46289 Mon Sep 17 00:00:00 2001 From: Todd McKinney Date: Mon, 16 Sep 2013 09:50:32 -0500 Subject: [PATCH 139/202] Clean up unneded includes and fix logic for display output to include fitscreen text --- .../com/freerdp/freerdpcore/domain/BookmarkBase.java | 2 -- .../freerdpcore/presentation/BookmarkActivity.java | 11 +++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java index 87a65dd15..8db15b864 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java @@ -10,8 +10,6 @@ package com.freerdp.freerdpcore.domain; import com.freerdp.freerdpcore.application.GlobalApp; -import com.freerdp.freerdpcore.application.GlobalSettings; -import com.freerdp.freerdpcore.R; import android.content.SharedPreferences; import android.os.Parcel; diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java index 33e6a330d..ca5b8f4ac 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java @@ -343,10 +343,17 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref else if (key.equals("bookmark.resolution") || key.equals("bookmark.colors") || key.equals("bookmark.width") || key.equals("bookmark.height")) { String resolution = sharedPreferences.getString("bookmark.resolution", "800x600"); - if (resolution.equals("automatic")) + //compare english string from resolutions_values_array array, decode to localized + //text for display + if (resolution.equals("automatic")) { resolution = getResources().getString(R.string.resolution_automatic); - else if (resolution.equals("custom")) + } + if (resolution.equals("custom")) { resolution = getResources().getString(R.string.resolution_custom); + } + if (resolution.equals("fitscreen")) { + resolution = getResources().getString(R.string.resolution_fit); + } resolution += "@" + sharedPreferences.getInt("bookmark.colors", 16); findPreference("bookmark.screen").setSummary(resolution); } From 1b304321eff1e7d8b690e3e16fc418527b72b65b Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 16 Sep 2013 17:23:26 +0200 Subject: [PATCH 140/202] winpr/registry: Fixed double free fixes #1479 --- winpr/libwinpr/registry/registry_reg.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/winpr/libwinpr/registry/registry_reg.c b/winpr/libwinpr/registry/registry_reg.c index 559c4a904..ea9e0f9ca 100644 --- a/winpr/libwinpr/registry/registry_reg.c +++ b/winpr/libwinpr/registry/registry_reg.c @@ -111,18 +111,6 @@ static void reg_load_finish(Reg* reg) free(reg->buffer); reg->buffer = NULL; } - - if (reg->line) - { - free(reg->line); - reg->line = NULL; - } - - if (reg->next_line) - { - free(reg->next_line); - reg->next_line = NULL; - } } static RegVal* reg_load_value(Reg* reg, RegKey* key) From af1ea7573c109a6ac062c20621e150f3f9d15ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 12:05:08 -0400 Subject: [PATCH 141/202] libwinpr-utils: start implementing ConsoleAppender --- winpr/include/winpr/wlog.h | 83 ++++++++++-- winpr/libwinpr/utils/test/TestWLog.c | 7 + winpr/libwinpr/utils/wlog.c | 192 +++++++++++++++++++++++++-- 3 files changed, 265 insertions(+), 17 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 70da16f05..73f4a238d 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -23,26 +23,93 @@ #include #include -#define WLOG_TRACE 0 -#define WLOG_DEBUG 1 -#define WLOG_INFO 2 -#define WLOG_WARN 3 -#define WLOG_ERROR 4 -#define WLOG_FATAL 5 -#define WLOG_OFF 6 +typedef struct _wLog wLog; +typedef struct _wLogMessage wLogMessage; +typedef struct _wLogAppender wLogAppender; + +/** + * Log Levels + */ + +#define WLOG_TRACE 0 +#define WLOG_DEBUG 1 +#define WLOG_INFO 2 +#define WLOG_WARN 3 +#define WLOG_ERROR 4 +#define WLOG_FATAL 5 +#define WLOG_OFF 6 + +/** + * Log Message + */ + +#define WLOG_MESSAGE_STRING 0 + +struct _wLogMessage +{ + DWORD Type; + + LPSTR TextString; +}; + +/** + * Log Appenders + */ + +#define WLOG_APPENDER_CONSOLE 0 +#define WLOG_APPENDER_FILE 1 + +typedef int (*WLOG_APPENDER_WRITE_MESSAGE_FN)(wLog* log, wLogAppender* appender, DWORD logLevel, wLogMessage* logMessage); + +struct _wLogAppender +{ + DWORD Type; + WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; +}; + +#define WLOG_CONSOLE_STDOUT 1 +#define WLOG_CONSOLE_STDERR 2 + +struct _wLogConsoleAppender +{ + DWORD Type; + WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; + + int outputStream; +}; +typedef struct _wLogConsoleAppender wLogConsoleAppender; + +struct _wLogFileAppender +{ + DWORD Type; + WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; + + +}; +typedef struct _wLogFileAppender wLogFileAppender; + +/** + * Logger + */ struct _wLog { LPSTR Name; DWORD Level; + + wLogAppender* Appender; }; -typedef struct _wLog wLog; WINPR_API void WLog_Print(wLog* log, DWORD logLevel, LPCSTR logMessage, ...); WINPR_API DWORD WLog_GetLogLevel(wLog* log); WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel); +WINPR_API wLogAppender* WLog_GetLogAppender(wLog* log); +WINPR_API void WLog_SetLogAppenderType(wLog* log, DWORD logAppenderType); + +WINPR_API void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* consoleAppender, int outputStream); + WINPR_API wLog* WLog_New(LPCSTR name); WINPR_API void WLog_Free(wLog* log); diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c index 5ded9417f..b26001eed 100644 --- a/winpr/libwinpr/utils/test/TestWLog.c +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -6,10 +6,17 @@ int TestWLog(int argc, char* argv[]) { wLog* log; + wLogConsoleAppender* appender; log = WLog_New("TEST"); WLog_SetLogLevel(log, WLOG_INFO); + + WLog_SetLogAppenderType(log, WLOG_APPENDER_CONSOLE); + appender = (wLogConsoleAppender*) WLog_GetLogAppender(log); + + WLog_ConsoleAppender_SetOutputStream(log, appender, WLOG_CONSOLE_STDERR); + WLog_Print(log, WLOG_INFO, "this is a test"); WLog_Print(log, WLOG_WARN, "this is a %dnd %s", 2, "test"); WLog_Print(log, WLOG_ERROR, "this is an error"); diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c index 3b0650ff4..9a776ec3d 100644 --- a/winpr/libwinpr/utils/wlog.c +++ b/winpr/libwinpr/utils/wlog.c @@ -30,6 +30,16 @@ #include +/** + * References for general logging concepts: + * + * Short introduction to log4j: + * http://logging.apache.org/log4j/1.2/manual.html + * + * logging - Logging facility for Python: + * http://docs.python.org/2/library/logging.html + */ + #define WLOG_BUFFER_SIZE 8192 const char* WLOG_LEVELS[7] = @@ -43,29 +53,35 @@ const char* WLOG_LEVELS[7] = "Off" }; -void WLog_WriteA(wLog* log, DWORD logLevel, LPCSTR logMessage) +int WLog_Write(wLog* log, DWORD logLevel, wLogMessage* logMessage) { - char* logLevelStr; + if (!log->Appender) + return -1; - if (logLevel > log->Level) - return; + if (!log->Appender->WriteMessage) + return -1; - logLevelStr = (char*) WLOG_LEVELS[logLevel]; - - printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage); + return log->Appender->WriteMessage(log, log->Appender, logLevel, logMessage); } void WLog_LogVA(wLog* log, DWORD logLevel, LPCSTR logMessage, va_list args) { + wLogMessage message; + + message.Type = WLOG_MESSAGE_STRING; + if (!strchr(logMessage, '%')) { - WLog_WriteA(log, logLevel, logMessage); + message.TextString = (LPSTR) logMessage; + WLog_Write(log, logLevel, &message); } else { char formattedLogMessage[8192]; wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage, args); - WLog_WriteA(log, logLevel, formattedLogMessage); + + message.TextString = formattedLogMessage; + WLog_Write(log, logLevel, &message); } } @@ -90,6 +106,156 @@ void WLog_SetLogLevel(wLog* log, DWORD logLevel) log->Level = logLevel; } +wLogAppender* WLog_GetLogAppender(wLog* log) +{ + return log->Appender; +} + +/** + * Console Appender + */ + +void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* consoleAppender, int outputStream) +{ + if (!consoleAppender) + return; + + if (outputStream < 0) + outputStream = WLOG_CONSOLE_STDOUT; + + if (outputStream == WLOG_CONSOLE_STDOUT) + consoleAppender->outputStream = WLOG_CONSOLE_STDOUT; + else if (outputStream == WLOG_CONSOLE_STDERR) + consoleAppender->outputStream = WLOG_CONSOLE_STDERR; + else + consoleAppender->outputStream = WLOG_CONSOLE_STDOUT; +} + +int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, DWORD logLevel, wLogMessage* logMessage) +{ + char* logLevelStr; + + if (logLevel > log->Level) + return 0; + + logLevelStr = (char*) WLOG_LEVELS[logLevel]; + + if (appender->outputStream == WLOG_CONSOLE_STDERR) + fprintf(stderr, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + else + printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + + return 1; +} + +wLogConsoleAppender* WLog_ConsoleAppender_New(wLog* log) +{ + wLogConsoleAppender* ConsoleAppender; + + ConsoleAppender = (wLogConsoleAppender*) malloc(sizeof(wLogConsoleAppender)); + + if (ConsoleAppender) + { + ZeroMemory(ConsoleAppender, sizeof(wLogConsoleAppender)); + + ConsoleAppender->WriteMessage = (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_ConsoleAppender_WriteMessage; + + ConsoleAppender->outputStream = WLOG_CONSOLE_STDOUT; + } + + return ConsoleAppender; +} + +void WLog_ConsoleAppender_Free(wLog* log, wLogConsoleAppender* consoleAppender) +{ + if (consoleAppender) + { + free(consoleAppender); + } +} + +/** + * File Appender + */ + +int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, DWORD logLevel, wLogMessage* logMessage) +{ + char* logLevelStr; + + if (logLevel > log->Level) + return 0; + + logLevelStr = (char*) WLOG_LEVELS[logLevel]; + + printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + + return 1; +} + +wLogFileAppender* WLog_FileAppender_New(wLog* log) +{ + wLogFileAppender* FileAppender; + + FileAppender = (wLogFileAppender*) malloc(sizeof(wLogFileAppender)); + + if (FileAppender) + { + ZeroMemory(FileAppender, sizeof(wLogFileAppender)); + + FileAppender->WriteMessage = (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_FileAppender_WriteMessage; + } + + return FileAppender; +} + +void WLog_FileAppender_Free(wLog* log, wLogFileAppender* fileAppender) +{ + if (fileAppender) + { + free(fileAppender); + } +} + +wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType) +{ + if (logAppenderType == WLOG_APPENDER_CONSOLE) + { + return (wLogAppender*) WLog_ConsoleAppender_New(log); + } + else if (logAppenderType == WLOG_APPENDER_FILE) + { + return (wLogAppender*) WLog_FileAppender_New(log); + } + + return (wLogAppender*) WLog_ConsoleAppender_New(log); +} + +void WLog_Appender_Free(wLog* log, wLogAppender* appender) +{ + if (appender) + { + if (appender->Type == WLOG_APPENDER_CONSOLE) + { + WLog_ConsoleAppender_Free(log, (wLogConsoleAppender*) appender); + } + else if (appender->Type == WLOG_APPENDER_FILE) + { + WLog_FileAppender_Free(log, (wLogFileAppender*) appender); + } + } +} + +void WLog_SetLogAppenderType(wLog* log, DWORD logAppenderType) +{ + if (log->Appender) + { + WLog_Appender_Free(log, log->Appender); + log->Appender = NULL; + } + + log->Appender = WLog_Appender_New(log, logAppenderType); +} + wLog* WLog_New(LPCSTR name) { wLog* log; @@ -102,6 +268,8 @@ wLog* WLog_New(LPCSTR name) log->Name = _strdup(name); log->Level = WLOG_TRACE; + + WLog_SetLogAppenderType(log, WLOG_APPENDER_CONSOLE); } return log; @@ -111,6 +279,12 @@ void WLog_Free(wLog* log) { if (log) { + if (log->Appender) + { + WLog_Appender_Free(log, log->Appender); + log->Appender = NULL; + } + free(log->Name); free(log); } From a4c8d97b4caff4ef9d022207fa1881332a171e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 12:56:22 -0400 Subject: [PATCH 142/202] libwinpr-utils: start implementing FileAppender --- winpr/include/winpr/wlog.h | 29 +++++-- winpr/libwinpr/utils/test/TestWLog.c | 28 ++++++- winpr/libwinpr/utils/wlog.c | 117 ++++++++++++++++++++++----- 3 files changed, 144 insertions(+), 30 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 73f4a238d..27a1980d2 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -20,6 +20,8 @@ #ifndef WINPR_LOG_H #define WINPR_LOG_H +#include + #include #include @@ -59,12 +61,19 @@ struct _wLogMessage #define WLOG_APPENDER_CONSOLE 0 #define WLOG_APPENDER_FILE 1 +typedef int (*WLOG_APPENDER_OPEN_FN)(wLog* log, wLogAppender* appender); +typedef int (*WLOG_APPENDER_CLOSE_FN)(wLog* log, wLogAppender* appender); typedef int (*WLOG_APPENDER_WRITE_MESSAGE_FN)(wLog* log, wLogAppender* appender, DWORD logLevel, wLogMessage* logMessage); +#define WLOG_APPENDER_COMMON() \ + DWORD Type; \ + WLOG_APPENDER_OPEN_FN Open; \ + WLOG_APPENDER_CLOSE_FN Close; \ + WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage + struct _wLogAppender { - DWORD Type; - WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; + WLOG_APPENDER_COMMON(); }; #define WLOG_CONSOLE_STDOUT 1 @@ -72,8 +81,7 @@ struct _wLogAppender struct _wLogConsoleAppender { - DWORD Type; - WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; + WLOG_APPENDER_COMMON(); int outputStream; }; @@ -81,10 +89,10 @@ typedef struct _wLogConsoleAppender wLogConsoleAppender; struct _wLogFileAppender { - DWORD Type; - WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; - + WLOG_APPENDER_COMMON(); + char* FileName; + FILE* FileDescriptor; }; typedef struct _wLogFileAppender wLogFileAppender; @@ -108,7 +116,12 @@ WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel); WINPR_API wLogAppender* WLog_GetLogAppender(wLog* log); WINPR_API void WLog_SetLogAppenderType(wLog* log, DWORD logAppenderType); -WINPR_API void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* consoleAppender, int outputStream); +WINPR_API int WLog_OpenAppender(wLog* log); +WINPR_API int WLog_CloseAppender(wLog* log); + +WINPR_API void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* appender, int outputStream); + +WINPR_API void WLog_FileAppender_SetOutputFileName(wLog* log, wLogFileAppender* appender, const char* filename); WINPR_API wLog* WLog_New(LPCSTR name); WINPR_API void WLog_Free(wLog* log); diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c index b26001eed..7021e76af 100644 --- a/winpr/libwinpr/utils/test/TestWLog.c +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -6,22 +6,42 @@ int TestWLog(int argc, char* argv[]) { wLog* log; - wLogConsoleAppender* appender; + wLogAppender* appender; - log = WLog_New("TEST"); + log = WLog_New("CONSOLE_LOG_TEST"); WLog_SetLogLevel(log, WLOG_INFO); WLog_SetLogAppenderType(log, WLOG_APPENDER_CONSOLE); - appender = (wLogConsoleAppender*) WLog_GetLogAppender(log); + appender = WLog_GetLogAppender(log); - WLog_ConsoleAppender_SetOutputStream(log, appender, WLOG_CONSOLE_STDERR); + WLog_ConsoleAppender_SetOutputStream(log, (wLogConsoleAppender*) appender, WLOG_CONSOLE_STDERR); + WLog_OpenAppender(log); WLog_Print(log, WLOG_INFO, "this is a test"); WLog_Print(log, WLOG_WARN, "this is a %dnd %s", 2, "test"); WLog_Print(log, WLOG_ERROR, "this is an error"); WLog_Print(log, WLOG_TRACE, "this is a trace output"); + WLog_CloseAppender(log); + WLog_Free(log); + + log = WLog_New("FILE_LOG_TEST"); + + WLog_SetLogLevel(log, WLOG_WARN); + + WLog_SetLogAppenderType(log, WLOG_APPENDER_FILE); + appender = WLog_GetLogAppender(log); + + WLog_FileAppender_SetOutputFileName(log, (wLogFileAppender*) appender, "/tmp/wlog_test.log"); + WLog_OpenAppender(log); + + WLog_Print(log, WLOG_INFO, "this is a test"); + WLog_Print(log, WLOG_WARN, "this is a %dnd %s", 2, "test"); + WLog_Print(log, WLOG_ERROR, "this is an error"); + WLog_Print(log, WLOG_TRACE, "this is a trace output"); + + WLog_CloseAppender(log); WLog_Free(log); return 0; diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c index 9a776ec3d..6a738ee32 100644 --- a/winpr/libwinpr/utils/wlog.c +++ b/winpr/libwinpr/utils/wlog.c @@ -106,33 +106,39 @@ void WLog_SetLogLevel(wLog* log, DWORD logLevel) log->Level = logLevel; } -wLogAppender* WLog_GetLogAppender(wLog* log) -{ - return log->Appender; -} - /** * Console Appender */ -void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* consoleAppender, int outputStream) +void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppender* appender, int outputStream) { - if (!consoleAppender) + if (!appender) return; if (outputStream < 0) outputStream = WLOG_CONSOLE_STDOUT; if (outputStream == WLOG_CONSOLE_STDOUT) - consoleAppender->outputStream = WLOG_CONSOLE_STDOUT; + appender->outputStream = WLOG_CONSOLE_STDOUT; else if (outputStream == WLOG_CONSOLE_STDERR) - consoleAppender->outputStream = WLOG_CONSOLE_STDERR; + appender->outputStream = WLOG_CONSOLE_STDERR; else - consoleAppender->outputStream = WLOG_CONSOLE_STDOUT; + appender->outputStream = WLOG_CONSOLE_STDOUT; +} + +int WLog_ConsoleAppender_Open(wLog* log, wLogConsoleAppender* appender) +{ + return 0; +} + +int WLog_ConsoleAppender_Close(wLog* log, wLogConsoleAppender* appender) +{ + return 0; } int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, DWORD logLevel, wLogMessage* logMessage) { + FILE* fp; char* logLevelStr; if (logLevel > log->Level) @@ -140,10 +146,9 @@ int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, logLevelStr = (char*) WLOG_LEVELS[logLevel]; - if (appender->outputStream == WLOG_CONSOLE_STDERR) - fprintf(stderr, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); - else - printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout; + + fprintf(fp, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); return 1; } @@ -158,6 +163,8 @@ wLogConsoleAppender* WLog_ConsoleAppender_New(wLog* log) { ZeroMemory(ConsoleAppender, sizeof(wLogConsoleAppender)); + ConsoleAppender->Open = (WLOG_APPENDER_OPEN_FN) WLog_ConsoleAppender_Open; + ConsoleAppender->Close = (WLOG_APPENDER_OPEN_FN) WLog_ConsoleAppender_Close; ConsoleAppender->WriteMessage = (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_ConsoleAppender_WriteMessage; ConsoleAppender->outputStream = WLOG_CONSOLE_STDOUT; @@ -178,8 +185,45 @@ void WLog_ConsoleAppender_Free(wLog* log, wLogConsoleAppender* consoleAppender) * File Appender */ +void WLog_FileAppender_SetOutputFileName(wLog* log, wLogFileAppender* appender, const char* filename) +{ + if (!appender) + return; + + if (!filename) + return; + + appender->FileName = _strdup(filename); +} + +int WLog_FileAppender_Open(wLog* log, wLogFileAppender* appender) +{ + if (!appender->FileName) + return -1; + + appender->FileDescriptor = fopen(appender->FileName, "a+"); + + if (!appender->FileDescriptor) + return -1; + + return 0; +} + +int WLog_FileAppender_Close(wLog* log, wLogFileAppender* appender) +{ + if (!appender->FileDescriptor) + return 0; + + fclose(appender->FileDescriptor); + + appender->FileDescriptor = NULL; + + return 0; +} + int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, DWORD logLevel, wLogMessage* logMessage) { + FILE* fp; char* logLevelStr; if (logLevel > log->Level) @@ -187,7 +231,12 @@ int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, DWORD logLevelStr = (char*) WLOG_LEVELS[logLevel]; - printf("[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + fp = appender->FileDescriptor; + + if (!fp || (fp < 0)) + return -1; + + fprintf(fp, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); return 1; } @@ -202,17 +251,22 @@ wLogFileAppender* WLog_FileAppender_New(wLog* log) { ZeroMemory(FileAppender, sizeof(wLogFileAppender)); + FileAppender->Open = (WLOG_APPENDER_OPEN_FN) WLog_FileAppender_Open; + FileAppender->Close = (WLOG_APPENDER_OPEN_FN) WLog_FileAppender_Close; FileAppender->WriteMessage = (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_FileAppender_WriteMessage; } return FileAppender; } -void WLog_FileAppender_Free(wLog* log, wLogFileAppender* fileAppender) +void WLog_FileAppender_Free(wLog* log, wLogFileAppender* appender) { - if (fileAppender) + if (appender) { - free(fileAppender); + if (appender->FileName) + free(appender->FileName); + + free(appender); } } @@ -245,6 +299,11 @@ void WLog_Appender_Free(wLog* log, wLogAppender* appender) } } +wLogAppender* WLog_GetLogAppender(wLog* log) +{ + return log->Appender; +} + void WLog_SetLogAppenderType(wLog* log, DWORD logAppenderType) { if (log->Appender) @@ -256,6 +315,28 @@ void WLog_SetLogAppenderType(wLog* log, DWORD logAppenderType) log->Appender = WLog_Appender_New(log, logAppenderType); } +int WLog_OpenAppender(wLog* log) +{ + if (!log->Appender) + return -1; + + if (!log->Appender->Open) + return 0; + + return log->Appender->Open(log, log->Appender); +} + +int WLog_CloseAppender(wLog* log) +{ + if (!log->Appender) + return -1; + + if (!log->Appender->Close) + return 0; + + return log->Appender->Close(log, log->Appender); +} + wLog* WLog_New(LPCSTR name) { wLog* log; From 5386d5cd603c6d6010ec4ad2120801485f989b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 13:24:50 -0400 Subject: [PATCH 143/202] libwinpr-utils: make use of logMessage structure and macro for logging --- winpr/include/winpr/wlog.h | 18 +++++++++++++++++- winpr/libwinpr/utils/wlog.c | 28 ++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 27a1980d2..1fb91cfc6 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -51,7 +51,12 @@ struct _wLogMessage { DWORD Type; + LPSTR FormatString; LPSTR TextString; + + DWORD LineNumber; /* __LINE__ */ + LPCSTR FileName; /* __FILE__ */ + LPCSTR FunctionName; /* __FUNCTION__ */ }; /** @@ -108,7 +113,18 @@ struct _wLog wLogAppender* Appender; }; -WINPR_API void WLog_Print(wLog* log, DWORD logLevel, LPCSTR logMessage, ...); +WINPR_API void WLog_PrintMessage(wLog* log, DWORD logLevel, wLogMessage* logMessage, ...); + +#define WLog_Print(_log, _log_level, _fmt, ...) \ + if (_log_level <= _log->Level) { \ + wLogMessage _log_message; \ + _log_message.Type = WLOG_MESSAGE_STRING; \ + _log_message.FormatString = _fmt; \ + _log_message.LineNumber = __LINE__; \ + _log_message.FileName = __FILE__; \ + _log_message.FunctionName = __FUNCTION__; \ + WLog_PrintMessage(_log, _log_level, &(_log_message), ## __VA_ARGS__ ); \ + } WINPR_API DWORD WLog_GetLogLevel(wLog* log); WINPR_API void WLog_SetLogLevel(wLog* log, DWORD logLevel); diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c index 6a738ee32..8ceb110f7 100644 --- a/winpr/libwinpr/utils/wlog.c +++ b/winpr/libwinpr/utils/wlog.c @@ -64,28 +64,24 @@ int WLog_Write(wLog* log, DWORD logLevel, wLogMessage* logMessage) return log->Appender->WriteMessage(log, log->Appender, logLevel, logMessage); } -void WLog_LogVA(wLog* log, DWORD logLevel, LPCSTR logMessage, va_list args) +void WLog_LogVA(wLog* log, DWORD logLevel, wLogMessage* logMessage, va_list args) { - wLogMessage message; - - message.Type = WLOG_MESSAGE_STRING; - - if (!strchr(logMessage, '%')) + if (!strchr(logMessage->FormatString, '%')) { - message.TextString = (LPSTR) logMessage; - WLog_Write(log, logLevel, &message); + logMessage->TextString = (LPSTR) logMessage->FormatString; + WLog_Write(log, logLevel, logMessage); } else { char formattedLogMessage[8192]; - wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage, args); + wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage->FormatString, args); - message.TextString = formattedLogMessage; - WLog_Write(log, logLevel, &message); + logMessage->TextString = formattedLogMessage; + WLog_Write(log, logLevel, logMessage); } } -void WLog_Print(wLog* log, DWORD logLevel, LPCSTR logMessage, ...) +void WLog_PrintMessage(wLog* log, DWORD logLevel, wLogMessage* logMessage, ...) { va_list args; va_start(args, logMessage); @@ -148,7 +144,9 @@ int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout; - fprintf(fp, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + fprintf(fp, "[%s] [%s] (%s,%s@%d): %s\n", logLevelStr, log->Name, + logMessage->FunctionName, logMessage->FileName, + logMessage->LineNumber, logMessage->TextString); return 1; } @@ -236,7 +234,9 @@ int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, DWORD if (!fp || (fp < 0)) return -1; - fprintf(fp, "[%s] [%s]: %s\n", logLevelStr, log->Name, logMessage->TextString); + fprintf(fp, "[%s] [%s] (%s,%s@%d): %s\n", logLevelStr, log->Name, + logMessage->FunctionName, logMessage->FileName, + logMessage->LineNumber, logMessage->TextString); return 1; } From 22ce1712611003d0256d3ff3d469d64c56c4bffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 16:30:49 -0400 Subject: [PATCH 144/202] libwinpr-utils: added custom prefix formatter in logger --- winpr/include/winpr/wlog.h | 27 ++- winpr/libwinpr/utils/test/TestWLog.c | 7 + winpr/libwinpr/utils/wlog.c | 329 +++++++++++++++++++++++---- 3 files changed, 317 insertions(+), 46 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 1fb91cfc6..394e1a9c6 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -27,6 +27,7 @@ typedef struct _wLog wLog; typedef struct _wLogMessage wLogMessage; +typedef struct _wLogLayout wLogLayout; typedef struct _wLogAppender wLogAppender; /** @@ -51,6 +52,10 @@ struct _wLogMessage { DWORD Type; + DWORD Level; + + LPSTR PrefixString; + LPSTR FormatString; LPSTR TextString; @@ -59,6 +64,17 @@ struct _wLogMessage LPCSTR FunctionName; /* __FUNCTION__ */ }; +/** + * Log Layout + */ + +struct _wLogLayout +{ + DWORD Type; + + LPSTR FormatString; +}; + /** * Log Appenders */ @@ -68,10 +84,11 @@ struct _wLogMessage typedef int (*WLOG_APPENDER_OPEN_FN)(wLog* log, wLogAppender* appender); typedef int (*WLOG_APPENDER_CLOSE_FN)(wLog* log, wLogAppender* appender); -typedef int (*WLOG_APPENDER_WRITE_MESSAGE_FN)(wLog* log, wLogAppender* appender, DWORD logLevel, wLogMessage* logMessage); +typedef int (*WLOG_APPENDER_WRITE_MESSAGE_FN)(wLog* log, wLogAppender* appender, wLogMessage* message); #define WLOG_APPENDER_COMMON() \ DWORD Type; \ + wLogLayout* Layout; \ WLOG_APPENDER_OPEN_FN Open; \ WLOG_APPENDER_CLOSE_FN Close; \ WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage @@ -113,17 +130,18 @@ struct _wLog wLogAppender* Appender; }; -WINPR_API void WLog_PrintMessage(wLog* log, DWORD logLevel, wLogMessage* logMessage, ...); +WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...); #define WLog_Print(_log, _log_level, _fmt, ...) \ if (_log_level <= _log->Level) { \ wLogMessage _log_message; \ _log_message.Type = WLOG_MESSAGE_STRING; \ + _log_message.Level = _log_level; \ _log_message.FormatString = _fmt; \ _log_message.LineNumber = __LINE__; \ _log_message.FileName = __FILE__; \ _log_message.FunctionName = __FUNCTION__; \ - WLog_PrintMessage(_log, _log_level, &(_log_message), ## __VA_ARGS__ ); \ + WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \ } WINPR_API DWORD WLog_GetLogLevel(wLog* log); @@ -139,6 +157,9 @@ WINPR_API void WLog_ConsoleAppender_SetOutputStream(wLog* log, wLogConsoleAppend WINPR_API void WLog_FileAppender_SetOutputFileName(wLog* log, wLogFileAppender* appender, const char* filename); +WINPR_API wLogLayout* WLog_GetLogLayout(wLog* log); +WINPR_API void WLog_Layout_SetPrefixFormat(wLog* log, wLogLayout* layout, const char* format); + WINPR_API wLog* WLog_New(LPCSTR name); WINPR_API void WLog_Free(wLog* log); diff --git a/winpr/libwinpr/utils/test/TestWLog.c b/winpr/libwinpr/utils/test/TestWLog.c index 7021e76af..7f430517c 100644 --- a/winpr/libwinpr/utils/test/TestWLog.c +++ b/winpr/libwinpr/utils/test/TestWLog.c @@ -6,6 +6,7 @@ int TestWLog(int argc, char* argv[]) { wLog* log; + wLogLayout* layout; wLogAppender* appender; log = WLog_New("CONSOLE_LOG_TEST"); @@ -15,6 +16,9 @@ int TestWLog(int argc, char* argv[]) WLog_SetLogAppenderType(log, WLOG_APPENDER_CONSOLE); appender = WLog_GetLogAppender(log); + layout = WLog_GetLogLayout(log); + WLog_Layout_SetPrefixFormat(log, layout, "[%lv:%mn] [%fl|%fn|%ln] - "); + WLog_ConsoleAppender_SetOutputStream(log, (wLogConsoleAppender*) appender, WLOG_CONSOLE_STDERR); WLog_OpenAppender(log); @@ -33,6 +37,9 @@ int TestWLog(int argc, char* argv[]) WLog_SetLogAppenderType(log, WLOG_APPENDER_FILE); appender = WLog_GetLogAppender(log); + layout = WLog_GetLogLayout(log); + WLog_Layout_SetPrefixFormat(log, layout, "[%lv:%mn] [%fl|%fn|%ln] - "); + WLog_FileAppender_SetOutputFileName(log, (wLogFileAppender*) appender, "/tmp/wlog_test.log"); WLog_OpenAppender(log); diff --git a/winpr/libwinpr/utils/wlog.c b/winpr/libwinpr/utils/wlog.c index 8ceb110f7..aced199d8 100644 --- a/winpr/libwinpr/utils/wlog.c +++ b/winpr/libwinpr/utils/wlog.c @@ -40,20 +40,21 @@ * http://docs.python.org/2/library/logging.html */ -#define WLOG_BUFFER_SIZE 8192 +#define WLOG_MAX_PREFIX_SIZE 512 +#define WLOG_MAX_STRING_SIZE 8192 const char* WLOG_LEVELS[7] = { - "Trace", - "Debug", - "Info", - "Warn", - "Error", - "Fatal", - "Off" + "TRACE", + "DEBUG", + "INFO", + "WARN", + "ERROR", + "FATAL", + "OFF" }; -int WLog_Write(wLog* log, DWORD logLevel, wLogMessage* logMessage) +int WLog_Write(wLog* log, wLogMessage* message) { if (!log->Appender) return -1; @@ -61,31 +62,31 @@ int WLog_Write(wLog* log, DWORD logLevel, wLogMessage* logMessage) if (!log->Appender->WriteMessage) return -1; - return log->Appender->WriteMessage(log, log->Appender, logLevel, logMessage); + return log->Appender->WriteMessage(log, log->Appender, message); } -void WLog_LogVA(wLog* log, DWORD logLevel, wLogMessage* logMessage, va_list args) +void WLog_PrintMessageVA(wLog* log, wLogMessage* message, va_list args) { - if (!strchr(logMessage->FormatString, '%')) + if (!strchr(message->FormatString, '%')) { - logMessage->TextString = (LPSTR) logMessage->FormatString; - WLog_Write(log, logLevel, logMessage); + message->TextString = (LPSTR) message->FormatString; + WLog_Write(log, message); } else { char formattedLogMessage[8192]; - wvsnprintfx(formattedLogMessage, WLOG_BUFFER_SIZE - 1, logMessage->FormatString, args); + wvsnprintfx(formattedLogMessage, WLOG_MAX_STRING_SIZE - 1, message->FormatString, args); - logMessage->TextString = formattedLogMessage; - WLog_Write(log, logLevel, logMessage); + message->TextString = formattedLogMessage; + WLog_Write(log, message); } } -void WLog_PrintMessage(wLog* log, DWORD logLevel, wLogMessage* logMessage, ...) +void WLog_PrintMessage(wLog* log, wLogMessage* message, ...) { va_list args; - va_start(args, logMessage); - WLog_LogVA(log, logLevel, logMessage, args); + va_start(args, message); + WLog_PrintMessageVA(log, message, args); va_end(args); } @@ -102,6 +103,237 @@ void WLog_SetLogLevel(wLog* log, DWORD logLevel) log->Level = logLevel; } +/** + * Log Layout + */ + +void WLog_PrintMessagePrefixVA(wLog* log, wLogMessage* message, const char* format, va_list args) +{ + if (!strchr(format, '%')) + { + message->PrefixString = (LPSTR) format; + } + else + { + wvsnprintfx(message->PrefixString, WLOG_MAX_PREFIX_SIZE - 1, format, args); + } +} + +void WLog_PrintMessagePrefix(wLog* log, wLogMessage* message, const char* format, ...) +{ + va_list args; + va_start(args, format); + WLog_PrintMessagePrefixVA(log, message, format, args); + va_end(args); +} + +void WLog_Layout_GetMessagePrefix(wLog* log, wLogLayout* layout, wLogMessage* message) +{ + char* p; + int index; + int argc = 0; + void* args[32]; + char format[128]; + + index = 0; + p = (char*) layout->FormatString; + + while (*p) + { + if (*p == '%') + { + p++; + + if (*p) + { + if ((*p == 'l') && (*(p + 1) == 'v')) /* log level */ + { + args[argc++] = (void*) WLOG_LEVELS[message->Level]; + format[index++] = '%'; + format[index++] = 's'; + p++; + } + else if ((*p == 'm') && (*(p + 1) == 'n')) /* module name */ + { + args[argc++] = (void*) log->Name; + format[index++] = '%'; + format[index++] = 's'; + p++; + } + else if ((*p == 'f') && (*(p + 1) == 'l')) /* file */ + { + char* file; + + file = strrchr(message->FileName, '/'); + + if (!file) + file = strrchr(message->FileName, '\\'); + + if (file) + file++; + else + file = (char*) message->FileName; + + args[argc++] = (void*) file; + format[index++] = '%'; + format[index++] = 's'; + p++; + } + else if ((*p == 'f') && (*(p + 1) == 'n')) /* function */ + { + args[argc++] = (void*) message->FunctionName; + format[index++] = '%'; + format[index++] = 's'; + p++; + } + else if ((*p == 'l') && (*(p + 1) == 'n')) /* line number */ + { + args[argc++] = (void*) message->LineNumber; + format[index++] = '%'; + format[index++] = 'd'; + p++; + } + } + } + else + { + format[index++] = *p; + } + + p++; + } + + format[index++] = '\0'; + + switch (argc) + { + case 0: + WLog_PrintMessagePrefix(log, message, format); + break; + + case 1: + WLog_PrintMessagePrefix(log, message, format, args[0]); + break; + + case 2: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1]); + break; + + case 3: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2]); + break; + + case 4: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3]); + break; + + case 5: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4]); + break; + + case 6: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5]); + break; + + case 7: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6]); + break; + + case 8: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7]); + break; + + case 9: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8]); + break; + + case 10: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9]); + break; + + case 11: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10]); + break; + + case 12: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11]); + break; + + case 13: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12]); + break; + + case 14: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13]); + break; + + case 15: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13], args[14]); + break; + + case 16: + WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13], args[14], args[15]); + break; + } +} + +wLogLayout* WLog_GetLogLayout(wLog* log) +{ + return log->Appender->Layout; +} + +void WLog_Layout_SetPrefixFormat(wLog* log, wLogLayout* layout, const char* format) +{ + if (layout->FormatString) + free(layout->FormatString); + + layout->FormatString = _strdup(format); +} + +wLogLayout* WLog_Layout_New(wLog* log) +{ + wLogLayout* layout; + + layout = (wLogLayout*) malloc(sizeof(wLogLayout)); + + if (layout) + { + ZeroMemory(layout, sizeof(wLogLayout)); + + layout->FormatString = _strdup("[%lv][%mn] - "); + } + + return layout; +} + +void WLog_Layout_Free(wLog* log, wLogLayout* layout) +{ + if (layout) + { + if (layout->FormatString) + free(layout->FormatString); + + free(layout); + } +} + /** * Console Appender */ @@ -132,21 +364,20 @@ int WLog_ConsoleAppender_Close(wLog* log, wLogConsoleAppender* appender) return 0; } -int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, DWORD logLevel, wLogMessage* logMessage) +int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, wLogMessage* message) { FILE* fp; - char* logLevelStr; + char prefix[WLOG_MAX_PREFIX_SIZE]; - if (logLevel > log->Level) + if (message->Level > log->Level) return 0; - logLevelStr = (char*) WLOG_LEVELS[logLevel]; - fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout; - fprintf(fp, "[%s] [%s] (%s,%s@%d): %s\n", logLevelStr, log->Name, - logMessage->FunctionName, logMessage->FileName, - logMessage->LineNumber, logMessage->TextString); + message->PrefixString = prefix; + WLog_Layout_GetMessagePrefix(log, appender->Layout, message); + + fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); return 1; } @@ -171,11 +402,11 @@ wLogConsoleAppender* WLog_ConsoleAppender_New(wLog* log) return ConsoleAppender; } -void WLog_ConsoleAppender_Free(wLog* log, wLogConsoleAppender* consoleAppender) +void WLog_ConsoleAppender_Free(wLog* log, wLogConsoleAppender* appender) { - if (consoleAppender) + if (appender) { - free(consoleAppender); + free(appender); } } @@ -219,24 +450,23 @@ int WLog_FileAppender_Close(wLog* log, wLogFileAppender* appender) return 0; } -int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, DWORD logLevel, wLogMessage* logMessage) +int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, wLogMessage* message) { FILE* fp; - char* logLevelStr; + char prefix[WLOG_MAX_PREFIX_SIZE]; - if (logLevel > log->Level) + if (message->Level > log->Level) return 0; - logLevelStr = (char*) WLOG_LEVELS[logLevel]; - fp = appender->FileDescriptor; - if (!fp || (fp < 0)) + if (!fp) return -1; - fprintf(fp, "[%s] [%s] (%s,%s@%d): %s\n", logLevelStr, log->Name, - logMessage->FunctionName, logMessage->FileName, - logMessage->LineNumber, logMessage->TextString); + message->PrefixString = prefix; + WLog_Layout_GetMessagePrefix(log, appender->Layout, message); + + fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); return 1; } @@ -272,22 +502,35 @@ void WLog_FileAppender_Free(wLog* log, wLogFileAppender* appender) wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType) { + wLogAppender* appender = NULL; + if (logAppenderType == WLOG_APPENDER_CONSOLE) { - return (wLogAppender*) WLog_ConsoleAppender_New(log); + appender = (wLogAppender*) WLog_ConsoleAppender_New(log); } else if (logAppenderType == WLOG_APPENDER_FILE) { - return (wLogAppender*) WLog_FileAppender_New(log); + appender = (wLogAppender*) WLog_FileAppender_New(log); } - return (wLogAppender*) WLog_ConsoleAppender_New(log); + if (!appender) + appender = (wLogAppender*) WLog_ConsoleAppender_New(log); + + appender->Layout = WLog_Layout_New(log); + + return appender; } void WLog_Appender_Free(wLog* log, wLogAppender* appender) { if (appender) { + if (appender->Layout) + { + WLog_Layout_Free(log, appender->Layout); + appender->Layout = NULL; + } + if (appender->Type == WLOG_APPENDER_CONSOLE) { WLog_ConsoleAppender_Free(log, (wLogConsoleAppender*) appender); From 7b2a372c763363194add161bafe23309c8096a4f Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 16 Sep 2013 22:48:08 +0200 Subject: [PATCH 145/202] drdynvc: fixed masked used in close request --- channels/drdynvc/client/drdynvc_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 05600014a..17492542b 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -293,7 +293,7 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC dvcman_close_channel(drdynvc->channel_mgr, ChannelId); data_out = Stream_New(NULL, 4); - value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x02); + value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); From 8a6b545a3624439b0370c006e4fde545b5c940b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 17:43:24 -0400 Subject: [PATCH 146/202] libwinpr-print: add missing include headers --- winpr/include/winpr/print.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winpr/include/winpr/print.h b/winpr/include/winpr/print.h index 5838fba76..b85f176f9 100644 --- a/winpr/include/winpr/print.h +++ b/winpr/include/winpr/print.h @@ -21,6 +21,8 @@ #define WINPR_UTILS_PRINT_H #include +#include +#include #include #include From 8f1aceac6a5ca7f80915fcab6afbf7fb660d5642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 17:49:16 -0400 Subject: [PATCH 147/202] libwinpr-nt: add missing link dependency --- winpr/libwinpr/nt/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/winpr/libwinpr/nt/CMakeLists.txt b/winpr/libwinpr/nt/CMakeLists.txt index b7455246e..451a7696b 100644 --- a/winpr/libwinpr/nt/CMakeLists.txt +++ b/winpr/libwinpr/nt/CMakeLists.txt @@ -39,6 +39,11 @@ if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rt) endif() +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-crt) + if(MONOLITHIC_BUILD) set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) else() From c0ba0fb3375c69640081b8e51ac92d6a1a60841b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 16 Sep 2013 17:59:29 -0400 Subject: [PATCH 148/202] libwinpr-utils: fix BufferPool test --- winpr/libwinpr/utils/test/TestBufferPool.c | 28 ++++------------------ 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/winpr/libwinpr/utils/test/TestBufferPool.c b/winpr/libwinpr/utils/test/TestBufferPool.c index 710bc61dd..7e6f0b97a 100644 --- a/winpr/libwinpr/utils/test/TestBufferPool.c +++ b/winpr/libwinpr/utils/test/TestBufferPool.c @@ -5,28 +5,18 @@ int TestBufferPool(int argc, char* argv[]) { - int PoolSize; + DWORD PoolSize; int BufferSize; - int DefaultSize; wBufferPool* pool; BYTE* Buffers[10]; + DWORD DefaultSize = 1234; - DefaultSize = 1234; + pool = BufferPool_New(TRUE, -1, 16); - pool = BufferPool_New(TRUE, DefaultSize, 16); - - Buffers[0] = BufferPool_Take(pool, -1); - Buffers[1] = BufferPool_Take(pool, 0); + Buffers[0] = BufferPool_Take(pool, DefaultSize); + Buffers[1] = BufferPool_Take(pool, DefaultSize); Buffers[2] = BufferPool_Take(pool, 2048); - PoolSize = BufferPool_GetPoolSize(pool); - - if (PoolSize != 3) - { - printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 3); - return -1; - } - BufferSize = BufferPool_GetBufferSize(pool, Buffers[0]); if (BufferSize != DefaultSize) @@ -63,14 +53,6 @@ int TestBufferPool(int argc, char* argv[]) BufferPool_Clear(pool); - PoolSize = BufferPool_GetPoolSize(pool); - - if (PoolSize != 0) - { - printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 0); - return -1; - } - BufferPool_Free(pool); return 0; From 31bbd368fecb57940648addcedf44f8f21b8b429 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 15:57:48 +0200 Subject: [PATCH 149/202] Added configuration options for android SDK Now activating JAVA_DEBUG only for CMake Debug configuration by default. --- cmake/ConfigOptionsAndroid.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/ConfigOptionsAndroid.cmake b/cmake/ConfigOptionsAndroid.cmake index 535092f73..a2f3e48c0 100644 --- a/cmake/ConfigOptionsAndroid.cmake +++ b/cmake/ConfigOptionsAndroid.cmake @@ -15,6 +15,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(JAVA_DEBUG_DEFAULT "off") +if("${CMAKE_BUILD_TYPE STREQUAL "Debug") + set(JAVA_DEBUG_DEFAULT "on") +endif() + option(WITH_DEBUG_ANDROID_JNI "Enable debug output for android jni bindings" ${DEFAULT_DEBUG_OPTION}) option(ANDROID_BUILD_JAVA "Automatically android java code - build type depends on CMAKE_BUILD_TYPE" ON) -option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ON) +option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ${JAVA_DEBUG_DEFAULT}) + +set(ANDROID_APP_TARGET_SDK 11 CACHE STRING "Application target android SDK") +set(ANDROID_APP_MIN_SDK 8 CACHE STRING "Application minimum android SDK requirement") +set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK") + From 64d4dda20b41ed03069d2c2e64e287e924009a2e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 15:58:32 +0200 Subject: [PATCH 150/202] Added documentation for android SDK variables. --- docs/README.android | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/README.android b/docs/README.android index e83af9107..08920db5b 100644 --- a/docs/README.android +++ b/docs/README.android @@ -156,3 +156,10 @@ Java classes: After that you need to implement the functionality in client/Android/jni/android_freerdp.c and add the call to client/Android/jni/generated/android_freerdp_jni.c. After that FreeRDP and the Android package need to be rebuilt to include the latest libfreerdp-android in the package. + +Android CMake related Variables +------------------------------- + +ANDROID_APP_TARGET_SDK ... specifies the desired android target SDK, currently 11 +ANDROID_APP_MIN_SDK ... specifies the minimum android SDK version supported, currently 8 +ANDROID_APP_GOOGLE_TARGET_SDK ... specifies the minimum google SDK requirement, currently 16 From b58942b0ccbca617d22f158d6c38ebe81a770cf6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 16:07:52 +0200 Subject: [PATCH 151/202] Fixed out of source build. --- .../FreeRDPCore/AndroidManifest.xml.cmake | 4 +- client/Android/FreeRDPCore/CMakeLists.txt | 23 +++-- client/Android/FreeRDPCore/ant.properties | 16 ---- client/Android/FreeRDPCore/build.xml | 92 ------------------- client/Android/FreeRDPCore/jni/CMakeLists.txt | 3 +- ...ct.properties => project.properties.cmake} | 2 +- 6 files changed, 22 insertions(+), 118 deletions(-) delete mode 100644 client/Android/FreeRDPCore/ant.properties delete mode 100644 client/Android/FreeRDPCore/build.xml rename client/Android/FreeRDPCore/{project.properties => project.properties.cmake} (93%) diff --git a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake index 161f5c061..f21e53c74 100644 --- a/client/Android/FreeRDPCore/AndroidManifest.xml.cmake +++ b/client/Android/FreeRDPCore/AndroidManifest.xml.cmake @@ -3,10 +3,10 @@ - + diff --git a/client/Android/FreeRDPCore/CMakeLists.txt b/client/Android/FreeRDPCore/CMakeLists.txt index 005e90d45..6f256af64 100644 --- a/client/Android/FreeRDPCore/CMakeLists.txt +++ b/client/Android/FreeRDPCore/CMakeLists.txt @@ -16,28 +16,39 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(ANDROID_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(ANDROID_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(ANDROID_PACKAGE_NAME "aFreeRDPCore") -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake + ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build.xml.cmake + ${CMAKE_CURRENT_BINARY_DIR}/build.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/project.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/project.properties @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ant.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/ant.properties @ONLY) + +file(COPY res DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) if (ANDROID_SDK) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local.properties.cmake ${CMAKE_CURRENT_SOURCE_DIR}/local.properties @ONLY) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/local.properties @ONLY) endif() add_subdirectory(jni) if(ANDROID_BUILD_JAVA) - set(ANDROIDLIB "${ANDROID_SOURCE_DIR}/bin/classes.jar") + set(ANDROIDLIB "${ANDROID_BINARY_DIR}/bin/classes.jar") # command to create the android package add_custom_command( OUTPUT "${ANDROIDLIB}" COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} - WORKING_DIRECTORY "${ANDROID_SOURCE_DIR}" + WORKING_DIRECTORY "${ANDROID_BINARY_DIR}" MAIN_DEPENDENCY AndroidManifest.xml - DEPENDS freerdp-android local.properties + DEPENDS freerdp-android + ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-lib ALL SOURCES "${ANDROIDLIB}") SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin") diff --git a/client/Android/FreeRDPCore/ant.properties b/client/Android/FreeRDPCore/ant.properties deleted file mode 100644 index 73031c7a7..000000000 --- a/client/Android/FreeRDPCore/ant.properties +++ /dev/null @@ -1,16 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# -# This file must be checked into Version Control Systems, as it is -# integral to the build system of your project. - -# This file is only used by the Ant script. - -# You can use this to override default values such as -# 'source.dir' for the location of your java source folder and -# 'out.dir' for the location of your output folder. - -# You can also use it define how the release builds are signed by declaring -# the following properties: -# 'key.store' for the location of your keystore and -# 'key.alias' for the name of the key to use. -# The password will be asked during the build when you use the 'release' target. diff --git a/client/Android/FreeRDPCore/build.xml b/client/Android/FreeRDPCore/build.xml deleted file mode 100644 index f07d7de42..000000000 --- a/client/Android/FreeRDPCore/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/Android/FreeRDPCore/jni/CMakeLists.txt b/client/Android/FreeRDPCore/jni/CMakeLists.txt index 5aec24ef1..05e6e1ff5 100644 --- a/client/Android/FreeRDPCore/jni/CMakeLists.txt +++ b/client/Android/FreeRDPCore/jni/CMakeLists.txt @@ -68,6 +68,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} jnigraphics) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ANDROID_SOURCE_DIR}/libs/${ANDROID_ABI}") +set_target_properties(${MODULE_NAME} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ANDROID_BINARY_DIR}/libs/${ANDROID_ABI}") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Android") diff --git a/client/Android/FreeRDPCore/project.properties b/client/Android/FreeRDPCore/project.properties.cmake similarity index 93% rename from client/Android/FreeRDPCore/project.properties rename to client/Android/FreeRDPCore/project.properties.cmake index b4af3b428..72b842609 100644 --- a/client/Android/FreeRDPCore/project.properties +++ b/client/Android/FreeRDPCore/project.properties.cmake @@ -11,5 +11,5 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-11 +target=android-@ANDROID_APP_TARGET_SDK@ android.library=true From ef3f534825c82d116aa75e705670517a19d67b5b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 16:09:04 +0200 Subject: [PATCH 152/202] Fixed out of source build. --- .../Android/FreeRDPCore/ant.properties.cmake | 20 ++++ client/Android/FreeRDPCore/build.xml.cmake | 92 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 client/Android/FreeRDPCore/ant.properties.cmake create mode 100644 client/Android/FreeRDPCore/build.xml.cmake diff --git a/client/Android/FreeRDPCore/ant.properties.cmake b/client/Android/FreeRDPCore/ant.properties.cmake new file mode 100644 index 000000000..13e49ee77 --- /dev/null +++ b/client/Android/FreeRDPCore/ant.properties.cmake @@ -0,0 +1,20 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. +build.dir=@CMAKE_CURRENT_BINARY_DIR@ +source.dir=@CMAKE_CURRENT_SOURCE_DIR@/src +out.dir=@CMAKE_CURRENT_BINARY_DIR@/bin + diff --git a/client/Android/FreeRDPCore/build.xml.cmake b/client/Android/FreeRDPCore/build.xml.cmake new file mode 100644 index 000000000..f07d7de42 --- /dev/null +++ b/client/Android/FreeRDPCore/build.xml.cmake @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d8db198a510d52f1fe7a6db60a26c80b150ca1af Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 16:09:31 +0200 Subject: [PATCH 153/202] Fixed out of source build. --- client/Android/aFreeRDP/CMakeLists.txt | 28 +++++++++++++------ client/Android/aFreeRDP/ant.properties.cmake | 20 +++++++++++++ .../aFreeRDP/{build.xml => build.xml.cmake} | 0 ...ct.properties => project.properties.cmake} | 2 +- 4 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 client/Android/aFreeRDP/ant.properties.cmake rename client/Android/aFreeRDP/{build.xml => build.xml.cmake} (100%) rename client/Android/aFreeRDP/{project.properties => project.properties.cmake} (91%) diff --git a/client/Android/aFreeRDP/CMakeLists.txt b/client/Android/aFreeRDP/CMakeLists.txt index d17533b75..f4261b2ad 100644 --- a/client/Android/aFreeRDP/CMakeLists.txt +++ b/client/Android/aFreeRDP/CMakeLists.txt @@ -16,29 +16,41 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(ANDROID_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(ANDROID_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(ANDROID_PACKAGE_NAME "aFreeRDP") -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake + ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build.xml.cmake + ${CMAKE_CURRENT_BINARY_DIR}/build.xml @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/project.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/project.properties @ONLY) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ant.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/ant.properties @ONLY) + +file(COPY res DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) if (ANDROID_SDK) - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local.properties.cmake ${CMAKE_CURRENT_SOURCE_DIR}/local.properties @ONLY) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local.properties.cmake + ${CMAKE_CURRENT_BINARY_DIR}/local.properties @ONLY) endif() if(ANDROID_BUILD_JAVA) - if(ANDROID_BUILD_JAVA_DEBUG) - set(APK "${ANDROID_SOURCE_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") + if(NOT ANDROID_BUILD_JAVA_DEBUG) + set(APK "${ANDROID_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-release-unsigned.apk") else() - set(APK "${ANDROID_SOURCE_DIR}/bin/${ANDROID_PACKAGE_NAME}-debug.apk") + set(APK "${ANDROID_BINARY_DIR}/bin/${ANDROID_PACKAGE_NAME}-debug.apk") endif() # command to create the android package add_custom_command( OUTPUT "${APK}" COMMAND ${ANT_COMMAND} ${ANDROID_BUILD_TYPE} - WORKING_DIRECTORY "${ANDROID_SOURCE_DIR}" + WORKING_DIRECTORY "${ANDROID_BINARY_DIR}" MAIN_DEPENDENCY AndroidManifest.xml - DEPENDS freerdp-android local.properties #android-lib + DEPENDS freerdp-android + ${CMAKE_CURRENT_BINARY_DIR}/local.properties ) add_custom_target(android-package ALL SOURCES "${APK}") SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gen;bin") diff --git a/client/Android/aFreeRDP/ant.properties.cmake b/client/Android/aFreeRDP/ant.properties.cmake new file mode 100644 index 000000000..13e49ee77 --- /dev/null +++ b/client/Android/aFreeRDP/ant.properties.cmake @@ -0,0 +1,20 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. +build.dir=@CMAKE_CURRENT_BINARY_DIR@ +source.dir=@CMAKE_CURRENT_SOURCE_DIR@/src +out.dir=@CMAKE_CURRENT_BINARY_DIR@/bin + diff --git a/client/Android/aFreeRDP/build.xml b/client/Android/aFreeRDP/build.xml.cmake similarity index 100% rename from client/Android/aFreeRDP/build.xml rename to client/Android/aFreeRDP/build.xml.cmake diff --git a/client/Android/aFreeRDP/project.properties b/client/Android/aFreeRDP/project.properties.cmake similarity index 91% rename from client/Android/aFreeRDP/project.properties rename to client/Android/aFreeRDP/project.properties.cmake index 4507b1846..7d04de0f2 100644 --- a/client/Android/aFreeRDP/project.properties +++ b/client/Android/aFreeRDP/project.properties.cmake @@ -8,6 +8,6 @@ # project structure. # Project target. -target=android-11 +target=android-@ANDROID_APP_TARGET_SDK@ android.library.reference.1=../FreeRDPCore manifestmerger.enabled=true From 135ba71c46d49b4638651c66b98cc3cdbc7607d5 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 16:09:45 +0200 Subject: [PATCH 154/202] Fixed typo in config options for android. --- cmake/ConfigOptionsAndroid.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ConfigOptionsAndroid.cmake b/cmake/ConfigOptionsAndroid.cmake index a2f3e48c0..aa00fac5b 100644 --- a/cmake/ConfigOptionsAndroid.cmake +++ b/cmake/ConfigOptionsAndroid.cmake @@ -16,7 +16,7 @@ # limitations under the License. set(JAVA_DEBUG_DEFAULT "off") -if("${CMAKE_BUILD_TYPE STREQUAL "Debug") +if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(JAVA_DEBUG_DEFAULT "on") endif() From 5fb9cacd5cbe98b6f16a1a707c8c76e94d3249e6 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 17 Sep 2013 16:16:02 +0200 Subject: [PATCH 155/202] Fixed android SDK version, now using variable. --- client/Android/aFreeRDP/AndroidManifest.xml.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index 3f481cb6a..d27c71052 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -6,7 +6,7 @@ android:versionCode="3" android:versionName="@GIT_REVISION@" > - + Date: Tue, 17 Sep 2013 14:56:23 -0400 Subject: [PATCH 156/202] libfreerdp-core: simplify management and consistency of PerformanceFlags --- client/common/cmdline.c | 21 +------------------ client/common/compatibility.c | 1 + client/common/file.c | 16 +++++++++++++++ include/freerdp/settings.h | 3 +++ libfreerdp/common/settings.c | 38 +++++++++++++++++++++++++++++++++++ libfreerdp/core/info.c | 3 +++ libfreerdp/core/settings.c | 17 ++++++++-------- 7 files changed, 70 insertions(+), 29 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index e1a893f75..9cbdc3d3a 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1432,7 +1432,6 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin settings->RemoteFxCodec = TRUE; settings->FastPathOutput = TRUE; settings->ColorDepth = 32; - settings->PerformanceFlags = PERF_FLAG_NONE; settings->LargePointerFlag = TRUE; settings->FrameMarkerCommandEnabled = TRUE; } @@ -1641,25 +1640,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); - settings->PerformanceFlags = PERF_FLAG_NONE; - - if (settings->AllowFontSmoothing) - settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; - - if (settings->AllowDesktopComposition) - settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; - - if (settings->DisableWallpaper) - settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; - - if (settings->DisableFullWindowDrag) - settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; - - if (settings->DisableMenuAnims) - settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; - - if (settings->DisableThemes) - settings->PerformanceFlags |= PERF_DISABLE_THEMING; + freerdp_performance_flags_make(settings); if (settings->GatewayEnabled) { diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 641bf2f65..5fdd9ea3a 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -536,6 +536,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe else { settings->PerformanceFlags = type; + freerdp_performance_flags_split(settings); } fprintf(stderr, "-x %s -> /network:", arg->Value); diff --git a/client/common/file.c b/client/common/file.c index 14bd5039b..e48e1251f 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -774,6 +774,22 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~file->UseMultiMon) freerdp_set_param_bool(settings, FreeRDP_UseMultimon, file->UseMultiMon); + if (~file->AllowFontSmoothing) + freerdp_set_param_bool(settings, FreeRDP_AllowFontSmoothing, file->AllowFontSmoothing); + if (~file->DisableWallpaper) + freerdp_set_param_bool(settings, FreeRDP_DisableWallpaper, file->DisableWallpaper); + if (~file->DisableFullWindowDrag) + freerdp_set_param_bool(settings, FreeRDP_DisableFullWindowDrag, file->DisableFullWindowDrag); + if (~file->DisableMenuAnims) + freerdp_set_param_bool(settings, FreeRDP_DisableMenuAnims, file->DisableMenuAnims); + if (~file->DisableThemes) + freerdp_set_param_bool(settings, FreeRDP_DisableThemes, file->DisableThemes); + if (~file->AllowDesktopComposition) + freerdp_set_param_bool(settings, FreeRDP_DisableCursorShadow, file->AllowDesktopComposition); + + if (~file->BitmapCachePersistEnable) + freerdp_set_param_bool(settings, FreeRDP_BitmapCachePersistEnabled, file->BitmapCachePersistEnable); + return TRUE; } diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index b9ca69342..d99d24161 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1317,6 +1317,9 @@ FREERDP_API void freerdp_dynamic_channel_collection_add(rdpSettings* settings, A FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const char* name); FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings); +FREERDP_API void freerdp_performance_flags_make(rdpSettings* settings); +FREERDP_API void freerdp_performance_flags_split(rdpSettings* settings); + FREERDP_API BOOL freerdp_get_param_bool(rdpSettings* settings, int id); FREERDP_API int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param); diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 67e801c14..1df6ba1a3 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -298,6 +298,44 @@ void freerdp_dynamic_channel_collection_free(rdpSettings* settings) settings->DynamicChannelCount = 0; } +void freerdp_performance_flags_make(rdpSettings* settings) +{ + settings->PerformanceFlags = PERF_FLAG_NONE; + + if (settings->AllowFontSmoothing) + settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; + + if (settings->AllowDesktopComposition) + settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; + + if (settings->DisableWallpaper) + settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; + + if (settings->DisableFullWindowDrag) + settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; + + if (settings->DisableMenuAnims) + settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; + + if (settings->DisableThemes) + settings->PerformanceFlags |= PERF_DISABLE_THEMING; +} + +void freerdp_performance_flags_split(rdpSettings* settings) +{ + settings->AllowFontSmoothing = (settings->PerformanceFlags & PERF_ENABLE_FONT_SMOOTHING) ? TRUE : FALSE; + + settings->AllowDesktopComposition = (settings->PerformanceFlags & PERF_ENABLE_DESKTOP_COMPOSITION) ? TRUE : FALSE; + + settings->DisableWallpaper = (settings->PerformanceFlags & PERF_DISABLE_WALLPAPER) ? TRUE : FALSE; + + settings->DisableFullWindowDrag = (settings->PerformanceFlags & PERF_DISABLE_FULLWINDOWDRAG) ? TRUE : FALSE; + + settings->DisableMenuAnims = (settings->PerformanceFlags & PERF_DISABLE_MENUANIMATIONS) ? TRUE : FALSE; + + settings->DisableThemes = (settings->PerformanceFlags & PERF_DISABLE_THEMING) ? TRUE : FALSE; +} + /** * Partially Generated Code */ diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 0d8606bc5..92d6dd331 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -153,6 +153,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) Stream_Seek_UINT32(s); /* clientSessionId, should be set to 0 */ Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ + freerdp_performance_flags_split(settings); Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ @@ -206,6 +207,8 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) rdp_write_client_time_zone(s, settings); /* clientTimeZone */ Stream_Write_UINT32(s, 0); /* clientSessionId, should be set to 0 */ + + freerdp_performance_flags_make(settings); Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index aaaaf99e9..dba2b12ae 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -243,10 +243,14 @@ rdpSettings* freerdp_settings_new(void* instance) settings->DesktopPosX = 0; settings->DesktopPosY = 0; - settings->PerformanceFlags = - PERF_DISABLE_FULLWINDOWDRAG | - PERF_DISABLE_MENUANIMATIONS | - PERF_DISABLE_WALLPAPER; + settings->PerformanceFlags = PERF_FLAG_NONE; + settings->AllowFontSmoothing = FALSE; + settings->AllowDesktopComposition = FALSE; + settings->DisableWallpaper = TRUE; + settings->DisableFullWindowDrag = TRUE; + settings->DisableMenuAnims = TRUE; + settings->DisableThemes = FALSE; + settings->ConnectionType = CONNECTION_TYPE_LAN; settings->AutoReconnectionEnabled = TRUE; @@ -306,11 +310,6 @@ rdpSettings* freerdp_settings_new(void* instance) settings->LargePointerFlag = TRUE; settings->PointerCacheSize = 20; settings->SoundBeepsEnabled = TRUE; - settings->DisableWallpaper = FALSE; - settings->DisableFullWindowDrag = FALSE; - settings->DisableMenuAnims = FALSE; - settings->DisableThemes = FALSE; - settings->ConnectionType = 0; settings->DrawGdiPlusEnabled = FALSE; From 1cfd1bdc5876661090e25e1085b3e743a3c3cead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 17 Sep 2013 15:42:36 -0400 Subject: [PATCH 157/202] libfreerdp-common: parse more .rdp file settings --- client/common/file.c | 105 +++++++++++++++++++++++++++++++++++ include/freerdp/settings.h | 2 +- libfreerdp/common/settings.c | 8 +++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/client/common/file.c b/client/common/file.c index e48e1251f..9250f916a 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -712,12 +712,52 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~((size_t) file->ShellWorkingDirectory)) freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory); + if (~file->ScreenModeId) + { + /** + * Screen Mode Id: + * http://technet.microsoft.com/en-us/library/ff393692/ + * + * This setting corresponds to the selection in the Display + * configuration slider on the Display tab under Options in RDC. + * + * Values: + * + * 0: The remote session will appear in a window. + * 1: The remote session will appear full screen. + */ + + freerdp_set_param_bool(settings, FreeRDP_Fullscreen, + (file->ScreenModeId == 1) ? TRUE : FALSE); + } + if (~((size_t) file->LoadBalanceInfo)) { settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo); settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo); } + if (~file->AuthenticationLevel) + { + /** + * Authentication Level: + * http://technet.microsoft.com/en-us/library/ff393709/ + * + * This setting corresponds to the selection in the If server authentication + * fails drop-down list on the Advanced tab under Options in RDC. + * + * Values: + * + * 0: If server authentication fails, connect to the computer without warning (Connect and don’t warn me). + * 1: If server authentication fails, do not establish a connection (Do not connect). + * 2: If server authentication fails, show a warning and allow me to connect or refuse the connection (Warn me). + * 3: No authentication requirement is specified. + */ + + freerdp_set_param_bool(settings, FreeRDP_IgnoreCertificate, + (file->AuthenticationLevel == 0) ? TRUE : FALSE); + } + if (~file->ConnectionType) freerdp_set_param_uint32(settings, FreeRDP_ConnectionType, file->ConnectionType); @@ -790,6 +830,71 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~file->BitmapCachePersistEnable) freerdp_set_param_bool(settings, FreeRDP_BitmapCachePersistEnabled, file->BitmapCachePersistEnable); + if (~file->DisableRemoteAppCapsCheck) + freerdp_set_param_bool(settings, FreeRDP_DisableRemoteAppCapsCheck, file->DisableRemoteAppCapsCheck); + + if (~file->AutoReconnectionEnabled) + freerdp_set_param_bool(settings, FreeRDP_AutoReconnectionEnabled, file->AutoReconnectionEnabled); + + if (~file->RedirectSmartCards) + freerdp_set_param_bool(settings, FreeRDP_RedirectSmartCards, file->RedirectSmartCards); + + if (~file->RedirectClipboard) + freerdp_set_param_bool(settings, FreeRDP_RedirectClipboard, file->RedirectClipboard); + + if (~file->RedirectPrinters) + freerdp_set_param_bool(settings, FreeRDP_RedirectPrinters, file->RedirectPrinters); + + if (~file->RedirectDrives) + freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, file->RedirectDrives); + + if (~file->RedirectPosDevices) + { + freerdp_set_param_bool(settings, FreeRDP_RedirectSerialPorts, file->RedirectComPorts); + freerdp_set_param_bool(settings, FreeRDP_RedirectParallelPorts, file->RedirectComPorts); + } + + if (~file->RedirectComPorts) + { + freerdp_set_param_bool(settings, FreeRDP_RedirectSerialPorts, file->RedirectComPorts); + freerdp_set_param_bool(settings, FreeRDP_RedirectParallelPorts, file->RedirectComPorts); + } + + if (~file->RedirectDirectX) + { + /* What is this?! */ + } + + if (~((size_t) file->DevicesToRedirect)) + { + /** + * Devices to redirect: + * http://technet.microsoft.com/en-us/library/ff393728/ + * + * This setting corresponds to the selections for Other supported Plug and Play + * (PnP) devices under More on the Local Resources tab under Options in RDC. + * + * Values: + * + * '*': + * Redirect all supported Plug and Play devices. + * + * 'DynamicDevices': + * Redirect any supported Plug and Play devices that are connected later. + * + * The hardware ID for the supported Plug and Play device: + * Redirect the specified supported Plug and Play device. + * + * Examples: + * devicestoredirect:s:* + * devicestoredirect:s:DynamicDevices + * devicestoredirect:s:USB\VID_04A9&PID_30C1\6&4BD985D&0&2;,DynamicDevices + * + */ + + freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); + } + return TRUE; } diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index d99d24161..02697579d 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1046,7 +1046,7 @@ struct rdp_settings ALIGN64 char* RemoteApplicationCmdLine; /* 2118 */ ALIGN64 DWORD RemoteApplicationExpandCmdLine; /* 2119 */ ALIGN64 DWORD RemoteApplicationExpandWorkingDir; /* 2120 */ - ALIGN64 DWORD DisableRemoteAppCapsCheck; /* 2121 */ + ALIGN64 BOOL DisableRemoteAppCapsCheck; /* 2121 */ ALIGN64 UINT32 RemoteAppNumIconCaches; /* 2122 */ ALIGN64 UINT32 RemoteAppNumIconCacheEntries; /* 2123 */ ALIGN64 BOOL RemoteAppLanguageBarSupported; /* 2124 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 1df6ba1a3..ffcf1937f 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -616,6 +616,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->RemoteApplicationMode; break; + case FreeRDP_DisableRemoteAppCapsCheck: + return settings->DisableRemoteAppCapsCheck; + break; + case FreeRDP_RemoteAppLanguageBarSupported: return settings->RemoteAppLanguageBarSupported; break; @@ -1071,6 +1075,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->RemoteApplicationMode = param; break; + case FreeRDP_DisableRemoteAppCapsCheck: + settings->DisableRemoteAppCapsCheck = param; + break; + case FreeRDP_RemoteAppLanguageBarSupported: settings->RemoteAppLanguageBarSupported = param; break; From d2b9d9f9d5cc647aef91f72a3cd77dfc2a4b543d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 17 Sep 2013 15:58:48 -0400 Subject: [PATCH 158/202] libfreerdp-common: add extra .rdp file options --- client/common/file.c | 17 +++++++++++++++++ libfreerdp/core/settings.c | 3 +++ 2 files changed, 20 insertions(+) diff --git a/client/common/file.c b/client/common/file.c index 9250f916a..35f7b74d7 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -778,6 +778,9 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* } } + if (~file->Compression) + freerdp_set_param_bool(settings, FreeRDP_CompressionEnabled, file->Compression); + if (~((size_t) file->GatewayHostname)) freerdp_set_param_string(settings, FreeRDP_GatewayHostname, file->GatewayHostname); @@ -835,6 +838,8 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* if (~file->AutoReconnectionEnabled) freerdp_set_param_bool(settings, FreeRDP_AutoReconnectionEnabled, file->AutoReconnectionEnabled); + if (~file->AutoReconnectMaxRetries) + freerdp_set_param_uint32(settings, FreeRDP_AutoReconnectMaxRetries, file->AutoReconnectMaxRetries); if (~file->RedirectSmartCards) freerdp_set_param_bool(settings, FreeRDP_RedirectSmartCards, file->RedirectSmartCards); @@ -895,6 +900,18 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); } + if (~((size_t) file->DrivesToRedirect)) + { + /* + * Drives to redirect: + * + * Very similar to DevicesToRedirect, but can contain a + * comma-separated list of drive letters to redirect. + */ + + freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); + } + return TRUE; } diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index dba2b12ae..ea719aae3 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -391,6 +391,9 @@ rdpSettings* freerdp_settings_new(void* instance) settings->ClientHostname[31] = 0; settings->MouseMotion = TRUE; + settings->AutoReconnectionEnabled = TRUE; + settings->AutoReconnectMaxRetries = 20; + settings->ClientAutoReconnectCookie = (ARC_CS_PRIVATE_PACKET*) malloc(sizeof(ARC_CS_PRIVATE_PACKET)); settings->ServerAutoReconnectCookie = (ARC_SC_PRIVATE_PACKET*) malloc(sizeof(ARC_SC_PRIVATE_PACKET)); ZeroMemory(settings->ClientAutoReconnectCookie, sizeof(ARC_CS_PRIVATE_PACKET)); From 10f1a898ef3892c5a625f3fed4e4d818cb90292b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 17 Sep 2013 17:03:35 -0400 Subject: [PATCH 159/202] libfreerdp-client: fix command-line parsing with .rdp file --- client/common/client.c | 42 ++++++++++++++++++---------------- client/common/cmdline.c | 35 +++++++++++++++++++++++++--- client/common/file.c | 7 +++--- winpr/libwinpr/utils/cmdline.c | 22 ++++++++++++++---- 4 files changed, 75 insertions(+), 31 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 9bba04740..1c19445b4 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -113,7 +113,7 @@ int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv if (settings->ConnectionFile) { - return freerdp_client_parse_connection_file(context, settings->ConnectionFile); + status = freerdp_client_parse_connection_file(context, settings->ConnectionFile); } return status; @@ -134,35 +134,37 @@ int freerdp_client_parse_connection_file(rdpContext* context, const char* filena int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size) { rdpFile* file; - int status = -1; + int status = -1; file = freerdp_client_rdp_file_new(); - if (freerdp_client_parse_rdp_file_buffer(file, buffer, size) - && freerdp_client_populate_settings_from_rdp_file(file, context->settings)) - { - status = 0; - } + + if (freerdp_client_parse_rdp_file_buffer(file, buffer, size) + && freerdp_client_populate_settings_from_rdp_file(file, context->settings)) + { + status = 0; + } freerdp_client_rdp_file_free(file); - return status; + return status; } int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode) { - rdpFile* file; - int status = -1; + rdpFile* file; + int status = -1; - file = freerdp_client_rdp_file_new(); - if (freerdp_client_populate_rdp_file_from_settings(file, context->settings)) - { - if (freerdp_client_write_rdp_file(file, filename, unicode)) - { - status = 0; - } - } + file = freerdp_client_rdp_file_new(); - freerdp_client_rdp_file_free(file); + if (freerdp_client_populate_rdp_file_from_settings(file, context->settings)) + { + if (freerdp_client_write_rdp_file(file, filename, unicode)) + { + status = 0; + } + } - return status; + freerdp_client_rdp_file_free(file); + + return status; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 9cbdc3d3a..d366f739f 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -856,6 +856,26 @@ int freerdp_map_keyboard_layout_name_to_id(char* name) return 0; } +int freerdp_detect_command_line_pre_filter(void* context, int index, int argc, LPCSTR* argv) +{ + int length; + + if (index == 1) + { + length = strlen(argv[index]); + + if (length > 4) + { + if (_stricmp(&(argv[index])[length - 4], ".rdp") == 0) + { + return 1; + } + } + } + + return 0; +} + int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* count) { int status; @@ -869,7 +889,10 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* *count = 0; detect_status = 0; CommandLineClearArgumentsA(args); - status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + + status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, + NULL, freerdp_detect_command_line_pre_filter, NULL); + if (status < 0) return status; @@ -904,7 +927,10 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c *count = 0; detect_status = 0; CommandLineClearArgumentsA(args); - status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + + status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, + NULL, freerdp_detect_command_line_pre_filter, NULL); + if (status < 0) return status; @@ -949,9 +975,10 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) *flags = COMMAND_LINE_SEPARATOR_COLON; *flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS; } - /* Ignore legacy parsing in case there is an error in the command line. */ else if (old_cli_status >= 0) { + /* Ignore legacy parsing in case there is an error in the command line. */ + if ((old_cli_status == 1) || ((old_cli_count > posix_cli_count) && (old_cli_status != -1))) { *flags = COMMAND_LINE_SEPARATOR_SPACE; @@ -1046,8 +1073,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin else { CommandLineClearArgumentsA(args); + status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); + if (status < 0) return status; } diff --git a/client/common/file.c b/client/common/file.c index 35f7b74d7..1ce7fdb36 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -42,7 +42,7 @@ #include -#define DEBUG_CLIENT_FILE 1 +//#define DEBUG_CLIENT_FILE 1 static BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE }; static WCHAR CR_LF_STR_W[] = { '\r', '\n', '\0' }; @@ -679,12 +679,13 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* freerdp_parse_username(file->Username, &user, &domain); freerdp_set_param_string(settings, FreeRDP_Username, user); - if (domain != NULL) + if (domain) freerdp_set_param_string(settings, FreeRDP_Domain, domain); if (user) free(user); - if(domain) + + if (domain) free(domain); } diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 1e6c45079..3ac9213ef 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -53,8 +53,11 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int count; int length; int index; - BOOL match, found, argument = FALSE; - BOOL notescaped = FALSE; + BOOL match; + BOOL found; + BOOL argument; + BOOL escaped; + BOOL notescaped; char* sigil; int sigil_length; int sigil_index; @@ -71,6 +74,12 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* status = 0; + match = FALSE; + found = FALSE; + argument = FALSE; + escaped = TRUE; + notescaped = FALSE; + if (!argv) return status; @@ -82,12 +91,14 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* for (i = 1; i < argc; i++) { - BOOL escaped = TRUE; index = i; + escaped = TRUE; + if (preFilter) { count = preFilter(context, i, argc, argv); + if (count < 0) { status = COMMAND_LINE_ERROR; @@ -96,7 +107,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* if (count > 0) { - i += count; + i += (count - 1); continue; } } @@ -136,6 +147,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* { if (notescaped) return COMMAND_LINE_ERROR; + sigil_length = 0; escaped = FALSE; notescaped = TRUE; @@ -144,7 +156,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* { return COMMAND_LINE_ERROR; } - + if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE) || (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)) { From 1f15d39f8a96f77f7b6d9464bd71d71d266322cb Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Tue, 17 Sep 2013 23:12:33 +0200 Subject: [PATCH 160/202] Correct generation of PasswordDialog.nib --- client/Mac/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Mac/CMakeLists.txt b/client/Mac/CMakeLists.txt index 2344f46a1..7fc35cea7 100755 --- a/client/Mac/CMakeLists.txt +++ b/client/Mac/CMakeLists.txt @@ -152,7 +152,7 @@ endif() COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources) # Compile the .xib files using the 'ibtool' program with the destination being the app package - foreach(xib ${${MODULE_NAME}_XIBS}) + foreach(xib ${${MODULE_PREFIX}_XIBS}) get_filename_component(XIB_WE ${xib} NAME_WE) add_custom_command (TARGET ${MODULE_NAME} POST_BUILD From 2695e906e01b0a86c74050fc514fed7ad1e0fc79 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 18 Sep 2013 10:16:58 +0200 Subject: [PATCH 161/202] Removed command line parser error return in evaluation of already parsed arguments. --- client/common/cmdline.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index e1a893f75..ae9226038 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1633,8 +1633,6 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin } CommandLineSwitchDefault(arg) { - fprintf(stderr, "Unknown argument %s\n", __func__, arg->Name); - return COMMAND_LINE_ERROR; } CommandLineSwitchEnd(arg) From 4910a33f3c9f6a69098045c4852c1ee639d29a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 18 Sep 2013 14:01:19 -0400 Subject: [PATCH 162/202] libfreerdp-client: add support for parsing command-line options from .rdp file --- client/common/file.c | 87 +++++++++++++++++++++++++++++++---- include/freerdp/client/file.h | 4 ++ 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/client/common/file.c b/client/common/file.c index 1ce7fdb36..fecfe54c2 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -269,6 +269,18 @@ BOOL freerdp_client_rdp_file_set_string(rdpFile* file, char* name, char* value) return TRUE; } +void freerdp_client_add_option(rdpFile* file, char* option) +{ + while ((file->argc + 1) > file->argSize) + { + file->argSize *= 2; + file->argv = (char**) realloc(file->argv, file->argSize * sizeof(char*)); + } + + file->argv[file->argc] = _strdup(option); + (file->argc)++; +} + void freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value) { int length; @@ -296,6 +308,21 @@ void freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* freerdp_client_rdp_file_set_string(file, name, value); } +void freerdp_client_parse_rdp_file_option_unicode(rdpFile* file, WCHAR* option) +{ + char* optionA = NULL; + + ConvertFromUnicode(CP_UTF8, 0, option, -1, &optionA, 0, NULL, NULL); + freerdp_client_add_option(file, optionA); + + free(optionA); +} + +void freerdp_client_parse_rdp_file_option_ascii(rdpFile* file, char* option) +{ + freerdp_client_add_option(file, option); +} + BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, BYTE* buffer, size_t size) { int length; @@ -317,6 +344,12 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, BYTE* buffer, siz beg = line; end = &line[length - 1]; + if (beg[0] == '/') + { + freerdp_client_parse_rdp_file_option_ascii(file, line); + goto next_line; /* FreeRDP option */ + } + d1 = strchr(line, ':'); if (!d1) @@ -383,6 +416,13 @@ BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, BYTE* buffer, s beg = line; end = &line[length - 1]; + if (beg[0] == '/') + { + /* FreeRDP option */ + freerdp_client_parse_rdp_file_option_unicode(file, line); + goto next_line; + } + d1 = _wcschr(line, ':'); if (!d1) @@ -533,16 +573,16 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* return TRUE; } - BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode) { - int rc = 0; + int rc = 0; char* buffer; int len, len2; FILE* fp = NULL; WCHAR* unicodestr = NULL; len = freerdp_client_write_rdp_file_buffer(file, NULL, 0); + if (len <= 0) { fprintf(stderr, "freerdp_client_write_rdp_file: Error determining buffer size.\n"); @@ -551,9 +591,11 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode buffer = (char*) malloc((len + 1) * sizeof(char)); len2 = freerdp_client_write_rdp_file_buffer(file, buffer, len + 1); + if (len2 == len) { fp = fopen(name, "w+b"); + if (fp != NULL) { if (unicode) @@ -564,22 +606,22 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp); fwrite(unicodestr, 2, len, fp); - free(unicodestr); + free(unicodestr); } else { fwrite(buffer, 1, len, fp); } - rc = fflush(fp); - rc = fclose(fp); + rc = fflush(fp); + rc = fclose(fp); } } if (buffer != NULL) free(buffer); - return (rc == 0); + return (rc == 0); } #define WRITE_RDP_FILE_DECLARE(_file, _buffer, _size) \ @@ -665,7 +707,6 @@ size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t WRITE_RDP_FILE_VALUE_RETURN } - BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings) { if (~((size_t) file->Domain)) @@ -913,6 +954,11 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); } + if (file->argc > 1) + { + freerdp_client_parse_command_line_arguments(file->argc, file->argv, settings); + } + return TRUE; } @@ -921,12 +967,35 @@ rdpFile* freerdp_client_rdp_file_new() rdpFile* file; file = (rdpFile*) malloc(sizeof(rdpFile)); - FillMemory(file, sizeof(rdpFile), 0xFF); + + if (file) + { + FillMemory(file, sizeof(rdpFile), 0xFF); + + file->argc = 0; + file->argSize = 32; + file->argv = (char**) malloc(file->argSize * sizeof(char*)); + + freerdp_client_add_option(file, "freerdp"); + } return file; } void freerdp_client_rdp_file_free(rdpFile* file) { - free(file); + int i; + + if (file) + { + if (file->argv) + { + for (i = 0; i < file->argc; i++) + free(file->argv[i]); + + free(file->argv); + } + + free(file); + } } diff --git a/include/freerdp/client/file.h b/include/freerdp/client/file.h index 8fffdfbe8..bf9dcb4d6 100644 --- a/include/freerdp/client/file.h +++ b/include/freerdp/client/file.h @@ -129,6 +129,10 @@ struct rdp_file LPSTR DrivesToRedirect; /* drivestoredirect */ LPSTR DevicesToRedirect; /* devicestoredirect */ LPSTR WinPosStr; /* winposstr */ + + int argc; + char** argv; + int argSize; }; typedef struct rdp_file rdpFile; From ffa616bff4d9c21d8e20210c76eab1a089ac638e Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Wed, 18 Sep 2013 23:34:43 +0200 Subject: [PATCH 163/202] Correct username place holder in mac application --- client/Mac/PasswordDialog.xib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Mac/PasswordDialog.xib b/client/Mac/PasswordDialog.xib index 5d98e2a7a..afdd957c7 100644 --- a/client/Mac/PasswordDialog.xib +++ b/client/Mac/PasswordDialog.xib @@ -239,7 +239,7 @@ 272630784 - billg + Username _NS:9 YES From 64454faf717fbad6c417e2baa9aef8b649d9de1e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 19 Sep 2013 10:23:28 +0200 Subject: [PATCH 164/202] Fixed double free of wave buffer. --- channels/rdpsnd/client/rdpsnd_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 9411380aa..5047ed76a 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -444,8 +444,6 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS; rdpsnd->device->WaveConfirm(rdpsnd->device, wave); } - else - free(wave); } static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd) From 403a9fff62ea1ef5e12ddcc4ec6c22f82ff7f74a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Thu, 19 Sep 2013 10:34:18 +0200 Subject: [PATCH 165/202] Fixed compiler warnings. --- channels/rdpsnd/client/alsa/rdpsnd_alsa.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 07a779a02..e775e48d3 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -72,7 +72,7 @@ struct rdpsnd_alsa_plugin return -1; \ } -int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa) +static int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa) { int status; snd_pcm_hw_params_t* hw_params; @@ -131,7 +131,7 @@ int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa) return 0; } -int rdpsnd_alsa_set_sw_params(rdpsndAlsaPlugin* alsa) +static int rdpsnd_alsa_set_sw_params(rdpsndAlsaPlugin* alsa) { int status; snd_pcm_sw_params_t* sw_params; @@ -158,7 +158,7 @@ int rdpsnd_alsa_set_sw_params(rdpsndAlsaPlugin* alsa) return 0; } -int rdpsnd_alsa_validate_params(rdpsndAlsaPlugin* alsa) +static int rdpsnd_alsa_validate_params(rdpsndAlsaPlugin* alsa) { int status; snd_pcm_uframes_t buffer_size; @@ -413,8 +413,6 @@ static UINT32 rdpsnd_alsa_get_volume(rdpsndDevicePlugin* device) long volume_max; long volume_left; long volume_right; - int percent_left; - int percent_right; UINT32 dwVolume; UINT16 dwVolumeLeft; UINT16 dwVolumeRight; @@ -438,9 +436,6 @@ static UINT32 rdpsnd_alsa_get_volume(rdpsndDevicePlugin* device) dwVolumeLeft = (UINT16) (((volume_left * 0xFFFF) - volume_min) / (volume_max - volume_min)); dwVolumeRight = (UINT16) (((volume_right * 0xFFFF) - volume_min) / (volume_max - volume_min)); - percent_left = (dwVolumeLeft * 100) / 0xFFFF; - percent_right = (dwVolumeRight * 100) / 0xFFFF; - break; } } @@ -485,7 +480,7 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value) } } -BYTE* rdpsnd_alsa_process_audio_sample(rdpsndDevicePlugin* device, BYTE* data, int* size) +static BYTE* rdpsnd_alsa_process_audio_sample(rdpsndDevicePlugin* device, BYTE* data, int* size) { int frames; BYTE* srcData; @@ -622,13 +617,13 @@ static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) device->WaveConfirm(device, wave); } -COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = +static COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = { { "dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "device" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; -static void rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args) +static int rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args) { int status; DWORD flags; @@ -638,6 +633,8 @@ static void rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_alsa_args, flags, alsa, NULL, NULL); + if (status) + return status; arg = rdpsnd_alsa_args; @@ -656,6 +653,8 @@ static void rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + + return status; } #ifdef STATIC_CHANNELS From 929d292f355cbc6e450b4a676b1ef868b224a779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Sep 2013 12:08:20 -0400 Subject: [PATCH 166/202] wfreerdp: fix compilation --- CMakeLists.txt | 7 + client/Windows/wf_interface.c | 1 + include/freerdp/channels/rdpdr.h | 9 - winpr/include/winpr/nt.h | 257 ++++++++++++++++++---------- winpr/include/winpr/synch.h | 2 + winpr/tools/makecert/CMakeLists.txt | 7 +- 6 files changed, 179 insertions(+), 104 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9ce8252f..18ef1e858 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,14 @@ if(CMAKE_COMPILER_IS_GNUCC) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") endif() + else() + if(CMAKE_POSITION_INDEPENDENT_CODE) + if(${CMAKE_VERSION} VERSION_LESS 2.8.9) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() + endif() endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") CHECK_C_COMPILER_FLAG (-Wno-unused-result Wno-unused-result) if(Wno-unused-result) diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index b4969a933..87abe188d 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #ifdef _MSC_VER diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 9a3077a30..2d7f6401e 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -103,15 +103,6 @@ enum IRP_MN }; /* DR_CREATE_REQ.CreateDisposition */ -enum FILE_CREATE_DISPOSITION -{ - FILE_SUPERSEDE = 0x00000000, - FILE_OPEN = 0x00000001, - FILE_CREATE = 0x00000002, - FILE_OPEN_IF = 0x00000003, - FILE_OVERWRITE = 0x00000004, - FILE_OVERWRITE_IF = 0x00000005 -}; /* DR_CREATE_REQ.CreateOptions [MS-SMB2] */ diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index dccf6e69b..6664576bb 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -22,9 +22,71 @@ #include #include +#include #ifndef _WIN32 +/* Defined in winnt.h, do not redefine */ + +#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L) +#define STATUS_ABANDONED_WAIT_0 ((NTSTATUS)0x00000080L) +#define STATUS_USER_APC ((NTSTATUS)0x000000C0L) +#define STATUS_TIMEOUT ((NTSTATUS)0x00000102L) +#define STATUS_PENDING ((NTSTATUS)0x00000103L) +#define DBG_EXCEPTION_HANDLED ((NTSTATUS)0x00010001L) +#define DBG_CONTINUE ((NTSTATUS)0x00010002L) +#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005L) +#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015L) +#define DBG_TERMINATE_THREAD ((NTSTATUS)0x40010003L) +#define DBG_TERMINATE_PROCESS ((NTSTATUS)0x40010004L) +#define DBG_CONTROL_C ((NTSTATUS)0x40010005L) +#define DBG_PRINTEXCEPTION_C ((NTSTATUS)0x40010006L) +#define DBG_RIPEXCEPTION ((NTSTATUS)0x40010007L) +#define DBG_CONTROL_BREAK ((NTSTATUS)0x40010008L) +#define DBG_COMMAND_EXCEPTION ((NTSTATUS)0x40010009L) +#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001L) +#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002L) +#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003L) +#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004L) +#define STATUS_LONGJUMP ((NTSTATUS)0x80000026L) +#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029L) +#define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS)0x80010001L) +#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L) +#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006L) +#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) +#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL) +#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017L) +#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001DL) +#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025L) +#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026L) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008CL) +#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008DL) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008EL) +#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008FL) +#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090L) +#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091L) +#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092L) +#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093L) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094L) +#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095L) +#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096L) +#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FDL) +#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135L) +#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138L) +#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139L) +#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013AL) +#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142L) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4L) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5L) +#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9L) +#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409L) +#define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS)0xC0000417L) +#define STATUS_ASSERTION_FAILURE ((NTSTATUS)0xC0000420L) +#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000FL) +#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010L) + +#endif + #define FACILITY_DEBUGGER 0x1 #define FACILITY_RPC_RUNTIME 0x2 #define FACILITY_RPC_STUBS 0x3 @@ -37,18 +99,18 @@ #define FACILITY_ACPI_ERROR_CODE 0x14 #define FACILITY_SXS_ERROR_CODE 0x15 -#define DBG_EXCEPTION_HANDLED ((NTSTATUS)0x00010001) -#define DBG_CONTINUE ((NTSTATUS)0x00010002) +//#define DBG_EXCEPTION_HANDLED ((NTSTATUS)0x00010001) +//#define DBG_CONTINUE ((NTSTATUS)0x00010002) #define DBG_REPLY_LATER ((NTSTATUS)0x40010001) #define DBG_UNABLE_TO_PROVIDE_HANDLE ((NTSTATUS)0x40010002) -#define DBG_TERMINATE_THREAD ((NTSTATUS)0x40010003) -#define DBG_TERMINATE_PROCESS ((NTSTATUS)0x40010004) -#define DBG_CONTROL_C ((NTSTATUS)0x40010005) -#define DBG_PRINTEXCEPTION_C ((NTSTATUS)0x40010006) -#define DBG_RIPEXCEPTION ((NTSTATUS)0x40010007) -#define DBG_CONTROL_BREAK ((NTSTATUS)0x40010008) -#define DBG_COMMAND_EXCEPTION ((NTSTATUS)0x40010009) -#define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS)0x80010001) +//#define DBG_TERMINATE_THREAD ((NTSTATUS)0x40010003) +//#define DBG_TERMINATE_PROCESS ((NTSTATUS)0x40010004) +//#define DBG_CONTROL_C ((NTSTATUS)0x40010005) +//#define DBG_PRINTEXCEPTION_C ((NTSTATUS)0x40010006) +//#define DBG_RIPEXCEPTION ((NTSTATUS)0x40010007) +//#define DBG_CONTROL_BREAK ((NTSTATUS)0x40010008) +//#define DBG_COMMAND_EXCEPTION ((NTSTATUS)0x40010009) +//#define DBG_EXCEPTION_NOT_HANDLED ((NTSTATUS)0x80010001) #define DBG_NO_STATE_CHANGE ((NTSTATUS)0xC0010001) #define DBG_APP_NOT_IDLE ((NTSTATUS)0xC0010002) @@ -71,11 +133,11 @@ #define STATUS_WAIT_63 ((NTSTATUS)0x0000003f) #define STATUS_ABANDONED ((NTSTATUS)0x00000080) #define STATUS_ABANDONED_WAIT_63 ((NTSTATUS)0x000000BF) -#define STATUS_USER_APC ((NTSTATUS)0x000000C0) +//#define STATUS_USER_APC ((NTSTATUS)0x000000C0) #define STATUS_KERNEL_APC ((NTSTATUS)0x00000100) #define STATUS_ALERTED ((NTSTATUS)0x00000101) -#define STATUS_TIMEOUT ((NTSTATUS)0x00000102) -#define STATUS_PENDING ((NTSTATUS)0x00000103) +//#define STATUS_TIMEOUT ((NTSTATUS)0x00000102) +//#define STATUS_PENDING ((NTSTATUS)0x00000103) #define STATUS_REPARSE ((NTSTATUS)0x00000104) #define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105) #define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS)0x00000106) @@ -110,7 +172,7 @@ #define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS)0x40000002) #define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS)0x40000003) #define STATUS_RXACT_STATE_CREATED ((NTSTATUS)0x40000004) -#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005) +//#define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS)0x40000005) #define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS)0x40000006) #define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS)0x40000007) #define STATUS_SERIAL_MORE_WRITES ((NTSTATUS)0x40000008) @@ -126,7 +188,7 @@ #define STATUS_EVENT_DONE ((NTSTATUS)0x40000012) #define STATUS_EVENT_PENDING ((NTSTATUS)0x40000013) #define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS)0x40000014) -#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015) +//#define STATUS_FATAL_APP_EXIT ((NTSTATUS)0x40000015) #define STATUS_PREDEFINED_HANDLE ((NTSTATUS)0x40000016) #define STATUS_WAS_UNLOCKED ((NTSTATUS)0x40000017) #define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018) @@ -161,10 +223,10 @@ #define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT ((NTSTATUS)0x4015000D) -#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001) -#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002) -#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003) -#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004) +//#define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS)0x80000001) +//#define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS)0x80000002) +//#define STATUS_BREAKPOINT ((NTSTATUS)0x80000003) +//#define STATUS_SINGLE_STEP ((NTSTATUS)0x80000004) #define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005) #define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006) #define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS)0x80000007) @@ -196,10 +258,10 @@ #define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS)0x80000023) #define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS)0x80000024) #define STATUS_ALREADY_DISCONNECTED ((NTSTATUS)0x80000025) -#define STATUS_LONGJUMP ((NTSTATUS)0x80000026) +//#define STATUS_LONGJUMP ((NTSTATUS)0x80000026) #define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS)0x80000027) #define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS)0x80000028) -#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029) +//#define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS)0x80000029) #define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS)0x8000002A) #define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS)0x8000002B) #define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS)0x8000002C) @@ -213,20 +275,20 @@ #define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE ((NTSTATUS)0x80130004) #define STATUS_CLUSTER_NODE_ALREADY_MEMBER ((NTSTATUS)0x80130005) -#define STATUS_WAIT_0 ((NTSTATUS)0x00000000) +//#define STATUS_WAIT_0 ((NTSTATUS)0x00000000) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001) #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002) #define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004) -#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005) -#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006) +//#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005) +//#define STATUS_IN_PAGE_ERROR ((NTSTATUS)0xC0000006) #define STATUS_PAGEFILE_QUOTA ((NTSTATUS)0xC0000007) -#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008) +//#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008) #define STATUS_BAD_INITIAL_STACK ((NTSTATUS)0xC0000009) #define STATUS_BAD_INITIAL_PC ((NTSTATUS)0xC000000A) #define STATUS_INVALID_CID ((NTSTATUS)0xC000000B) #define STATUS_TIMER_NOT_CANCELED ((NTSTATUS)0xC000000C) -#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000D) +//#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000D) #define STATUS_NO_SUCH_DEVICE ((NTSTATUS)0xC000000E) #define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000F) #define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010) @@ -236,13 +298,13 @@ #define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS)0xC0000014) #define STATUS_NONEXISTENT_SECTOR ((NTSTATUS)0xC0000015) #define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS)0xC0000016) -#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017) +//#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017) #define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018) #define STATUS_NOT_MAPPED_VIEW ((NTSTATUS)0xC0000019) #define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS)0xC000001A) #define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS)0xC000001B) #define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS)0xC000001C) -#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001D) +//#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001D) #define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS)0xC000001E) #define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xC000001F) #define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020) @@ -250,8 +312,8 @@ #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023) #define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024) -#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025) -#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026) +//#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025) +//#define STATUS_INVALID_DISPOSITION ((NTSTATUS)0xC0000026) #define STATUS_UNWIND ((NTSTATUS)0xC0000027) #define STATUS_BAD_STACK ((NTSTATUS)0xC0000028) #define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS)0xC0000029) @@ -352,17 +414,17 @@ #define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS)0xC0000089) #define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS)0xC000008A) #define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS)0xC000008B) -#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008C) -#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008D) -#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008E) -#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008F) -#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090) -#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091) -#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092) -#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093) -#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094) -#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095) -#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096) +//#define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS)0xC000008C) +//#define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS)0xC000008D) +//#define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS)0xC000008E) +//#define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS)0xC000008F) +//#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090) +//#define STATUS_FLOAT_OVERFLOW ((NTSTATUS)0xC0000091) +//#define STATUS_FLOAT_STACK_CHECK ((NTSTATUS)0xC0000092) +//#define STATUS_FLOAT_UNDERFLOW ((NTSTATUS)0xC0000093) +//#define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS)0xC0000094) +//#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095) +//#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096) #define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS)0xC0000097) #define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098) #define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS)0xC0000099) @@ -465,7 +527,7 @@ #define STATUS_INVALID_PARAMETER_12 ((NTSTATUS)0xC00000FA) #define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS)0xC00000FB) #define STATUS_REDIRECTOR_STARTED ((NTSTATUS)0xC00000FC) -#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FD) +//#define STATUS_STACK_OVERFLOW ((NTSTATUS)0xC00000FD) #define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xC00000FE) #define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS)0xC00000FF) #define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS)0xC0000100) @@ -521,12 +583,12 @@ #define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS)0xC0000132) #define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS)0xC0000133) #define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS)0xC0000134) -#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135) +//#define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135) #define STATUS_OPEN_FAILED ((NTSTATUS)0xC0000136) #define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS)0xC0000137) -#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138) -#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139) -#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013A) +//#define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS)0xC0000138) +//#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS)0xC0000139) +//#define STATUS_CONTROL_C_EXIT ((NTSTATUS)0xC000013A) #define STATUS_LOCAL_DISCONNECT ((NTSTATUS)0xC000013B) #define STATUS_REMOTE_DISCONNECT ((NTSTATUS)0xC000013C) #define STATUS_REMOTE_RESOURCES ((NTSTATUS)0xC000013D) @@ -534,7 +596,7 @@ #define STATUS_LINK_TIMEOUT ((NTSTATUS)0xC000013F) #define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140) #define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141) -#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142) +//#define STATUS_DLL_INIT_FAILED ((NTSTATUS)0xC0000142) #define STATUS_MISSING_SYSTEMFILE ((NTSTATUS)0xC0000143) #define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS)0xC0000144) #define STATUS_APP_INIT_FAILURE ((NTSTATUS)0xC0000145) @@ -783,8 +845,8 @@ #define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS)0xC00002B1) #define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS)0xC00002B2) #define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS)0xC00002B3) -#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4) -#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5) +//#define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS)0xC00002B4) +//#define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS)0xC00002B5) #define STATUS_DEVICE_REMOVED ((NTSTATUS)0xC00002B6) #define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS)0xC00002B7) #define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS)0xC00002B8) @@ -797,7 +859,7 @@ #define STATUS_WMI_READ_ONLY ((NTSTATUS)0xC00002C6) #define STATUS_WMI_SET_FAILURE ((NTSTATUS)0xC00002C7) #define STATUS_COMMITMENT_MINIMUM ((NTSTATUS)0xC00002C8) -#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9) +//#define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS)0xC00002C9) #define STATUS_TRANSPORT_FULL ((NTSTATUS)0xC00002CA) #define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS)0xC00002CB) #define STATUS_ONLY_IF_CONNECTED ((NTSTATUS)0xC00002CC) @@ -922,7 +984,7 @@ #define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS)0xC0000406) #define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS)0xC0000407) #define STATUS_USER2USER_REQUIRED ((NTSTATUS)0xC0000408) -#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409) +//#define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409) #define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS)0xC000040A) #define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS)0xC000040B) #define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS)0xC000040C) @@ -935,8 +997,8 @@ #define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) #define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) #define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) -#define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS)0xC0000417) -#define STATUS_ASSERTION_FAILURE ((NTSTATUS)0xC0000420L) +//#define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS)0xC0000417) +//#define STATUS_ASSERTION_FAILURE ((NTSTATUS)0xC0000420L) #define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898) @@ -1156,8 +1218,8 @@ #define STATUS_SXS_THREAD_QUERIES_DISABLED ((NTSTATUS)0xC015000B) #define STATUS_SXS_ASSEMBLY_MISSING ((NTSTATUS)0xC015000C) #define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET ((NTSTATUS)0xC015000E) -#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000F) -#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010) +//#define STATUS_SXS_EARLY_DEACTIVATION ((NTSTATUS)0xC015000F) +//#define STATUS_SXS_INVALID_DEACTIVATION ((NTSTATUS)0xC0150010) #define STATUS_SXS_MULTIPLE_DEACTIVATION ((NTSTATUS)0xC0150011) #define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY ((NTSTATUS)0xC0150012) #define STATUS_SXS_PROCESS_TERMINATION_REQUESTED ((NTSTATUS)0xC0150013) @@ -1182,6 +1244,57 @@ #define STATUS_GENERIC_COMMAND_FAILED ((NTSTATUS)0xC0150026) #define STATUS_SXS_FILE_HASH_MISSING ((NTSTATUS)0xC0150027) +/* Defined in winternl.h, always define since we do not include this header */ + +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 + +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 + +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 + +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_REMOTE_INSTANCE 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 + +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 + +#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000 + +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + +#define FILE_VALID_OPTION_FLAGS 0x00FFFFFF +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +#ifndef _WIN32 + typedef struct _PEB PEB; typedef struct _PEB* PPEB; @@ -1261,40 +1374,6 @@ struct _TEB #define FILE_SHARE_WRITE 0x00000002 #define FILE_SHARE_DELETE 0x00000004 -#define FILE_DIRECTORY_FILE 0x00000001 -#define FILE_WRITE_THROUGH 0x00000002 -#define FILE_SEQUENTIAL_ONLY 0x00000004 -#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 -#define FILE_NON_DIRECTORY_FILE 0x00000040 -#define FILE_CREATE_TREE_CONNECTION 0x00000080 -#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 -#define FILE_NO_EA_KNOWLEDGE 0x00000200 -#define FILE_OPEN_REMOTE_INSTANCE 0x00000400 -#define FILE_RANDOM_ACCESS 0x00000800 -#define FILE_DELETE_ON_CLOSE 0x00001000 -#define FILE_OPEN_BY_FILE_ID 0x00002000 -#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 -#define FILE_NO_COMPRESSION 0x00008000 -#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000 -#define FILE_RESERVE_OPFILTER 0x00100000 -#define FILE_OPEN_REPARSE_POINT 0x00200000 -#define FILE_OPEN_NO_RECALL 0x00400000 -#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 - -#define FILE_VALID_OPTION_FLAGS 0x00FFFFFF -#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 -#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 -#define FILE_VALID_SET_FLAGS 0x00000036 - -#define FILE_SUPERSEDED 0x00000000 -#define FILE_OPENED 0x00000001 -#define FILE_CREATED 0x00000002 -#define FILE_OVERWRITTEN 0x00000003 -#define FILE_EXISTS 0x00000004 -#define FILE_DOES_NOT_EXIST 0x00000005 - typedef DWORD ACCESS_MASK; typedef ACCESS_MASK* PACCESS_MASK; diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index 136c0877a..45373ac00 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -29,6 +29,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/winpr/tools/makecert/CMakeLists.txt b/winpr/tools/makecert/CMakeLists.txt index 4089fd914..84386697a 100644 --- a/winpr/tools/makecert/CMakeLists.txt +++ b/winpr/tools/makecert/CMakeLists.txt @@ -25,12 +25,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${OPENSSL_INCLUDE_DIR}) -add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) - -# This line compiles the static libraries with -fPIC to allow linking -# to shared libraries later on... -# TODO: Remove this non portable way of linking. -set_target_properties(${MODULE_NAME} PROPERTIES COMPILE_FLAGS "-fPIC") +add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) set(${MODULE_PREFIX}_LIBS ${ZLIB_LIBRARIES} From 0c17eb1a231e9d2c76655d326699040464af21d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Sep 2013 13:50:00 -0400 Subject: [PATCH 167/202] winpr: fix unit tests on Windows --- include/freerdp/channels/rdpdr.h | 44 ---- winpr/include/winpr/credui.h | 1 + winpr/include/winpr/nt.h | 228 ++++++++++++------ winpr/include/winpr/synch.h | 6 + winpr/libwinpr/nt/test/TestNtCreateFile.c | 2 + winpr/libwinpr/nt/test/TestNtCurrentTeb.c | 3 +- winpr/libwinpr/synch/critical.c | 47 ++++ winpr/libwinpr/synch/test/TestSynchCritical.c | 1 - 8 files changed, 215 insertions(+), 117 deletions(-) diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 2d7f6401e..5ed9f7dfc 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -280,50 +280,6 @@ enum FILE_FS_DEVICE_FLAG FILE_DEVICE_SECURE_OPEN = 0x00000100 }; -enum FILE_INFORMATION_CLASS -{ - FileDirectoryInformation = 1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileUnknownInformation1, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation -}; - enum FILE_FS_INFORMATION_CLASS { FileFsVolumeInformation = 1, diff --git a/winpr/include/winpr/credui.h b/winpr/include/winpr/credui.h index b4277906e..5ad1c28d7 100644 --- a/winpr/include/winpr/credui.h +++ b/winpr/include/winpr/credui.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index 6664576bb..1dc82e224 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -87,6 +87,29 @@ #endif +/* Defined in wincred.h, do not redefine */ + +#ifdef _WIN32 + +#include + +#else + +#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006DL) +#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006AL) +#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071L) +#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224L) +#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) +#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388L) +#define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413L) +#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072L) +#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006EL) +#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234L) +#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193L) +#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015BL) + +#endif + #define FACILITY_DEBUGGER 0x1 #define FACILITY_RPC_RUNTIME 0x2 #define FACILITY_RPC_STUBS 0x3 @@ -309,7 +332,7 @@ #define STATUS_INVALID_VIEW_SIZE ((NTSTATUS)0xC000001F) #define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020) #define STATUS_ALREADY_COMMITTED ((NTSTATUS)0xC0000021) -#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022) +//#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023) #define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024) //#define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS)0xC0000025) @@ -380,15 +403,15 @@ #define STATUS_MEMBER_IN_GROUP ((NTSTATUS)0xC0000067) #define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS)0xC0000068) #define STATUS_LAST_ADMIN ((NTSTATUS)0xC0000069) -#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006A) +//#define STATUS_WRONG_PASSWORD ((NTSTATUS)0xC000006A) #define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS)0xC000006B) #define STATUS_PASSWORD_RESTRICTION ((NTSTATUS)0xC000006C) -#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006D) -#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006E) +//#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006D) +//#define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS)0xC000006E) #define STATUS_INVALID_LOGON_HOURS ((NTSTATUS)0xC000006F) #define STATUS_INVALID_WORKSTATION ((NTSTATUS)0xC0000070) -#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071) -#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072) +//#define STATUS_PASSWORD_EXPIRED ((NTSTATUS)0xC0000071) +//#define STATUS_ACCOUNT_DISABLED ((NTSTATUS)0xC0000072) #define STATUS_NONE_MAPPED ((NTSTATUS)0xC0000073) #define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS)0xC0000074) #define STATUS_LUIDS_EXHAUSTED ((NTSTATUS)0xC0000075) @@ -621,7 +644,7 @@ #define STATUS_INTERNAL_DB_ERROR ((NTSTATUS)0xC0000158) #define STATUS_FULLSCREEN_MODE ((NTSTATUS)0xC0000159) #define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS)0xC000015A) -#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015B) +//#define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS)0xC000015B) #define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015C) #define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS)0xC000015D) #define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS)0xC000015E) @@ -674,7 +697,7 @@ #define STATUS_TRUST_FAILURE ((NTSTATUS)0xC0000190) #define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS)0xC0000191) #define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS)0xC0000192) -#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193) +//#define STATUS_ACCOUNT_EXPIRED ((NTSTATUS)0xC0000193) #define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS)0xC0000194) #define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS)0xC0000195) #define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS)0xC0000196) @@ -718,7 +741,7 @@ #define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS)0xC0000221) #define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS)0xC0000222) #define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS)0xC0000223) -#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224) +//#define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS)0xC0000224) #define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225) #define STATUS_NOT_TINY_STREAM ((NTSTATUS)0xC0000226) #define STATUS_RECOVERY_FAILURE ((NTSTATUS)0xC0000227) @@ -734,7 +757,7 @@ #define STATUS_MARSHALL_OVERFLOW ((NTSTATUS)0xC0000231) #define STATUS_INVALID_VARIANT ((NTSTATUS)0xC0000232) #define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS)0xC0000233) -#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234) +//#define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS)0xC0000234) #define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xC0000235) #define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236) #define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS)0xC0000237) @@ -968,7 +991,7 @@ #define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS)0xC0000385) #define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS)0xC0000386) #define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS)0xC0000387) -#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388) +//#define STATUS_DOWNGRADE_DETECTED ((NTSTATUS)0xC0000388) #define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS)0xC0000389) #define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS)0xC000038A) #define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS)0xC000038B) @@ -994,7 +1017,7 @@ #define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS)0xC0000410) #define STATUS_HIBERNATION_FAILURE ((NTSTATUS)0xC0000411) #define STATUS_DELAY_LOAD_FAILED ((NTSTATUS)0xC0000412) -#define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) +//#define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) #define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) #define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) //#define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS)0xC0000417) @@ -1246,6 +1269,71 @@ /* Defined in winternl.h, always define since we do not include this header */ +#ifdef _WIN32 + +/** + * winternl.h contains an incomplete definition of enum FILE_INFORMATION_CLASS + * avoid conflict by prefixing the winternl.h definition by _WINTERNL_ and then + * make a complete definition of enum FILE_INFORMATION_CLASS ourselves. + * + * For more information, refer to [MS-FSCC]: File System Control Codes: + * http://msdn.microsoft.com/en-us/library/cc231987.aspx + */ + +#define _FILE_INFORMATION_CLASS _WINTERNL_FILE_INFORMATION_CLASS +#define FileDirectoryInformation _WINTERNL_FileDirectoryInformation + +#include + +#undef _FILE_INFORMATION_CLASS +#undef FileDirectoryInformation + +enum FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileObjectIdInformation, + FileUnknownInformation1, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileAttributeTagInformation, + FileTrackingInformation, + FileIdBothDirectoryInformation, + FileIdFullDirectoryInformation, + FileValidDataLengthInformation, + FileShortNameInformation +}; + +#else + #define FILE_SUPERSEDE 0x00000000 #define FILE_OPEN 0x00000001 #define FILE_CREATE 0x00000002 @@ -1293,7 +1381,63 @@ #define FILE_EXISTS 0x00000004 #define FILE_DOES_NOT_EXIST 0x00000005 -#ifndef _WIN32 +typedef CONST char *PCSZ; + +typedef struct _STRING +{ + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING; +typedef STRING *PSTRING; + +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; +typedef PSTRING PCANSI_STRING; + +typedef STRING OEM_STRING; +typedef PSTRING POEM_STRING; +typedef CONST STRING* PCOEM_STRING; + +typedef struct _LSA_UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; + +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_FORCE_ACCESS_CHECK 0x00000400L +#define OBJ_VALID_ATTRIBUTES 0x000007F2L + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES; +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef VOID (*PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved); typedef struct _PEB PEB; typedef struct _PEB* PPEB; @@ -1377,64 +1521,6 @@ struct _TEB typedef DWORD ACCESS_MASK; typedef ACCESS_MASK* PACCESS_MASK; -typedef CONST char *PCSZ; - -typedef struct _STRING -{ - USHORT Length; - USHORT MaximumLength; - PCHAR Buffer; -} STRING; -typedef STRING *PSTRING; - -typedef STRING ANSI_STRING; -typedef PSTRING PANSI_STRING; -typedef PSTRING PCANSI_STRING; - -typedef STRING OEM_STRING; -typedef PSTRING POEM_STRING; -typedef CONST STRING* PCOEM_STRING; - -typedef struct _LSA_UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; - -#define OBJ_INHERIT 0x00000002L -#define OBJ_PERMANENT 0x00000010L -#define OBJ_EXCLUSIVE 0x00000020L -#define OBJ_CASE_INSENSITIVE 0x00000040L -#define OBJ_OPENIF 0x00000080L -#define OBJ_OPENLINK 0x00000100L -#define OBJ_KERNEL_HANDLE 0x00000200L -#define OBJ_FORCE_ACCESS_CHECK 0x00000400L -#define OBJ_VALID_ATTRIBUTES 0x000007F2L - -typedef struct _OBJECT_ATTRIBUTES -{ - ULONG Length; - HANDLE RootDirectory; - PUNICODE_STRING ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES; -typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; - -typedef struct _IO_STATUS_BLOCK -{ - union - { - NTSTATUS status; - PVOID Pointer; - }; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef VOID (*PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved); - #ifdef __cplusplus extern "C" { #endif diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index 45373ac00..28d15fa23 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -271,6 +271,12 @@ WINPR_API BOOL CancelWaitableTimer(HANDLE hTimer); #endif +#if ((_WIN32) && (_WIN32_WINNT < 0x0600)) + +WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + +#endif + /* Extended API */ WINPR_API VOID USleep(DWORD dwMicroseconds); diff --git a/winpr/libwinpr/nt/test/TestNtCreateFile.c b/winpr/libwinpr/nt/test/TestNtCreateFile.c index 4dcb876ae..571f733a0 100644 --- a/winpr/libwinpr/nt/test/TestNtCreateFile.c +++ b/winpr/libwinpr/nt/test/TestNtCreateFile.c @@ -5,6 +5,7 @@ int TestNtCreateFile(int argc, char* argv[]) { +#ifndef _WIN32 HANDLE handle; NTSTATUS ntstatus; ULONG CreateOptions; @@ -25,6 +26,7 @@ int TestNtCreateFile(int argc, char* argv[]) ntstatus = NtCreateFile(&handle, DesiredAccess, &attributes, &ioStatusBlock, 0, 0, 0, CreateOptions, 0, 0, 0); RtlFreeUnicodeString(&uString); +#endif return 0; } diff --git a/winpr/libwinpr/nt/test/TestNtCurrentTeb.c b/winpr/libwinpr/nt/test/TestNtCurrentTeb.c index 43f46a77f..719042c70 100644 --- a/winpr/libwinpr/nt/test/TestNtCurrentTeb.c +++ b/winpr/libwinpr/nt/test/TestNtCurrentTeb.c @@ -5,6 +5,7 @@ int TestNtCurrentTeb(int argc, char* argv[]) { +#ifndef _WIN32 PTEB teb; teb = NtCurrentTeb(); @@ -14,7 +15,7 @@ int TestNtCurrentTeb(int argc, char* argv[]) printf("NtCurrentTeb() returned NULL\n"); return -1; } - +#endif return 0; } diff --git a/winpr/libwinpr/synch/critical.c b/winpr/libwinpr/synch/critical.c index a547bd24e..ff419a55f 100644 --- a/winpr/libwinpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -22,6 +22,7 @@ #include "config.h" #endif +#include #include #include #include @@ -233,3 +234,49 @@ VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) } #endif + +#if ((_WIN32) && (_WIN32_WINNT < 0x0600)) + +typedef BOOL (*PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + +static HMODULE g_KERNEL32_Library = NULL; +static BOOL g_InitializeCriticalSectionEx_Detected = FALSE; +static BOOL g_InitializeCriticalSectionEx_Available = FALSE; +static PINITIALIZE_CRITICAL_SECTION_EX_FN g_pInitializeCriticalSectionEx = NULL; + +BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags) +{ + if (!g_InitializeCriticalSectionEx_Detected) + { + g_KERNEL32_Library = LoadLibrary(_T("kernel32.dll")); + + if (g_KERNEL32_Library) + { + g_pInitializeCriticalSectionEx = (PINITIALIZE_CRITICAL_SECTION_EX_FN) + GetProcAddress(g_KERNEL32_Library, "InitializeCriticalSectionEx"); + + g_InitializeCriticalSectionEx_Available = (g_pInitializeCriticalSectionEx) ? TRUE : FALSE; + } + else + { + g_InitializeCriticalSectionEx_Available = FALSE; + } + + g_InitializeCriticalSectionEx_Detected = TRUE; + } + + if (g_InitializeCriticalSectionEx_Available) + { + /* Vista and later */ + return g_pInitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags); + } + else + { + /* Windows XP */ + InitializeCriticalSection(lpCriticalSection); + } + + return TRUE; +} + +#endif diff --git a/winpr/libwinpr/synch/test/TestSynchCritical.c b/winpr/libwinpr/synch/test/TestSynchCritical.c index 6ec5ca284..854e24215 100644 --- a/winpr/libwinpr/synch/test/TestSynchCritical.c +++ b/winpr/libwinpr/synch/test/TestSynchCritical.c @@ -7,7 +7,6 @@ #include #include - #define TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS 500 #define TEST_SYNC_CRITICAL_TEST1_RUNS 4 From e8a8c1cf7f1a7f568113782a4781deddc8f56d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Sep 2013 14:17:00 -0400 Subject: [PATCH 168/202] winpr: fix crashing tests --- winpr/libwinpr/nt/test/TestNtCreateFile.c | 2 +- winpr/libwinpr/synch/critical.c | 4 ++-- winpr/libwinpr/synch/test/TestSynchWaitableTimer.c | 13 +++++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/winpr/libwinpr/nt/test/TestNtCreateFile.c b/winpr/libwinpr/nt/test/TestNtCreateFile.c index 571f733a0..8c1b9fdb5 100644 --- a/winpr/libwinpr/nt/test/TestNtCreateFile.c +++ b/winpr/libwinpr/nt/test/TestNtCreateFile.c @@ -5,7 +5,7 @@ int TestNtCreateFile(int argc, char* argv[]) { -#ifndef _WIN32 +#if 0 HANDLE handle; NTSTATUS ntstatus; ULONG CreateOptions; diff --git a/winpr/libwinpr/synch/critical.c b/winpr/libwinpr/synch/critical.c index ff419a55f..df66f1aae 100644 --- a/winpr/libwinpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -237,7 +237,7 @@ VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) #if ((_WIN32) && (_WIN32_WINNT < 0x0600)) -typedef BOOL (*PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); +typedef BOOL (WINAPI * PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); static HMODULE g_KERNEL32_Library = NULL; static BOOL g_InitializeCriticalSectionEx_Detected = FALSE; @@ -268,7 +268,7 @@ BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwS if (g_InitializeCriticalSectionEx_Available) { /* Vista and later */ - return g_pInitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags); + return (*g_pInitializeCriticalSectionEx)(lpCriticalSection, dwSpinCount, Flags); } else { diff --git a/winpr/libwinpr/synch/test/TestSynchWaitableTimer.c b/winpr/libwinpr/synch/test/TestSynchWaitableTimer.c index 472a412e1..fb8497c60 100644 --- a/winpr/libwinpr/synch/test/TestSynchWaitableTimer.c +++ b/winpr/libwinpr/synch/test/TestSynchWaitableTimer.c @@ -4,11 +4,12 @@ int TestSynchWaitableTimer(int argc, char* argv[]) { + DWORD status; HANDLE timer; LONG period; LARGE_INTEGER due; - timer = CreateWaitableTimer(NULL, TRUE, NULL); + timer = CreateWaitableTimer(NULL, FALSE, NULL); if (!timer) { @@ -24,7 +25,9 @@ int TestSynchWaitableTimer(int argc, char* argv[]) return -1; } - if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0) + status = WaitForSingleObject(timer, INFINITE); + + if (status != WAIT_OBJECT_0) { printf("WaitForSingleObject(timer, INFINITE) failure\n"); return -1; @@ -32,9 +35,11 @@ int TestSynchWaitableTimer(int argc, char* argv[]) printf("Timer Signaled\n"); - if (WaitForSingleObject(timer, 2000) != WAIT_TIMEOUT) + status = WaitForSingleObject(timer, 2000); + + if (status != WAIT_TIMEOUT) { - printf("WaitForSingleObject(timer, 2000) failure\n"); + printf("WaitForSingleObject(timer, 2000) failure: Actual: 0x%04X, Expected: 0x%04X\n", status, WAIT_TIMEOUT); return -1; } From b9a3ff3c85e8c8866227cee78c0fc85ed3dc5f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Sep 2013 15:47:54 -0400 Subject: [PATCH 169/202] winpr: fix build on Linux --- winpr/include/winpr/nt.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index 1dc82e224..a3c15489c 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -1288,6 +1288,8 @@ #undef _FILE_INFORMATION_CLASS #undef FileDirectoryInformation +#endif + enum FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, @@ -1332,7 +1334,7 @@ enum FILE_INFORMATION_CLASS FileShortNameInformation }; -#else +#ifndef _WIN32 #define FILE_SUPERSEDE 0x00000000 #define FILE_OPEN 0x00000001 From e62e78c24b233f173275d6c42a9cc7eb786a6e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 19 Sep 2013 16:25:10 -0400 Subject: [PATCH 170/202] libfreerdp-client: fix registration of static addin table (don't associate it with command-line parsing) --- client/common/client.c | 4 ++++ client/common/cmdline.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/common/client.c b/client/common/client.c index 1c19445b4..14456618c 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -23,8 +23,10 @@ #include +#include #include #include +#include int freerdp_client_common_new(freerdp* instance, rdpContext* context) { @@ -59,6 +61,8 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) context->instance = instance; context->settings = instance->settings; + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + return context; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index d366f739f..88dcc7e45 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1061,8 +1061,6 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin BOOL compatibility; COMMAND_LINE_ARGUMENT_A* arg; - freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); - compatibility = freerdp_client_detect_command_line(argc, argv, &flags); if (compatibility) From 489e375f7b4094ae8d87f81650e9c1cf79baebc3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 20 Sep 2013 09:19:11 +0200 Subject: [PATCH 171/202] Fixed potential memory leak, now always calling WaveConfirm after playing a sample. --- channels/rdpsnd/client/alsa/rdpsnd_alsa.c | 2 -- channels/rdpsnd/client/rdpsnd_main.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index e775e48d3..bfb995c2e 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -613,8 +613,6 @@ static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) wave->wTimeStampB = wave->wTimeStampA + wave->wLatency; //fprintf(stderr, "wTimeStampA: %d wTimeStampB: %d wLatency: %d\n", wave->wTimeStampA, wave->wTimeStampB, wave->wLatency); - - device->WaveConfirm(device, wave); } static COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 5047ed76a..613f16003 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -442,8 +442,8 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) { wave->wTimeStampB = rdpsnd->wTimeStamp + wave->wAudioLength + TIME_DELAY_MS; wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS; - rdpsnd->device->WaveConfirm(rdpsnd->device, wave); } + rdpsnd->device->WaveConfirm(rdpsnd->device, wave); } static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd) From 01b6d5d2292e5406b2b23a4ead981519930b0779 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 20 Sep 2013 10:08:56 +0200 Subject: [PATCH 172/202] Fixed compiler warnings. --- channels/rdpsnd/client/alsa/rdpsnd_alsa.c | 5 ----- channels/rdpsnd/client/pulse/rdpsnd_pulse.c | 3 ++- channels/rdpsnd/client/rdpsnd_main.c | 2 ++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index bfb995c2e..3ab97adc3 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -453,8 +453,6 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value) long volume_max; long volume_left; long volume_right; - int percent_left; - int percent_right; snd_mixer_elem_t* elem; rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device; @@ -464,9 +462,6 @@ static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value) left = (value & 0xFFFF); right = ((value >> 16) & 0xFFFF); - percent_left = (left * 100) / 0xFFFF; - percent_right = (right * 100) / 0xFFFF; - for (elem = snd_mixer_first_elem(alsa->mixer_handle); elem; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index 607645d1e..c44d29113 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -548,9 +548,10 @@ static void rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_pulse_args, flags, pulse, NULL, NULL); + if (status) + return; arg = rdpsnd_pulse_args; - do { if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 613f16003..5fe38457d 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -594,6 +594,8 @@ static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_args, flags, rdpsnd, NULL, NULL); + if (status) + return; arg = rdpsnd_args; From 1c506a3724dab1a2fcac07c23d9c423a37f4a03c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 20 Sep 2013 10:11:05 +0200 Subject: [PATCH 173/202] Fixed CommandLinePArseArgumentsA return value check, only abort if negative. --- channels/rdpsnd/client/alsa/rdpsnd_alsa.c | 2 +- channels/rdpsnd/client/pulse/rdpsnd_pulse.c | 2 +- channels/rdpsnd/client/rdpsnd_main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 3ab97adc3..cb43e4680 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -626,7 +626,7 @@ static int rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_alsa_args, flags, alsa, NULL, NULL); - if (status) + if (status < 0) return status; arg = rdpsnd_alsa_args; diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index c44d29113..cb0bea63d 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -548,7 +548,7 @@ static void rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_pulse_args, flags, pulse, NULL, NULL); - if (status) + if (status < 0) return; arg = rdpsnd_pulse_args; diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 5fe38457d..cda1cf2ce 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -594,7 +594,7 @@ static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, rdpsnd_args, flags, rdpsnd, NULL, NULL); - if (status) + if (status < 0) return; arg = rdpsnd_args; From e841e6068ba39c65606907e7a37579230ef8285f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 20 Sep 2013 14:39:31 -0400 Subject: [PATCH 174/202] winpr: fix inclusion of winternl.h --- winpr/include/winpr/nt.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/winpr/include/winpr/nt.h b/winpr/include/winpr/nt.h index a3c15489c..e369636f6 100644 --- a/winpr/include/winpr/nt.h +++ b/winpr/include/winpr/nt.h @@ -1280,17 +1280,19 @@ * http://msdn.microsoft.com/en-us/library/cc231987.aspx */ -#define _FILE_INFORMATION_CLASS _WINTERNL_FILE_INFORMATION_CLASS +#define FILE_INFORMATION_CLASS _WINTERNL_FILE_INFORMATION_CLASS +#define _FILE_INFORMATION_CLASS _WINTERNL__FILE_INFORMATION_CLASS #define FileDirectoryInformation _WINTERNL_FileDirectoryInformation #include +#undef FILE_INFORMATION_CLASS #undef _FILE_INFORMATION_CLASS #undef FileDirectoryInformation #endif -enum FILE_INFORMATION_CLASS +typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, @@ -1332,7 +1334,7 @@ enum FILE_INFORMATION_CLASS FileIdFullDirectoryInformation, FileValidDataLengthInformation, FileShortNameInformation -}; +} FILE_INFORMATION_CLASS; #ifndef _WIN32 From 16048641f325c195a68b9a316446cd8881c7a6ca Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sat, 21 Sep 2013 16:58:30 +0200 Subject: [PATCH 175/202] Let mac client print command line info as well Only seen when running the actual executable itself, not during open. --- client/Mac/cli/AppDelegate.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m index aec62be91..7348d5912 100644 --- a/client/Mac/cli/AppDelegate.m +++ b/client/Mac/cli/AppDelegate.m @@ -9,6 +9,7 @@ #import "AppDelegate.h" #import "MacFreeRDP/mfreerdp.h" #import "MacFreeRDP/mf_client.h" +#import static AppDelegate* _singleDelegate = nil; void AppDelegate_EmbedWindowEventHandler(void* context, EmbedWindowEventArgs* e); @@ -90,6 +91,7 @@ void AppDelegate_ErrorInfoEventHandler(void* ctx, ErrorInfoEventArgs* e); } status = freerdp_client_parse_command_line(context, argc, argv); + status = freerdp_client_command_line_status_print(context->argc, context->argv, context->settings, status); return status; } From 11912497ea91095284a3fbf8e03e5f9b8f603ed1 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sat, 21 Sep 2013 17:37:39 +0200 Subject: [PATCH 176/202] Make sure windows size follows commandline geometry This adds support for fullscreen mode, which may fail on non lion systems --- client/Mac/MRDPView.m | 51 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index d12f2da3a..6f1ce51f4 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -138,7 +138,21 @@ struct rgba_data e.embed = TRUE; e.handle = (void*) self; PubSub_OnEmbedWindow(context->pubSub, context, &e); - [self setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight]; + + NSScreen *screen = [[NSScreen screens] objectAtIndex:0]; + NSRect screenFrame = [screen frame]; + + if(instance->settings->Fullscreen) + { + instance->settings->DesktopWidth = screenFrame.size.width; + instance->settings->DesktopHeight = screenFrame.size.height; + } + + [self setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight]; + + + if(instance->settings->Fullscreen) + [[self window] toggleFullScreen:nil]; mfc->thread = CreateThread(NULL, 0, mac_client_thread, (void*) context, 0, &mfc->mainThreadId); @@ -748,34 +762,25 @@ DWORD mac_client_thread(void* param) // store current dimensions width = w; height = h; - - // compute difference between window and client area - NSRect outerRect = [[self window] frame]; - NSRect innerRect = [self frame]; - - int widthDiff = outerRect.size.width - innerRect.size.width; - int heightDiff = outerRect.size.height - innerRect.size.height; - - // we are not in RemoteApp mode, disable resizing - outerRect.size.width = w + widthDiff; - outerRect.size.height = h + heightDiff; - [[self window] setMaxSize:outerRect.size]; - [[self window] setMinSize:outerRect.size]; - @try - { - [[self window] setFrame:outerRect display:YES]; - } - @catch (NSException * e) { - NSLog(@"Exception: %@", e); - } - @finally { - } // set client area to specified dimensions + NSRect innerRect; + innerRect.origin.x = 0; + innerRect.origin.y = 0; innerRect.size.width = w; innerRect.size.height = h; [self setFrame:innerRect]; + + // calculate window of same size, but keep position + NSRect outerRect = [[self window] frame]; + outerRect.size = [[self window] frameRectForContentRect:innerRect].size; + + // we are not in RemoteApp mode, disable larger than resolution + [[self window] setContentMaxSize:innerRect.size]; + + // set window to given area + [[self window] setFrame:outerRect display:YES]; } /************************************************************************ From 56672023dbb5c797e9e48c881696463c595e14e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Sep 2013 17:16:49 -0400 Subject: [PATCH 177/202] libwinpr-thread: start implementing CommandLineToArgv --- winpr/include/winpr/thread.h | 11 + winpr/libwinpr/thread/CMakeLists.txt | 5 + winpr/libwinpr/thread/argv.c | 233 ++++++++++++++++++ winpr/libwinpr/thread/process.c | 7 + winpr/libwinpr/thread/test/.gitignore | 3 + winpr/libwinpr/thread/test/CMakeLists.txt | 30 +++ .../thread/test/TestThreadCommandLineToArgv.c | 88 +++++++ 7 files changed, 377 insertions(+) create mode 100644 winpr/libwinpr/thread/argv.c create mode 100644 winpr/libwinpr/thread/test/.gitignore create mode 100644 winpr/libwinpr/thread/test/CMakeLists.txt create mode 100644 winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c diff --git a/winpr/include/winpr/thread.h b/winpr/include/winpr/thread.h index 5fe7adab0..9114a6783 100644 --- a/winpr/include/winpr/thread.h +++ b/winpr/include/winpr/thread.h @@ -117,6 +117,17 @@ WINPR_API DWORD GetCurrentProcessId(void); WINPR_API BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode); +/* Process Argument Vector Parsing */ + +WINPR_API LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs); +WINPR_API LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs); + +#ifdef UNICODE +#define CommandLineToArgv CommandLineToArgvW +#else +#define CommandLineToArgv CommandLineToArgvA +#endif + /* Thread */ #define CREATE_SUSPENDED 0x00000004 diff --git a/winpr/libwinpr/thread/CMakeLists.txt b/winpr/libwinpr/thread/CMakeLists.txt index 2a2f34438..5a6690b6f 100644 --- a/winpr/libwinpr/thread/CMakeLists.txt +++ b/winpr/libwinpr/thread/CMakeLists.txt @@ -19,6 +19,7 @@ set(MODULE_NAME "winpr-thread") set(MODULE_PREFIX "WINPR_THREAD") set(${MODULE_PREFIX}_SRCS + argv.c process.c processor.c thread.c @@ -53,3 +54,7 @@ else() endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c new file mode 100644 index 000000000..040aa8131 --- /dev/null +++ b/winpr/libwinpr/thread/argv.c @@ -0,0 +1,233 @@ +/** + * WinPR: Windows Portable Runtime + * Process Argument Vector Functions + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +#ifndef _WIN32 + +#ifdef HAVE_UNISTD_H +#include +#endif + +/** + * CommandLineToArgvW function: + * http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391/ + * + * CommandLineToArgvW has a special interpretation of backslash characters + * when they are followed by a quotation mark character ("), as follows: + * + * 2n backslashes followed by a quotation mark produce n backslashes followed by a quotation mark. + * (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark. + * n backslashes not followed by a quotation mark simply produce n backslashes. + * + * The address returned by CommandLineToArgvW is the address of the first element in an array of LPWSTR values; + * the number of pointers in this array is indicated by pNumArgs. Each pointer to a null-terminated Unicode + * string represents an individual argument found on the command line. + * + * CommandLineToArgvW allocates a block of contiguous memory for pointers to the argument strings, + * and for the argument strings themselves; the calling application must free the memory used by the + * argument list when it is no longer needed. To free the memory, use a single call to the LocalFree function. + */ + +/** + * Parsing C++ Command-Line Arguments: + * http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft + * + * Microsoft C/C++ startup code uses the following rules when + * interpreting arguments given on the operating system command line: + * + * Arguments are delimited by white space, which is either a space or a tab. + * + * The caret character (^) is not recognized as an escape character or delimiter. + * The character is handled completely by the command-line parser in the operating + * system before being passed to the argv array in the program. + * + * A string surrounded by double quotation marks ("string") is interpreted as a + * single argument, regardless of white space contained within. A quoted string + * can be embedded in an argument. + * + * A double quotation mark preceded by a backslash (\") is interpreted as a + * literal double quotation mark character ("). + * + * Backslashes are interpreted literally, unless they immediately + * precede a double quotation mark. + * + * If an even number of backslashes is followed by a double quotation mark, + * one backslash is placed in the argv array for every pair of backslashes, + * and the double quotation mark is interpreted as a string delimiter. + * + * If an odd number of backslashes is followed by a double quotation mark, + * one backslash is placed in the argv array for every pair of backslashes, + * and the double quotation mark is "escaped" by the remaining backslash, + * causing a literal double quotation mark (") to be placed in argv. + * + */ + +LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) +{ + char* p; + int index; + int length; + char* pBeg; + char* pEnd; + char* buffer; + char* pOutput; + int numArgs; + LPSTR* pArgs; + int maxNumArgs; + int maxBufferSize; + int currentIndex; + int cmdLineLength; + + if (!lpCmdLine) + return NULL; + + if (!pNumArgs) + return NULL; + + pArgs = NULL; + numArgs = 0; + cmdLineLength = strlen(lpCmdLine); + + if (!strstr(lpCmdLine, "\\\"")) + { + /* Simplified case: only literal backslashes */ + + maxNumArgs = 1; + currentIndex = 0; + p = (char*) lpCmdLine; + + while (currentIndex < cmdLineLength - 1) + { + index = strcspn(p, " \t"); + + currentIndex += (index + 1); + p = (char*) &lpCmdLine[currentIndex]; + + maxNumArgs++; + } + + maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); + + buffer = (char*) malloc(maxBufferSize); + + if (!buffer) + return NULL; + + ZeroMemory(buffer, maxBufferSize); + + pArgs = (LPSTR*) buffer; + pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; + + numArgs = 0; + currentIndex = 0; + p = (char*) lpCmdLine; + + while (currentIndex < cmdLineLength) + { + pBeg = pEnd = p; + + index = strcspn(p, " \t\"\0"); + + if (p[index] != '"') + { + /* no whitespace escaped with double quotes */ + + p = &p[index + 1]; + pEnd = p; + + length = (pEnd - pBeg); + + CopyMemory(pOutput, pBeg, length); + pOutput[length] = '\0'; + pArgs[numArgs++] = pOutput; + pOutput += (length + 1); + } + else + { + p = &p[index + 1]; + + index = strcspn(p, "\"\0"); + + if (p[index] != '"') + { + printf("CommandLineToArgvA parsing error: uneven number of unescaped double quotes!\n"); + } + + if (p[index] == '\0') + { + p = &p[index + 1]; + pEnd = p; + } + else + { + p = &p[index + 1]; + index = strcspn(p, " \t\0"); + p = &p[index + 1]; + pEnd = p; + } + + length = 0; + pArgs[numArgs++] = pOutput; + + while (pBeg < pEnd) + { + if (*pBeg != '"') + { + *pOutput = *pBeg; + pOutput++; + length++; + } + + pBeg++; + } + + *pOutput = '\0'; + pOutput++; + } + + while ((*p == ' ') || (*p == '\t')) + p++; + + currentIndex = (p - lpCmdLine); + } + } + else + { + /* TODO: handle escaping of double quotes */ + } + + *pNumArgs = numArgs; + + return pArgs; +} + +LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs) +{ + return NULL; +} + +#endif diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 76c4f127e..3d5c977df 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -63,6 +63,13 @@ BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_AT LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { + int status = 0; + + if (!lpApplicationName) + return FALSE; + + status = execve(lpApplicationName, NULL, NULL); + return TRUE; } diff --git a/winpr/libwinpr/thread/test/.gitignore b/winpr/libwinpr/thread/test/.gitignore new file mode 100644 index 000000000..5b53e5e49 --- /dev/null +++ b/winpr/libwinpr/thread/test/.gitignore @@ -0,0 +1,3 @@ +TestThread +TestThread.c + diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt new file mode 100644 index 000000000..8d03a256e --- /dev/null +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -0,0 +1,30 @@ + +set(MODULE_NAME "TestThread") +set(MODULE_PREFIX "TEST_THREAD") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestThreadCommandLineToArgv.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-thread) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c new file mode 100644 index 000000000..827b53512 --- /dev/null +++ b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c @@ -0,0 +1,88 @@ + +#include +#include +#include + +const char* test_args_line_1 = "abc d e"; + +const char* test_args_list_1[] = +{ + "abc", + "d", + "e", + NULL +}; + +const char* test_args_line_2 = "abc \t def"; + +const char* test_args_list_2[] = +{ + "abc", + "def", + NULL +}; + +const char* test_args_line_3 = "\"abc\" d e"; + +const char* test_args_list_3[] = +{ + "abc", + "d", + "e", + NULL +}; + +const char* test_args_line_4 = "a\\\\b d\"e f\"g h"; + +const char* test_args_list_4[] = +{ + "a\\\\b", + "de fg", + "h", + NULL +}; + +const char* test_args_line_5 = "a\\\\\\\"b c d"; + +const char* test_args_list_5[] = +{ + "a\\\"b", + "c", + "d", + NULL +}; + +static int test_command_line_parsing_case(const char* line, const char** list) +{ + int i; + LPSTR* pArgs; + int pNumArgs; + + pArgs = NULL; + pNumArgs = 0; + + printf("Parsing: %s\n", line); + + pArgs = CommandLineToArgvA(line, &pNumArgs); + + printf("pNumArgs: %d\n", pNumArgs); + + for (i = 0; i < pNumArgs; i++) + { + printf("argv[%d] = %s\n", i, pArgs[i]); + } + + return 0; +} + +int TestThreadCommandLineToArgv(int argc, char* argv[]) +{ + test_command_line_parsing_case(test_args_line_1, test_args_list_1); + test_command_line_parsing_case(test_args_line_2, test_args_list_2); + test_command_line_parsing_case(test_args_line_3, test_args_list_3); + test_command_line_parsing_case(test_args_line_4, test_args_list_4); + //test_command_line_parsing_case(test_args_line_5, test_args_list_5); + + return 0; +} + From 1c112474c64c77ff2ffd98c88d093eaab84e2a56 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sun, 22 Sep 2013 00:07:27 +0200 Subject: [PATCH 178/202] Correct handling of mouse scrolling for osx Setup server to scroll 1 line at a time to match osx scrolling speed. --- client/Mac/MRDPView.m | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 6f1ce51f4..b89599246 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -486,20 +486,23 @@ DWORD mac_client_thread(void* param) NSPoint loc = [event locationInWindow]; int x = (int) loc.x; int y = (int) loc.y; - + y = height - y; flags = PTR_FLAGS_WHEEL; - - if ([event deltaY] < 0) - flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; - else - flags |= 0x0078; - - x += (int) [event deltaX]; - y += (int) [event deltaY]; - - instance->input->MouseEvent(instance->input, flags, x, y); + + /* 1 event = 120 units */ + int units = [event deltaY] * 120; + + /* send out all accumulated rotations */ + while(units != 0) + { + /* limit to maximum value in WheelRotationMask (9bit signed value) */ + int step = MIN(MAX(-256, units), 255); + + instance->input->MouseEvent(instance->input, flags | ((UINT16)step & WheelRotationMask), x, y); + units -= step; + } } /** ********************************************************************* From 83e124f909c1891913a2efdff0f60c75dd808ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Sep 2013 19:49:00 -0400 Subject: [PATCH 179/202] libwinpr-thread: partial support for character escaping in CommandLineToArgv --- winpr/libwinpr/thread/argv.c | 241 ++++++++++++------ .../thread/test/TestThreadCommandLineToArgv.c | 13 +- 2 files changed, 174 insertions(+), 80 deletions(-) diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 040aa8131..01c887a38 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -101,6 +101,8 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) int maxBufferSize; int currentIndex; int cmdLineLength; + LPSTR lpEscapedChars; + LPSTR lpEscapedCmdLine; if (!lpCmdLine) return NULL; @@ -110,115 +112,196 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) pArgs = NULL; numArgs = 0; + + lpEscapedCmdLine = NULL; cmdLineLength = strlen(lpCmdLine); - if (!strstr(lpCmdLine, "\\\"")) + lpEscapedChars = (char*) malloc(cmdLineLength + 1); + ZeroMemory(lpEscapedChars, cmdLineLength + 1); + + if (strstr(lpCmdLine, "\\\"")) { - /* Simplified case: only literal backslashes */ + int i, n; + + lpEscapedCmdLine = (char*) malloc(cmdLineLength + 1); - maxNumArgs = 1; - currentIndex = 0; p = (char*) lpCmdLine; + pOutput = (char*) lpEscapedCmdLine; - while (currentIndex < cmdLineLength - 1) + pBeg = strstr(lpCmdLine, "\\\""); + pEnd = pBeg + 2; + + while (pBeg >= lpCmdLine) { - index = strcspn(p, " \t"); + if (*pBeg != '\\') + { + pBeg++; + break; + } - currentIndex += (index + 1); - p = (char*) &lpCmdLine[currentIndex]; - - maxNumArgs++; + pBeg--; } - maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); + n = (pEnd - pBeg) - 1; - buffer = (char*) malloc(maxBufferSize); + length = (pBeg - lpCmdLine); + CopyMemory(pOutput, p, length); + pOutput += length; + p += length; - if (!buffer) - return NULL; - - ZeroMemory(buffer, maxBufferSize); - - pArgs = (LPSTR*) buffer; - pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; - - numArgs = 0; - currentIndex = 0; - p = (char*) lpCmdLine; - - while (currentIndex < cmdLineLength) + for (i = 0; i < (n / 2); i++) { - pBeg = pEnd = p; + *pOutput = '\\'; + pOutput++; + } + p += n + 1; + + if ((n % 2) != 0) + lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\'; + + *pOutput = '"'; + pOutput++; + + length = cmdLineLength - (pEnd - lpCmdLine); + CopyMemory(pOutput, p, length); + pOutput += length; + p += length; + + *pOutput = '\0'; + pOutput++; + + lpCmdLine = (LPCSTR) lpEscapedCmdLine; + cmdLineLength = strlen(lpCmdLine); + + //printf("EscapedCmdLine: %s\n", lpEscapedCmdLine); + } + + maxNumArgs = 1; + currentIndex = 0; + p = (char*) lpCmdLine; + + while (currentIndex < cmdLineLength - 1) + { + index = strcspn(p, " \t"); + + currentIndex += (index + 1); + p = (char*) &lpCmdLine[currentIndex]; + + maxNumArgs++; + } + + maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); + + buffer = (char*) malloc(maxBufferSize); + + if (!buffer) + return NULL; + + ZeroMemory(buffer, maxBufferSize); + + pArgs = (LPSTR*) buffer; + pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; + + numArgs = 0; + currentIndex = 0; + p = (char*) lpCmdLine; + + while (currentIndex < cmdLineLength) + { + pBeg = pEnd = p; + + while (1) + { index = strcspn(p, " \t\"\0"); + if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine])) + { + p = &p[index + 1]; + continue; + } + + break; + } + + if (p[index] != '"') + { + /* no whitespace escaped with double quotes */ + + p = &p[index + 1]; + pEnd = p; + + length = (pEnd - pBeg); + + CopyMemory(pOutput, pBeg, length); + pOutput[length] = '\0'; + pArgs[numArgs++] = pOutput; + pOutput += (length + 1); + } + else + { + p = &p[index + 1]; + + while (1) + { + index = strcspn(p, "\"\0"); + + if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine])) + { + p = &p[index + 1]; + continue; + } + + break; + } + if (p[index] != '"') { - /* no whitespace escaped with double quotes */ + printf("CommandLineToArgvA parsing error: uneven number of unescaped double quotes!\n"); + } + if (p[index] == '\0') + { p = &p[index + 1]; pEnd = p; - - length = (pEnd - pBeg); - - CopyMemory(pOutput, pBeg, length); - pOutput[length] = '\0'; - pArgs[numArgs++] = pOutput; - pOutput += (length + 1); } else { p = &p[index + 1]; - - index = strcspn(p, "\"\0"); - - if (p[index] != '"') - { - printf("CommandLineToArgvA parsing error: uneven number of unescaped double quotes!\n"); - } - - if (p[index] == '\0') - { - p = &p[index + 1]; - pEnd = p; - } - else - { - p = &p[index + 1]; - index = strcspn(p, " \t\0"); - p = &p[index + 1]; - pEnd = p; - } - - length = 0; - pArgs[numArgs++] = pOutput; - - while (pBeg < pEnd) - { - if (*pBeg != '"') - { - *pOutput = *pBeg; - pOutput++; - length++; - } - - pBeg++; - } - - *pOutput = '\0'; - pOutput++; + index = strcspn(p, " \t\0"); + p = &p[index + 1]; + pEnd = p; } - while ((*p == ' ') || (*p == '\t')) - p++; + length = 0; + pArgs[numArgs++] = pOutput; - currentIndex = (p - lpCmdLine); + while (pBeg < pEnd) + { + if (*pBeg != '"') + { + *pOutput = *pBeg; + pOutput++; + length++; + } + + pBeg++; + } + + *pOutput = '\0'; + pOutput++; } + + while ((*p == ' ') || (*p == '\t')) + p++; + + currentIndex = (p - lpCmdLine); } - else - { - /* TODO: handle escaping of double quotes */ - } + + if (lpEscapedCmdLine) + free(lpEscapedCmdLine); + + free(lpEscapedChars); *pNumArgs = numArgs; diff --git a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c index 827b53512..2e17765af 100644 --- a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c +++ b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c @@ -52,6 +52,16 @@ const char* test_args_list_5[] = NULL }; +const char* test_args_line_6 = "a\\\\\\\\\"b c\" d e"; + +const char* test_args_list_6[] = +{ + "a\\\\b c", + "d", + "e", + NULL +}; + static int test_command_line_parsing_case(const char* line, const char** list) { int i; @@ -81,7 +91,8 @@ int TestThreadCommandLineToArgv(int argc, char* argv[]) test_command_line_parsing_case(test_args_line_2, test_args_list_2); test_command_line_parsing_case(test_args_line_3, test_args_list_3); test_command_line_parsing_case(test_args_line_4, test_args_list_4); - //test_command_line_parsing_case(test_args_line_5, test_args_list_5); + test_command_line_parsing_case(test_args_line_5, test_args_list_5); + test_command_line_parsing_case(test_args_line_6, test_args_list_6); return 0; } From bb9db9720486339ec788b49a539f432e6671dc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Sep 2013 20:05:14 -0400 Subject: [PATCH 180/202] libwinpr-thread: improve CommandLineToArgv completeness --- winpr/libwinpr/thread/argv.c | 73 +++++++++++-------- winpr/libwinpr/thread/test/CMakeLists.txt | 2 +- .../thread/test/TestThreadCommandLineToArgv.c | 16 ++++ 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 01c887a38..1369742d1 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -122,59 +122,70 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) if (strstr(lpCmdLine, "\\\"")) { int i, n; + char* pLastEnd = NULL; lpEscapedCmdLine = (char*) malloc(cmdLineLength + 1); p = (char*) lpCmdLine; + pLastEnd = (char*) lpCmdLine; pOutput = (char*) lpEscapedCmdLine; - pBeg = strstr(lpCmdLine, "\\\""); - pEnd = pBeg + 2; - - while (pBeg >= lpCmdLine) + while (p < &lpCmdLine[cmdLineLength]) { - if (*pBeg != '\\') + pBeg = strstr(p, "\\\""); + + if (!pBeg) { - pBeg++; + length = strlen(p); + CopyMemory(pOutput, p, length); + pOutput += length; + p += length; + break; } - pBeg--; - } + pEnd = pBeg + 2; - n = (pEnd - pBeg) - 1; + while (pBeg >= lpCmdLine) + { + if (*pBeg != '\\') + { + pBeg++; + break; + } - length = (pBeg - lpCmdLine); - CopyMemory(pOutput, p, length); - pOutput += length; - p += length; + pBeg--; + } - for (i = 0; i < (n / 2); i++) - { - *pOutput = '\\'; + n = (pEnd - pBeg) - 1; + + length = (pBeg - pLastEnd); + CopyMemory(pOutput, p, length); + pOutput += length; + p += length; + + for (i = 0; i < (n / 2); i++) + { + *pOutput = '\\'; + pOutput++; + } + + p += n + 1; + + if ((n % 2) != 0) + lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\'; + + *pOutput = '"'; pOutput++; + + pLastEnd = p; } - p += n + 1; - - if ((n % 2) != 0) - lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\'; - - *pOutput = '"'; - pOutput++; - - length = cmdLineLength - (pEnd - lpCmdLine); - CopyMemory(pOutput, p, length); - pOutput += length; - p += length; - *pOutput = '\0'; pOutput++; lpCmdLine = (LPCSTR) lpEscapedCmdLine; cmdLineLength = strlen(lpCmdLine); - - //printf("EscapedCmdLine: %s\n", lpEscapedCmdLine); } maxNumArgs = 1; diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt index 8d03a256e..f05e033ed 100644 --- a/winpr/libwinpr/thread/test/CMakeLists.txt +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -16,7 +16,7 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-thread) + MODULES winpr-thread winpr-heap) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c index 2e17765af..e4573d91f 100644 --- a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c +++ b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c @@ -62,6 +62,19 @@ const char* test_args_list_6[] = NULL }; +const char* test_args_line_7 = "a\\\\\\\\\"b c\" d e f\\\\\\\\\"g h\" i j"; + +const char* test_args_list_7[] = +{ + "a\\\\b c", + "d", + "e", + "f\\\\g h", + "i", + "j", + NULL +}; + static int test_command_line_parsing_case(const char* line, const char** list) { int i; @@ -82,6 +95,8 @@ static int test_command_line_parsing_case(const char* line, const char** list) printf("argv[%d] = %s\n", i, pArgs[i]); } + HeapFree(GetProcessHeap(), 0, pArgs); + return 0; } @@ -93,6 +108,7 @@ int TestThreadCommandLineToArgv(int argc, char* argv[]) test_command_line_parsing_case(test_args_line_4, test_args_list_4); test_command_line_parsing_case(test_args_line_5, test_args_list_5); test_command_line_parsing_case(test_args_line_6, test_args_list_6); + test_command_line_parsing_case(test_args_line_7, test_args_list_7); return 0; } From 8d142eb85f64446f01a66515bc2b26ae6b8c19e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 22 Sep 2013 17:23:00 -0400 Subject: [PATCH 181/202] libwinpr-thread: initial CreateProcess() implementation --- winpr/libwinpr/handle/handle.c | 9 +++ winpr/libwinpr/handle/handle.h | 15 ++--- winpr/libwinpr/synch/wait.c | 13 +++++ winpr/libwinpr/thread/argv.c | 21 +++---- winpr/libwinpr/thread/process.c | 57 +++++++++++++++++-- winpr/libwinpr/thread/test/CMakeLists.txt | 3 +- .../thread/test/TestThreadCommandLineToArgv.c | 31 ++++++---- .../thread/test/TestThreadCreateProcess.c | 52 +++++++++++++++++ winpr/libwinpr/thread/thread.h | 10 ++++ 9 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 winpr/libwinpr/thread/test/TestThreadCreateProcess.c diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index 31ac5641b..7830be31d 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -52,6 +52,15 @@ BOOL CloseHandle(HANDLE hObject) return TRUE; } + else if (Type == HANDLE_TYPE_PROCESS) + { + WINPR_PROCESS* process; + + process = (WINPR_PROCESS*) Object; + free(process); + + return TRUE; + } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index 75faae4ea..9ba8982b5 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -23,13 +23,14 @@ #include #define HANDLE_TYPE_NONE 0 -#define HANDLE_TYPE_THREAD 1 -#define HANDLE_TYPE_EVENT 2 -#define HANDLE_TYPE_MUTEX 3 -#define HANDLE_TYPE_SEMAPHORE 4 -#define HANDLE_TYPE_TIMER 5 -#define HANDLE_TYPE_NAMED_PIPE 6 -#define HANDLE_TYPE_ANONYMOUS_PIPE 7 +#define HANDLE_TYPE_PROCESS 1 +#define HANDLE_TYPE_THREAD 2 +#define HANDLE_TYPE_EVENT 3 +#define HANDLE_TYPE_MUTEX 4 +#define HANDLE_TYPE_SEMAPHORE 5 +#define HANDLE_TYPE_TIMER 6 +#define HANDLE_TYPE_NAMED_PIPE 7 +#define HANDLE_TYPE_ANONYMOUS_PIPE 8 #define WINPR_HANDLE_DEF() \ ULONG Type diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 8fab17203..8727831e2 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -43,6 +43,8 @@ #ifndef _WIN32 +#include + #include "../handle/handle.h" #include "../pipe/pipe.h" @@ -102,6 +104,17 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } + else if (Type == HANDLE_TYPE_PROCESS) + { + WINPR_PROCESS* process; + + process = (WINPR_PROCESS*) Object; + + if (waitpid(process->pid, &(process->status), 0) != -1) + { + return WAIT_FAILED; + } + } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 1369742d1..041216131 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -101,7 +101,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) int maxBufferSize; int currentIndex; int cmdLineLength; - LPSTR lpEscapedChars; + BOOL* lpEscapedChars; LPSTR lpEscapedCmdLine; if (!lpCmdLine) @@ -116,15 +116,15 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) lpEscapedCmdLine = NULL; cmdLineLength = strlen(lpCmdLine); - lpEscapedChars = (char*) malloc(cmdLineLength + 1); - ZeroMemory(lpEscapedChars, cmdLineLength + 1); + lpEscapedChars = (BOOL*) malloc((cmdLineLength + 1) * sizeof(BOOL)); + ZeroMemory(lpEscapedChars, (cmdLineLength + 1) * sizeof(BOOL)); if (strstr(lpCmdLine, "\\\"")) { int i, n; char* pLastEnd = NULL; - lpEscapedCmdLine = (char*) malloc(cmdLineLength + 1); + lpEscapedCmdLine = (char*) malloc((cmdLineLength + 1) * sizeof(char)); p = (char*) lpCmdLine; pLastEnd = (char*) lpCmdLine; @@ -173,7 +173,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) p += n + 1; if ((n % 2) != 0) - lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\'; + lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE; *pOutput = '"'; pOutput++; @@ -188,7 +188,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) cmdLineLength = strlen(lpCmdLine); } - maxNumArgs = 1; + maxNumArgs = 2; currentIndex = 0; p = (char*) lpCmdLine; @@ -240,7 +240,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) /* no whitespace escaped with double quotes */ p = &p[index + 1]; - pEnd = p; + pEnd = p - 1; length = (pEnd - pBeg); @@ -274,14 +274,14 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) if (p[index] == '\0') { p = &p[index + 1]; - pEnd = p; + pEnd = p - 1; } else { p = &p[index + 1]; index = strcspn(p, " \t\0"); p = &p[index + 1]; - pEnd = p; + pEnd = p - 1; } length = 0; @@ -312,7 +312,8 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) if (lpEscapedCmdLine) free(lpEscapedCmdLine); - free(lpEscapedChars); + if (lpEscapedChars) + free(lpEscapedChars); *pNumArgs = numArgs; diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 3d5c977df..347b2aca9 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -55,20 +55,69 @@ #include #endif +#include + +#include +#include +#include + #include -typedef void *(*pthread_start_routine)(void*); +#include "thread.h" + +#include "../handle/handle.h" BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { - int status = 0; + pid_t pid; + char* envp; + int status; + int numArgs; + LPSTR* pArgs; + WINPR_THREAD* thread; + WINPR_PROCESS* process; - if (!lpApplicationName) + pid = 0; + numArgs = 0; + + pArgs = CommandLineToArgvA(lpCommandLine, &numArgs); + + envp = NULL; + + status = posix_spawnp(&pid, pArgs[0], NULL, NULL, pArgs, &envp); + + if (status != 0) return FALSE; - status = execve(lpApplicationName, NULL, NULL); + process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS)); + + if (!process) + return FALSE; + + ZeroMemory(process, sizeof(WINPR_PROCESS)); + + WINPR_HANDLE_SET_TYPE(process, HANDLE_TYPE_PROCESS); + + process->pid = pid; + process->status = 0; + + thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD)); + + ZeroMemory(thread, sizeof(WINPR_THREAD)); + + if (!thread) + return FALSE; + + WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); + + thread->mainProcess = TRUE; + + lpProcessInformation->hProcess = (HANDLE) process; + lpProcessInformation->hThread = (HANDLE) thread; + lpProcessInformation->dwProcessId = (DWORD) pid; + lpProcessInformation->dwThreadId = (DWORD) pid; return TRUE; } diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt index f05e033ed..1f6de6f2b 100644 --- a/winpr/libwinpr/thread/test/CMakeLists.txt +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -5,7 +5,8 @@ set(MODULE_PREFIX "TEST_THREAD") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS - TestThreadCommandLineToArgv.c) + TestThreadCommandLineToArgv.c + TestThreadCreateProcess.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c index e4573d91f..d863ba59b 100644 --- a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c +++ b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c @@ -3,69 +3,76 @@ #include #include -const char* test_args_line_1 = "abc d e"; +const char* test_args_line_1 = "app.exe abc d e"; const char* test_args_list_1[] = { + "app.exe", "abc", "d", "e", NULL }; -const char* test_args_line_2 = "abc \t def"; +const char* test_args_line_2 = "app.exe abc \t def"; const char* test_args_list_2[] = { + "app.exe", "abc", "def", NULL }; -const char* test_args_line_3 = "\"abc\" d e"; +const char* test_args_line_3 = "app.exe \"abc\" d e"; const char* test_args_list_3[] = { + "app.exe", "abc", "d", "e", NULL }; -const char* test_args_line_4 = "a\\\\b d\"e f\"g h"; +const char* test_args_line_4 = "app.exe a\\\\b d\"e f\"g h"; const char* test_args_list_4[] = { + "app.exe", "a\\\\b", "de fg", "h", NULL }; -const char* test_args_line_5 = "a\\\\\\\"b c d"; +const char* test_args_line_5 = "app.exe a\\\\\\\"b c d"; const char* test_args_list_5[] = { + "app.exe", "a\\\"b", "c", "d", NULL }; -const char* test_args_line_6 = "a\\\\\\\\\"b c\" d e"; +const char* test_args_line_6 = "app.exe a\\\\\\\\\"b c\" d e"; const char* test_args_list_6[] = { + "app.exe", "a\\\\b c", "d", "e", NULL }; -const char* test_args_line_7 = "a\\\\\\\\\"b c\" d e f\\\\\\\\\"g h\" i j"; +const char* test_args_line_7 = "app.exe a\\\\\\\\\"b c\" d e f\\\\\\\\\"g h\" i j"; const char* test_args_list_7[] = { + "app.exe", "a\\\\b c", "d", "e", @@ -79,18 +86,18 @@ static int test_command_line_parsing_case(const char* line, const char** list) { int i; LPSTR* pArgs; - int pNumArgs; + int numArgs; pArgs = NULL; - pNumArgs = 0; + numArgs = 0; printf("Parsing: %s\n", line); - pArgs = CommandLineToArgvA(line, &pNumArgs); + pArgs = CommandLineToArgvA(line, &numArgs); - printf("pNumArgs: %d\n", pNumArgs); + printf("pNumArgs: %d\n", numArgs); - for (i = 0; i < pNumArgs; i++) + for (i = 0; i < numArgs; i++) { printf("argv[%d] = %s\n", i, pArgs[i]); } diff --git a/winpr/libwinpr/thread/test/TestThreadCreateProcess.c b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c new file mode 100644 index 000000000..889fb5cb4 --- /dev/null +++ b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c @@ -0,0 +1,52 @@ + +#include +#include +#include +#include +#include + +int TestThreadCreateProcess(int argc, char* argv[]) +{ + BOOL status; + LPCTSTR lpApplicationName; + LPTSTR lpCommandLine; + LPSECURITY_ATTRIBUTES lpProcessAttributes; + LPSECURITY_ATTRIBUTES lpThreadAttributes; + BOOL bInheritHandles; + DWORD dwCreationFlags; + LPVOID lpEnvironment; + LPCTSTR lpCurrentDirectory; + STARTUPINFO StartupInfo; + PROCESS_INFORMATION ProcessInformation; + + lpApplicationName = NULL; + lpCommandLine = _T("ls -l /"); + lpProcessAttributes = NULL; + lpThreadAttributes = NULL; + bInheritHandles = FALSE; + dwCreationFlags = 0; + lpEnvironment = NULL; + lpCurrentDirectory = NULL; + ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); + StartupInfo.cb = sizeof(STARTUPINFO); + ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION)); + + status = CreateProcess(lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + &StartupInfo, + &ProcessInformation); + + WaitForSingleObject(ProcessInformation.hProcess, INFINITE); + + CloseHandle(ProcessInformation.hProcess); + CloseHandle(ProcessInformation.hThread); + + return 0; +} + diff --git a/winpr/libwinpr/thread/thread.h b/winpr/libwinpr/thread/thread.h index c13ff5278..6652ed310 100644 --- a/winpr/libwinpr/thread/thread.h +++ b/winpr/libwinpr/thread/thread.h @@ -35,6 +35,7 @@ struct winpr_thread WINPR_HANDLE_DEF(); BOOL started; + BOOL mainProcess; DWORD dwExitCode; pthread_t thread; SIZE_T dwStackSize; @@ -45,6 +46,15 @@ struct winpr_thread }; typedef struct winpr_thread WINPR_THREAD; +struct winpr_process +{ + WINPR_HANDLE_DEF(); + + pid_t pid; + int status; +}; +typedef struct winpr_process WINPR_PROCESS; + #endif #endif /* WINPR_THREAD_PRIVATE_H */ From 9a08171b88faec388ebbf9604981a657c24b84f1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 23 Sep 2013 09:11:23 +0200 Subject: [PATCH 182/202] Dumping stream now. --- .../smartcard/client/smartcard_operations.c | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 1fe48bf5d..e87571c51 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1546,6 +1546,23 @@ finish: return status; } +static void Stream_Dump(wStream *s) +{ + size_t size = Stream_GetRemainingLength(s); + int i; + + fprintf(stderr, "-------------------------- Start [%s] [%zd] ------------------------", + __func__, size); + for(i=0; ipointer[i]); + if (i % 80 == 0) + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + fprintf(stderr, "-------------------------- End [%s] ------------------------", __func__); +} + static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) { LONG status; @@ -1607,6 +1624,18 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = handle_RedirHandleRef(scard, irp, &inlen, &hContext, &hCard); if (status) goto finish; + + DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength,=%d, ptrSendBuffer,=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL,=%d, cbRecvLength=%d", + irp->input, ioSendPci.rq->dwProtocol, + irp->input, ioSendPci.rq->cbPciLength, + irp->input, pioSendPciBufferPtr, + irp->input, cbSendLength, + irp->input, ptrSendBuffer, + irp->input, ptrIoRecvPciBuffer, + irp->input, recvBufferIsNULL, + irp->input, cbRecvLength); + + Stream_Dump(irp->input); /* Check, if there is data available from the ipSendPci element */ if (pioSendPciBufferPtr) @@ -1690,8 +1719,10 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) Stream_Read_UINT32(irp->input, linkedLen); Stream_Read_UINT16(irp->input, ioRecvPci.rq->dwProtocol); Stream_Read_UINT16(irp->input, ioRecvPci.rq->cbPciLength); - - if (linkedLen != ioSendPci.rq->cbPciLength) + + /* Just check for too few bytes, there may be more actual + * data than is used due to padding. */ + if (linkedLen < ioSendPci.rq->cbPciLength) { DEBUG_WARN("SCARD_IO_REQUEST with invalid extra byte length %d [%d]", ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); @@ -1716,7 +1747,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; ioRecvPci.v = tmp; - Stream_Read(irp->input, &ioRecvPci.rq[1], linkedLen); + Stream_Read(irp->input, &ioRecvPci.rq[1], ioRecvPci.rq->cbPciLength); pPioRecvPci = ioRecvPci.rq; } From 2a9610bbfeeb153ca1902b1bac7a9fad7e2ed863 Mon Sep 17 00:00:00 2001 From: Daryl Poe Date: Tue, 20 Aug 2013 12:00:36 -0600 Subject: [PATCH 183/202] apply glyph fragment offset after fragment (cherry picked from commit eb2f3a02b465a59d29578248f25d2c2726592150) --- libfreerdp/cache/glyph.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index e8650fcd7..8d346190c 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -48,6 +48,7 @@ void update_process_glyph(rdpContext* context, BYTE* data, int* index, if ((ulCharInc == 0) && (!(flAccel & SO_CHAR_INC_EQUAL_BM_BASE))) { + /* Contrary to fragments, the offset is added before the glyph. */ (*index)++; offset = data[*index]; @@ -111,6 +112,12 @@ void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 leng if (fragments != NULL) { + for (n = 0; n < (int) size; n++) + { + update_process_glyph(context, fragments, &n, &x, &y, cacheId, ulCharInc, flAccel); + } + + /* Contrary to glyphs, the offset is added after the fragment. */ if ((ulCharInc == 0) && (!(flAccel & SO_CHAR_INC_EQUAL_BM_BASE))) { if (flAccel & SO_VERTICAL) @@ -118,11 +125,6 @@ void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 leng else x += data[index + 2]; } - - for (n = 0; n < (int) size; n++) - { - update_process_glyph(context, fragments, &n, &x, &y, cacheId, ulCharInc, flAccel); - } } index += (index + 2 < (int) length) ? 3 : 2; From fee219168a02616cbc1198a399f98ffef401151e Mon Sep 17 00:00:00 2001 From: Daryl Poe Date: Wed, 18 Sep 2013 17:16:48 -0600 Subject: [PATCH 184/202] send RDP_NEG_REQ also in the case of a null server certificate (cherry picked from commit afec6957c4245aa2091c3ab5f7e67f07e0c3cf9b) --- libfreerdp/core/nego.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index de082bc75..2e97d059d 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -798,6 +798,7 @@ void nego_process_negotiation_failure(rdpNego* nego, wStream* s) case SSL_NOT_ALLOWED_BY_SERVER: DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER"); + nego->sendNegoData = TRUE; break; case SSL_CERT_NOT_ON_SERVER: @@ -940,6 +941,7 @@ void nego_init(rdpNego* nego) nego->transport->ReceiveCallback = nego_recv; nego->transport->ReceiveExtra = (void*) nego; nego->cookie_max_length = DEFAULT_COOKIE_MAX_LENGTH; + nego->sendNegoData = FALSE; nego->flags = 0; } From 1148a8c9fd91ebeaffcd4c295b5e4fc813c38381 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 23 Sep 2013 15:10:06 +0200 Subject: [PATCH 185/202] Fixed length check, now just assuring data read is available and ignoring padding length. --- .../smartcard/client/smartcard_operations.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index e87571c51..4b32d8375 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1625,15 +1625,15 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (status) goto finish; - DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength,=%d, ptrSendBuffer,=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL,=%d, cbRecvLength=%d", - irp->input, ioSendPci.rq->dwProtocol, - irp->input, ioSendPci.rq->cbPciLength, - irp->input, pioSendPciBufferPtr, - irp->input, cbSendLength, - irp->input, ptrSendBuffer, - irp->input, ptrIoRecvPciBuffer, - irp->input, recvBufferIsNULL, - irp->input, cbRecvLength); + DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength=%d, ptrSendBuffer,=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL=%d, cbRecvLength=%d", + ioSendPci.rq->dwProtocol, + ioSendPci.rq->cbPciLength, + pioSendPciBufferPtr, + cbSendLength, + ptrSendBuffer, + ptrIoRecvPciBuffer, + recvBufferIsNULL, + cbRecvLength); Stream_Dump(irp->input); @@ -1731,9 +1731,9 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } linkedLen -= 4; - if (Stream_GetRemainingLength(irp->input) < linkedLen) + if (Stream_GetRemainingLength(irp->input) < ioSendPci.rq->cbPciLength) { - DEBUG_WARN("length violation %d [%d]", linkedLen, + DEBUG_WARN("length violation %d [%d]", ioSendPci.rq->cbPciLength, Stream_GetRemainingLength(irp->input)); status = SCARD_F_INTERNAL_ERROR; goto finish; From 3d2754e8eda0473c0e8772359e310fcc8aa8b6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Sep 2013 14:44:59 -0400 Subject: [PATCH 186/202] libwinpr-environment: implement required functions for CreateProcess --- winpr/include/winpr/environment.h | 7 ++ winpr/include/winpr/thread.h | 1 + winpr/include/winpr/wtypes.h | 4 +- winpr/libwinpr/environment/CMakeLists.txt | 4 + winpr/libwinpr/environment/environment.c | 76 ++++++++++++++++++- winpr/libwinpr/environment/test/.gitignore | 3 + .../libwinpr/environment/test/CMakeLists.txt | 31 ++++++++ .../TestEnvironmentGetEnvironmentStrings.c | 28 +++++++ .../TestEnvironmentSetEnvironmentVariable.c | 30 ++++++++ winpr/libwinpr/synch/wait.c | 2 + winpr/libwinpr/thread/process.c | 72 +++++++++++++++++- winpr/libwinpr/thread/test/CMakeLists.txt | 2 +- .../thread/test/TestThreadCreateProcess.c | 15 +++- winpr/libwinpr/thread/thread.h | 1 + 14 files changed, 268 insertions(+), 8 deletions(-) create mode 100644 winpr/libwinpr/environment/test/.gitignore create mode 100644 winpr/libwinpr/environment/test/CMakeLists.txt create mode 100644 winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c create mode 100644 winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c diff --git a/winpr/include/winpr/environment.h b/winpr/include/winpr/environment.h index b77ab71bf..0df30f5e0 100644 --- a/winpr/include/winpr/environment.h +++ b/winpr/include/winpr/environment.h @@ -54,6 +54,11 @@ WINPR_API DWORD GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD n WINPR_API BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue); WINPR_API BOOL SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue); +/** + * A brief history of the GetEnvironmentStrings functions: + * http://blogs.msdn.com/b/oldnewthing/archive/2013/01/17/10385718.aspx + */ + WINPR_API LPCH GetEnvironmentStrings(VOID); WINPR_API LPWCH GetEnvironmentStringsW(VOID); @@ -79,6 +84,7 @@ WINPR_API BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock); #define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathW #define GetEnvironmentVariable GetEnvironmentVariableW #define SetEnvironmentVariable SetEnvironmentVariableW +#define GetEnvironmentStrings GetEnvironmentStringsW #define SetEnvironmentStrings SetEnvironmentStringsW #define ExpandEnvironmentStrings ExpandEnvironmentStringsW #define FreeEnvironmentStrings FreeEnvironmentStringsW @@ -90,6 +96,7 @@ WINPR_API BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock); #define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathA #define GetEnvironmentVariable GetEnvironmentVariableA #define SetEnvironmentVariable SetEnvironmentVariableA +#define GetEnvironmentStringsA GetEnvironmentStrings #define SetEnvironmentStrings SetEnvironmentStringsA #define ExpandEnvironmentStrings ExpandEnvironmentStringsA #define FreeEnvironmentStrings FreeEnvironmentStringsA diff --git a/winpr/include/winpr/thread.h b/winpr/include/winpr/thread.h index 9114a6783..6d2444dce 100644 --- a/winpr/include/winpr/thread.h +++ b/winpr/include/winpr/thread.h @@ -111,6 +111,7 @@ WINPR_API BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LP #endif DECLSPEC_NORETURN WINPR_API VOID ExitProcess(UINT uExitCode); +WINPR_API BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode); WINPR_API HANDLE _GetCurrentProcess(void); WINPR_API DWORD GetCurrentProcessId(void); diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index d3639d771..034c7e608 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -108,10 +108,10 @@ typedef signed int LONG32; typedef signed __int64 LONG64; #endif -typedef CHAR* PSTR, *LPSTR, *LPCH; +typedef CHAR *PSTR, *LPSTR, *LPCH; typedef const CHAR *LPCSTR,*PCSTR; -typedef WCHAR* LPWSTR, *PWSTR, *LPWCH; +typedef WCHAR *LPWSTR, *PWSTR, *LPWCH; typedef const WCHAR *LPCWSTR,*PCWSTR; typedef unsigned __int64 QWORD; diff --git a/winpr/libwinpr/environment/CMakeLists.txt b/winpr/libwinpr/environment/CMakeLists.txt index 831fa7879..6f5ab2c77 100644 --- a/winpr/libwinpr/environment/CMakeLists.txt +++ b/winpr/libwinpr/environment/CMakeLists.txt @@ -38,3 +38,7 @@ else() endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/environment/environment.c b/winpr/libwinpr/environment/environment.c index 058232d3c..f1bcf56fb 100644 --- a/winpr/libwinpr/environment/environment.c +++ b/winpr/libwinpr/environment/environment.c @@ -157,6 +157,25 @@ DWORD GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize) BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue) { + int length; + char* envstr; + + if (!lpName) + return FALSE; + + if (lpValue) + { + length = strlen(lpName) + strlen(lpValue) + 1; + envstr = (char*) malloc(length + 1); + sprintf_s(envstr, length + 1, "%s=%s", lpName, lpValue); + envstr[length] = '\0'; + putenv(envstr); + } + else + { + unsetenv(lpName); + } + return TRUE; } @@ -165,9 +184,61 @@ BOOL SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue) return TRUE; } +/** + * GetEnvironmentStrings function: + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187/ + * + * The GetEnvironmentStrings function returns a pointer to a block of memory + * that contains the environment variables of the calling process (both the + * system and the user environment variables). Each environment block contains + * the environment variables in the following format: + * + * Var1=Value1\0 + * Var2=Value2\0 + * Var3=Value3\0 + * ... + * VarN=ValueN\0\0 + */ + +extern char** environ; + LPCH GetEnvironmentStrings(VOID) { - return NULL; + char* p; + int offset; + int length; + char** envp; + DWORD cchEnvironmentBlock; + LPCH lpszEnvironmentBlock; + + offset = 0; + envp = environ; + + cchEnvironmentBlock = 128; + lpszEnvironmentBlock = (LPCH) malloc(cchEnvironmentBlock * sizeof(CHAR)); + + while (*envp) + { + length = strlen(*envp); + + while ((offset + length + 8) > cchEnvironmentBlock) + { + cchEnvironmentBlock *= 2; + lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR)); + } + + p = &(lpszEnvironmentBlock[offset]); + + CopyMemory(p, *envp, length * sizeof(CHAR)); + p[length] = '\0'; + + offset += (length + 1); + envp++; + } + + lpszEnvironmentBlock[offset] = '\0'; + + return lpszEnvironmentBlock; } LPWCH GetEnvironmentStringsW(VOID) @@ -197,6 +268,9 @@ DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize) BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock) { + if (lpszEnvironmentBlock) + free(lpszEnvironmentBlock); + return TRUE; } diff --git a/winpr/libwinpr/environment/test/.gitignore b/winpr/libwinpr/environment/test/.gitignore new file mode 100644 index 000000000..47921403a --- /dev/null +++ b/winpr/libwinpr/environment/test/.gitignore @@ -0,0 +1,3 @@ +TestEnvironment +TestEnvironment.c + diff --git a/winpr/libwinpr/environment/test/CMakeLists.txt b/winpr/libwinpr/environment/test/CMakeLists.txt new file mode 100644 index 000000000..5b9ec3fd9 --- /dev/null +++ b/winpr/libwinpr/environment/test/CMakeLists.txt @@ -0,0 +1,31 @@ + +set(MODULE_NAME "TestEnvironment") +set(MODULE_PREFIX "TEST_ENVIRONMENT") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestEnvironmentGetEnvironmentStrings.c + TestEnvironmentSetEnvironmentVariable.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-environment) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c new file mode 100644 index 000000000..0aa0435d5 --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c @@ -0,0 +1,28 @@ + +#include +#include +#include +#include + +int TestEnvironmentGetEnvironmentStrings(int argc, char* argv[]) +{ + TCHAR* p; + int length; + LPTCH lpszEnvironmentBlock; + + lpszEnvironmentBlock = GetEnvironmentStrings(); + + p = (TCHAR*) lpszEnvironmentBlock; + + while (p[0] && p[1]) + { + printf("%s\n", p); + length = strlen(p); + p += (length + 1); + } + + FreeEnvironmentStrings(lpszEnvironmentBlock); + + return 0; +} + diff --git a/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c b/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c new file mode 100644 index 000000000..a80010d19 --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c @@ -0,0 +1,30 @@ + +#include +#include +#include +#include + +int TestEnvironmentSetEnvironmentVariable(int argc, char* argv[]) +{ + DWORD nSize; + LPSTR lpBuffer; + + SetEnvironmentVariableA("WINPR_TEST_VARIABLE", "WINPR_TEST_VALUE"); + + nSize = GetEnvironmentVariableA("WINPR_TEST_VARIABLE", NULL, 0); + + lpBuffer = (LPSTR) malloc(nSize); + nSize = GetEnvironmentVariableA("WINPR_TEST_VARIABLE", lpBuffer, nSize); + + printf("GetEnvironmentVariableA(WINPR_TEST_VARIABLE) = %s\n" , lpBuffer); + + if (strcmp(lpBuffer, "WINPR_TEST_VALUE") != 0) + { + return -1; + } + + free(lpBuffer); + + return 0; +} + diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 8727831e2..823a07fd8 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -114,6 +114,8 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { return WAIT_FAILED; } + + process->dwExitCode = (DWORD) process->status; } else if (Type == HANDLE_TYPE_MUTEX) { diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 347b2aca9..9c9e9c333 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -56,6 +56,8 @@ #endif #include +#include +#include #include #include @@ -67,26 +69,72 @@ #include "../handle/handle.h" +char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) +{ + char* p; + int index; + int count; + int length; + char** envp = NULL; + + count = 0; + p = (char*) lpszEnvironmentBlock; + + while (p[0] && p[1]) + { + length = strlen(p); + p += (length + 1); + count++; + } + + index = 0; + p = (char*) lpszEnvironmentBlock; + + envp = (char**) malloc(sizeof(char*) * (count + 1)); + envp[count] = NULL; + + while (p[0] && p[1]) + { + length = strlen(p); + envp[index] = _strdup(p); + p += (length + 1); + index++; + } + + return envp; +} + BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { pid_t pid; - char* envp; int status; int numArgs; LPSTR* pArgs; + char** envp; WINPR_THREAD* thread; WINPR_PROCESS* process; + LPTCH lpszEnvironmentBlock; pid = 0; + envp = NULL; numArgs = 0; + lpszEnvironmentBlock = NULL; pArgs = CommandLineToArgvA(lpCommandLine, &numArgs); - envp = NULL; + if (lpEnvironment) + { + envp = EnvironmentBlockToEnvpA(lpEnvironment); + } + else + { + lpszEnvironmentBlock = GetEnvironmentStrings(); + envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock); + } - status = posix_spawnp(&pid, pArgs[0], NULL, NULL, pArgs, &envp); + status = posix_spawnp(&pid, pArgs[0], NULL, NULL, pArgs, envp); if (status != 0) return FALSE; @@ -102,6 +150,7 @@ BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_AT process->pid = pid; process->status = 0; + process->dwExitCode = 0; thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD)); @@ -148,6 +197,23 @@ DECLSPEC_NORETURN VOID ExitProcess(UINT uExitCode) } +BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) +{ + WINPR_PROCESS* process; + + if (!hProcess) + return FALSE; + + if (!lpExitCode) + return FALSE; + + process = (WINPR_PROCESS*) hProcess; + + *lpExitCode = process->dwExitCode; + + return TRUE; +} + HANDLE _GetCurrentProcess(VOID) { return NULL; diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt index 1f6de6f2b..9ca3a9ac0 100644 --- a/winpr/libwinpr/thread/test/CMakeLists.txt +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -17,7 +17,7 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-thread winpr-heap) + MODULES winpr-thread winpr-heap winpr-environment) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/winpr/libwinpr/thread/test/TestThreadCreateProcess.c b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c index 889fb5cb4..b57b0a1f9 100644 --- a/winpr/libwinpr/thread/test/TestThreadCreateProcess.c +++ b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c @@ -4,10 +4,12 @@ #include #include #include +#include int TestThreadCreateProcess(int argc, char* argv[]) { BOOL status; + DWORD exitCode; LPCTSTR lpApplicationName; LPTSTR lpCommandLine; LPSECURITY_ATTRIBUTES lpProcessAttributes; @@ -18,14 +20,19 @@ int TestThreadCreateProcess(int argc, char* argv[]) LPCTSTR lpCurrentDirectory; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; + LPTCH lpszEnvironmentBlock; + + lpszEnvironmentBlock = GetEnvironmentStrings(); lpApplicationName = NULL; - lpCommandLine = _T("ls -l /"); + //lpCommandLine = _T("ls -l /"); + lpCommandLine = _T("printenv"); lpProcessAttributes = NULL; lpThreadAttributes = NULL; bInheritHandles = FALSE; dwCreationFlags = 0; lpEnvironment = NULL; + lpEnvironment = lpszEnvironmentBlock; lpCurrentDirectory = NULL; ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); StartupInfo.cb = sizeof(STARTUPINFO); @@ -42,8 +49,14 @@ int TestThreadCreateProcess(int argc, char* argv[]) &StartupInfo, &ProcessInformation); + FreeEnvironmentStrings(lpszEnvironmentBlock); + WaitForSingleObject(ProcessInformation.hProcess, INFINITE); + status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode); + + printf("Process exited with code: %d\n", exitCode); + CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hThread); diff --git a/winpr/libwinpr/thread/thread.h b/winpr/libwinpr/thread/thread.h index 6652ed310..67fc3d831 100644 --- a/winpr/libwinpr/thread/thread.h +++ b/winpr/libwinpr/thread/thread.h @@ -52,6 +52,7 @@ struct winpr_process pid_t pid; int status; + DWORD dwExitCode; }; typedef struct winpr_process WINPR_PROCESS; From b4ac2ef8c83ffceb2e2d6d79d1affa4a35ad3054 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 23 Sep 2013 23:29:55 +0200 Subject: [PATCH 187/202] osx build: make 10.7 default deployment target 10.6 isn't shipped with xcode > 4.4 anymore per default If older/newer deployment target is required it can be set with -DCMAKE_OSX_DEPLOYMENT_TARGET=10.x --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18ef1e858..85446b9da 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,7 +248,7 @@ if(APPLE) set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES) else() if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET MATCHES "") - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6 CACHE STRING "OSX deployment target" FORCE) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "OSX deployment target" FORCE) endif() if(NOT DEFINED CMAKE_OSX_ARCHITECTURES) From 979ed1b75615859a09d77aee70e2f4f8ea4e9bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Sep 2013 18:10:21 -0400 Subject: [PATCH 188/202] libwinpr-pipe: implement WaitNamedPipe --- winpr/libwinpr/pipe/pipe.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 144979e86..4c984a3db 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -225,7 +225,36 @@ BOOL TransactNamedPipe(HANDLE hNamedPipe, LPVOID lpInBuffer, DWORD nInBufferSize BOOL WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut) { - return TRUE; + BOOL status; + DWORD nWaitTime; + char* lpFilePath; + DWORD dwSleepInterval; + + if (!lpNamedPipeName) + return FALSE; + + lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpNamedPipeName); + + if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT) + nTimeOut = 50; + + nWaitTime = 0; + status = TRUE; + dwSleepInterval = 10; + + while (!PathFileExistsA(lpFilePath)) + { + Sleep(dwSleepInterval); + nWaitTime += dwSleepInterval; + + if (nWaitTime >= nTimeOut) + { + status = FALSE; + break; + } + } + + return status; } BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut) From b647b5bfc92da74bcc6d5b0f01dafc5ae2c500ae Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 24 Sep 2013 01:41:18 +0200 Subject: [PATCH 189/202] some CMakeLists format fixes --- CMakeLists.txt | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85446b9da..0a6e0f26c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,7 @@ if(WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNICODE -D_UNICODE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=0x0501") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") endif() if(IOS) @@ -240,26 +240,26 @@ endif() # Mac OS X if(APPLE) - if(IOS) - if (NOT FREERDP_IOS_EXTERNAL_SSL_PATH) - message(STATUS "FREERDP_IOS_EXTERNAL_SSL_PATH not set! Required if openssl is not found in the iOS SDK (which usually isn't") - endif() - set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH}) - set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES) - else() + if(IOS) + if (NOT FREERDP_IOS_EXTERNAL_SSL_PATH) + message(STATUS "FREERDP_IOS_EXTERNAL_SSL_PATH not set! Required if openssl is not found in the iOS SDK (which usually isn't") + endif() + set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH}) + set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES) + else(IOS) if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET MATCHES "") - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "OSX deployment target" FORCE) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "OSX deployment target" FORCE) endif() if(NOT DEFINED CMAKE_OSX_ARCHITECTURES) set(CMAKE_OSX_ARCHITECTURES i386 x86_64) endif() - if(IS_DIRECTORY /opt/local/include) - include_directories(/opt/local/include) - link_directories(/opt/local/lib) - endif() - endif() + if(IS_DIRECTORY /opt/local/include) + include_directories(/opt/local/include) + link_directories(/opt/local/lib) + endif() + endif(IOS) # Temporarily disabled, causes the cmake script to be reexecuted, causing the compilation to fail. # Workaround: specify the parameter in the command-line @@ -267,11 +267,11 @@ if(APPLE) # set(CMAKE_C_COMPILER "clang") # endif() - if (WITH_VERBOSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v") - endif() -endif() + if (WITH_VERBOSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v") + endif() +endif(APPLE) # Android if(ANDROID) From 47b18ec841bdb15bd56a32736232c6ca259cbf89 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 24 Sep 2013 01:43:12 +0200 Subject: [PATCH 190/202] osx build: don't set deployment target If a deployment target is set within CMakeLists.txt detection might fail if CMAKE_OSX_SYSROOT isn't set. In case no deployment target is specified the latest available SDK is used as deployment target and sysroot is set accordingly. An other deployment target can still be set with -DCMAKE_OSX_DEPLOYMENT_TARGET=10.x when running cmake for the first time or can be overwritten in cmake cache later on. --- CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a6e0f26c..0473b719e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,10 +247,6 @@ if(APPLE) set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH}) set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES) else(IOS) - if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET MATCHES "") - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "OSX deployment target" FORCE) - endif() - if(NOT DEFINED CMAKE_OSX_ARCHITECTURES) set(CMAKE_OSX_ARCHITECTURES i386 x86_64) endif() From 0506bd1ac61d39e38f0c75d2f3ca1f93a3638b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 23 Sep 2013 22:39:28 -0400 Subject: [PATCH 191/202] libwinpr-security: initial stub module --- winpr/include/winpr/sspicli.h | 42 +++++ winpr/include/winpr/thread.h | 24 +++ winpr/libwinpr/security/CMakeLists.txt | 44 ++++++ winpr/libwinpr/security/ModuleOptions.cmake | 8 + winpr/libwinpr/security/module.def | 2 + winpr/libwinpr/security/security.c | 144 ++++++++++++++++++ winpr/libwinpr/security/test/.gitignore | 3 + winpr/libwinpr/security/test/CMakeLists.txt | 30 ++++ .../security/test/TestSecurityToken.c | 10 ++ winpr/libwinpr/sspicli/sspicli.c | 33 +++- winpr/libwinpr/thread/process.c | 28 ++++ 11 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 winpr/libwinpr/security/CMakeLists.txt create mode 100644 winpr/libwinpr/security/ModuleOptions.cmake create mode 100644 winpr/libwinpr/security/module.def create mode 100644 winpr/libwinpr/security/security.c create mode 100644 winpr/libwinpr/security/test/.gitignore create mode 100644 winpr/libwinpr/security/test/CMakeLists.txt create mode 100644 winpr/libwinpr/security/test/TestSecurityToken.c diff --git a/winpr/include/winpr/sspicli.h b/winpr/include/winpr/sspicli.h index 30869a1ab..017643dcb 100644 --- a/winpr/include/winpr/sspicli.h +++ b/winpr/include/winpr/sspicli.h @@ -28,6 +28,30 @@ #ifndef _WIN32 +#define LOGON32_LOGON_INTERACTIVE 2 +#define LOGON32_LOGON_NETWORK 3 +#define LOGON32_LOGON_BATCH 4 +#define LOGON32_LOGON_SERVICE 5 +#define LOGON32_LOGON_UNLOCK 7 +#define LOGON32_LOGON_NETWORK_CLEARTEXT 8 +#define LOGON32_LOGON_NEW_CREDENTIALS 9 + +#define LOGON32_PROVIDER_DEFAULT 0 +#define LOGON32_PROVIDER_WINNT35 1 +#define LOGON32_PROVIDER_WINNT40 2 +#define LOGON32_PROVIDER_WINNT50 3 +#define LOGON32_PROVIDER_VIRTUAL 4 + +typedef struct _QUOTA_LIMITS +{ + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; +} QUOTA_LIMITS, *PQUOTA_LIMITS; + typedef enum { /* An unknown name type */ @@ -79,6 +103,20 @@ typedef enum extern "C" { #endif +WINPR_API BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken); + +WINPR_API BOOL LogonUserW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken); + +WINPR_API BOOL LogonUserExA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, + PVOID* ppProfileBuffer, LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits); + +WINPR_API BOOL LogonUserExW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, + PVOID* ppProfileBuffer, LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits); + WINPR_API BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize); WINPR_API BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize); @@ -87,8 +125,12 @@ WINPR_API BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuff #endif #ifdef UNICODE +#define LogonUser LogonUserW +#define LogonUserEx LogonUserExW #define GetUserNameEx GetUserNameExW #else +#define LogonUser LogonUserA +#define LogonUserEx LogonUserExA #define GetUserNameEx GetUserNameExA #endif diff --git a/winpr/include/winpr/thread.h b/winpr/include/winpr/thread.h index 6d2444dce..4603ed8b1 100644 --- a/winpr/include/winpr/thread.h +++ b/winpr/include/winpr/thread.h @@ -86,6 +86,10 @@ typedef LPSTARTUPINFOA LPSTARTUPINFO; /* Process */ +#define LOGON_WITH_PROFILE 0x00000001 +#define LOGON_NETCREDENTIALS_ONLY 0x00000002 +#define LOGON_ZERO_PASSWORD_BUFFER 0x80000000 + WINPR_API BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); @@ -102,12 +106,32 @@ WINPR_API BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LP LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); +WINPR_API BOOL CreateProcessWithLogonA(LPCSTR lpUsername, LPCSTR lpDomain, LPCSTR lpPassword, DWORD dwLogonFlags, + LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); + +WINPR_API BOOL CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, + LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); + +WINPR_API BOOL CreateProcessWithTokenA(HANDLE hToken, DWORD dwLogonFlags, + LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); + +WINPR_API BOOL CreateProcessWithTokenW(HANDLE hToken, DWORD dwLogonFlags, + LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); + #ifdef UNICODE #define CreateProcess CreateProcessW #define CreateProcessAsUser CreateProcessAsUserW +#define CreateProcessWithLogon CreateProcessWithLogonW +#define CreateProcessWithToken CreateProcessWithTokenW #else #define CreateProcess CreateProcessA #define CreateProcessAsUser CreateProcessAsUserA +#define CreateProcessWithLogon CreateProcessWithLogonA +#define CreateProcessWithToken CreateProcessWithTokenA #endif DECLSPEC_NORETURN WINPR_API VOID ExitProcess(UINT uExitCode); diff --git a/winpr/libwinpr/security/CMakeLists.txt b/winpr/libwinpr/security/CMakeLists.txt new file mode 100644 index 000000000..0985854e2 --- /dev/null +++ b/winpr/libwinpr/security/CMakeLists.txt @@ -0,0 +1,44 @@ +# WinPR: Windows Portable Runtime +# libwinpr-security cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-security") +set(MODULE_PREFIX "WINPR_SECURITY") + +set(${MODULE_PREFIX}_SRCS + security.c) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +if(MONOLITHIC_BUILD) + +else() + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/security/ModuleOptions.cmake b/winpr/libwinpr/security/ModuleOptions.cmake new file mode 100644 index 000000000..66fa71ac9 --- /dev/null +++ b/winpr/libwinpr/security/ModuleOptions.cmake @@ -0,0 +1,8 @@ + +set(MINWIN_LAYER "1") +set(MINWIN_GROUP "security") +set(MINWIN_MAJOR_VERSION "2") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "base") +set(MINWIN_LONG_NAME "Base Security Functions") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") diff --git a/winpr/libwinpr/security/module.def b/winpr/libwinpr/security/module.def new file mode 100644 index 000000000..9857be66b --- /dev/null +++ b/winpr/libwinpr/security/module.def @@ -0,0 +1,2 @@ +LIBRARY "libwinpr-security" +EXPORTS diff --git a/winpr/libwinpr/security/security.c b/winpr/libwinpr/security/security.c new file mode 100644 index 000000000..d958e0e15 --- /dev/null +++ b/winpr/libwinpr/security/security.c @@ -0,0 +1,144 @@ +/** + * WinPR: Windows Portable Runtime + * Base Security Functions + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include + +/** + * api-ms-win-security-base-l1-2-0.dll: + * + * AccessCheck + * AccessCheckAndAuditAlarmW + * AccessCheckByType + * AccessCheckByTypeAndAuditAlarmW + * AccessCheckByTypeResultList + * AccessCheckByTypeResultListAndAuditAlarmByHandleW + * AccessCheckByTypeResultListAndAuditAlarmW + * AddAccessAllowedAce + * AddAccessAllowedAceEx + * AddAccessAllowedObjectAce + * AddAccessDeniedAce + * AddAccessDeniedAceEx + * AddAccessDeniedObjectAce + * AddAce + * AddAuditAccessAce + * AddAuditAccessAceEx + * AddAuditAccessObjectAce + * AddMandatoryAce + * AddResourceAttributeAce + * AddScopedPolicyIDAce + * AdjustTokenGroups + * AdjustTokenPrivileges + * AllocateAndInitializeSid + * AllocateLocallyUniqueId + * AreAllAccessesGranted + * AreAnyAccessesGranted + * CheckTokenCapability + * CheckTokenMembership + * CheckTokenMembershipEx + * ConvertToAutoInheritPrivateObjectSecurity + * CopySid + * CreatePrivateObjectSecurity + * CreatePrivateObjectSecurityEx + * CreatePrivateObjectSecurityWithMultipleInheritance + * CreateRestrictedToken + * CreateWellKnownSid + * DeleteAce + * DestroyPrivateObjectSecurity + * DuplicateToken + * DuplicateTokenEx + * EqualDomainSid + * EqualPrefixSid + * EqualSid + * FindFirstFreeAce + * FreeSid + * GetAce + * GetAclInformation + * GetAppContainerAce + * GetCachedSigningLevel + * GetFileSecurityW + * GetKernelObjectSecurity + * GetLengthSid + * GetPrivateObjectSecurity + * GetSecurityDescriptorControl + * GetSecurityDescriptorDacl + * GetSecurityDescriptorGroup + * GetSecurityDescriptorLength + * GetSecurityDescriptorOwner + * GetSecurityDescriptorRMControl + * GetSecurityDescriptorSacl + * GetSidIdentifierAuthority + * GetSidLengthRequired + * GetSidSubAuthority + * GetSidSubAuthorityCount + * GetTokenInformation + * GetWindowsAccountDomainSid + * ImpersonateAnonymousToken + * ImpersonateLoggedOnUser + * ImpersonateSelf + * InitializeAcl + * InitializeSecurityDescriptor + * InitializeSid + * IsTokenRestricted + * IsValidAcl + * IsValidSecurityDescriptor + * IsValidSid + * IsWellKnownSid + * MakeAbsoluteSD + * MakeSelfRelativeSD + * MapGenericMask + * ObjectCloseAuditAlarmW + * ObjectDeleteAuditAlarmW + * ObjectOpenAuditAlarmW + * ObjectPrivilegeAuditAlarmW + * PrivilegeCheck + * PrivilegedServiceAuditAlarmW + * QuerySecurityAccessMask + * RevertToSelf + * SetAclInformation + * SetCachedSigningLevel + * SetFileSecurityW + * SetKernelObjectSecurity + * SetPrivateObjectSecurity + * SetPrivateObjectSecurityEx + * SetSecurityAccessMask + * SetSecurityDescriptorControl + * SetSecurityDescriptorDacl + * SetSecurityDescriptorGroup + * SetSecurityDescriptorOwner + * SetSecurityDescriptorRMControl + * SetSecurityDescriptorSacl + * SetTokenInformation + */ + +#ifndef _WIN32 + + + +#endif + diff --git a/winpr/libwinpr/security/test/.gitignore b/winpr/libwinpr/security/test/.gitignore new file mode 100644 index 000000000..1763e12b0 --- /dev/null +++ b/winpr/libwinpr/security/test/.gitignore @@ -0,0 +1,3 @@ +TestSecurity +TestSecurity.c + diff --git a/winpr/libwinpr/security/test/CMakeLists.txt b/winpr/libwinpr/security/test/CMakeLists.txt new file mode 100644 index 000000000..9365b1c66 --- /dev/null +++ b/winpr/libwinpr/security/test/CMakeLists.txt @@ -0,0 +1,30 @@ + +set(MODULE_NAME "TestSecurity") +set(MODULE_PREFIX "TEST_SECURITY") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestSecurityToken.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-security) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/security/test/TestSecurityToken.c b/winpr/libwinpr/security/test/TestSecurityToken.c new file mode 100644 index 000000000..ccddf72ba --- /dev/null +++ b/winpr/libwinpr/security/test/TestSecurityToken.c @@ -0,0 +1,10 @@ + +#include +#include +#include + +int TestSecurityToken(int argc, char* argv[]) +{ + return 0; +} + diff --git a/winpr/libwinpr/sspicli/sspicli.c b/winpr/libwinpr/sspicli/sspicli.c index 6a820b2a2..0bad74088 100644 --- a/winpr/libwinpr/sspicli/sspicli.c +++ b/winpr/libwinpr/sspicli/sspicli.c @@ -30,6 +30,8 @@ * EnumerateSecurityPackagesW * GetUserNameExW * ImportSecurityContextA + * LogonUser + * LogonUserEx * LogonUserExExW * SspiCompareAuthIdentities * SspiCopyAuthIdentity @@ -52,9 +54,38 @@ #ifndef _WIN32 -#include #include +#ifdef HAVE_UNISTD_H +#include +#endif + +BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken) +{ + return TRUE; +} + +BOOL LogonUserW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken) +{ + return TRUE; +} + +BOOL LogonUserExA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, + PVOID* ppProfileBuffer, LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits) +{ + return TRUE; +} + +BOOL LogonUserExW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, + DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, + PVOID* ppProfileBuffer, LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits) +{ + return TRUE; +} + BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize) { int length; diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 9c9e9c333..012edd382 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -192,6 +192,34 @@ BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCom return TRUE; } +BOOL CreateProcessWithLogonA(LPCSTR lpUsername, LPCSTR lpDomain, LPCSTR lpPassword, DWORD dwLogonFlags, + LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) +{ + return TRUE; +} + +BOOL CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, + LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) +{ + return TRUE; +} + +BOOL CreateProcessWithTokenA(HANDLE hToken, DWORD dwLogonFlags, + LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) +{ + return TRUE; +} + +BOOL CreateProcessWithTokenW(HANDLE hToken, DWORD dwLogonFlags, + LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) +{ + return TRUE; +} + DECLSPEC_NORETURN VOID ExitProcess(UINT uExitCode) { From 4a77f12b32067ec6c326ca9cf9e303099386a9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 24 Sep 2013 00:07:48 -0400 Subject: [PATCH 192/202] libwinpr-security: expand stubs --- winpr/include/winpr/security.h | 343 ++++++++++++++++++++++++++++- winpr/libwinpr/handle/handle.c | 15 ++ winpr/libwinpr/handle/handle.h | 1 + winpr/libwinpr/security/security.c | 2 +- winpr/libwinpr/security/security.h | 43 ++++ winpr/libwinpr/sspicli/sspicli.c | 37 ++++ winpr/libwinpr/thread/process.c | 23 +- 7 files changed, 455 insertions(+), 9 deletions(-) create mode 100644 winpr/libwinpr/security/security.h diff --git a/winpr/include/winpr/security.h b/winpr/include/winpr/security.h index 13a49cb28..4ad7d4d4f 100644 --- a/winpr/include/winpr/security.h +++ b/winpr/include/winpr/security.h @@ -32,11 +32,344 @@ #include -#define SECURITY_MANDATORY_UNTRUSTED_RID 0x0000 -#define SECURITY_MANDATORY_LOW_RID 0x1000 -#define SECURITY_MANDATORY_MEDIUM_RID 0x2000 -#define SECURITY_MANDATORY_HIGH_RID 0x3000 -#define SECURITY_MANDATORY_SYSTEM_RID 0x4000 +#define ANYSIZE_ARRAY 1 + +typedef enum _SECURITY_IMPERSONATION_LEVEL +{ + SecurityAnonymous, + SecurityIdentification, + SecurityImpersonation, + SecurityDelegation +} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; + +#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation +#define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous +#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation +#define VALID_IMPERSONATION_LEVEL(L) (((L) >= SECURITY_MIN_IMPERSONATION_LEVEL) && ((L) <= SECURITY_MAX_IMPERSONATION_LEVEL)) + +#define TOKEN_ASSIGN_PRIMARY (0x0001) +#define TOKEN_DUPLICATE (0x0002) +#define TOKEN_IMPERSONATE (0x0004) +#define TOKEN_QUERY (0x0008) +#define TOKEN_QUERY_SOURCE (0x0010) +#define TOKEN_ADJUST_PRIVILEGES (0x0020) +#define TOKEN_ADJUST_GROUPS (0x0040) +#define TOKEN_ADJUST_DEFAULT (0x0080) +#define TOKEN_ADJUST_SESSIONID (0x0100) + +#define TOKEN_ALL_ACCESS_P (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | \ + TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | \ + TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT) + +#define TOKEN_ALL_ACCESS (TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID) + +#define TOKEN_READ (STANDARD_RIGHTS_READ | TOKEN_QUERY) + +#define TOKEN_WRITE (STANDARD_RIGHTS_WRITE | \ + TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT) + +#define TOKEN_EXECUTE (STANDARD_RIGHTS_EXECUTE) + +#define TOKEN_MANDATORY_POLICY_OFF 0x0 +#define TOKEN_MANDATORY_POLICY_NO_WRITE_UP 0x1 +#define TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN 0x2 + +#define TOKEN_MANDATORY_POLICY_VALID_MASK (TOKEN_MANDATORY_POLICY_NO_WRITE_UP | \ + TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN) + +#define POLICY_AUDIT_SUBCATEGORY_COUNT (56) + +#define TOKEN_SOURCE_LENGTH 8 + +#define SID_REVISION (1) +#define SID_MAX_SUB_AUTHORITIES (15) +#define SID_RECOMMENDED_SUB_AUTHORITIES (1) + +#define SID_HASH_SIZE 32 + +#define SECURITY_MANDATORY_UNTRUSTED_RID 0x0000 +#define SECURITY_MANDATORY_LOW_RID 0x1000 +#define SECURITY_MANDATORY_MEDIUM_RID 0x2000 +#define SECURITY_MANDATORY_HIGH_RID 0x3000 +#define SECURITY_MANDATORY_SYSTEM_RID 0x4000 + +#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} +#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} +#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2} +#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3} +#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4} +#define SECURITY_RESOURCE_MANAGER_AUTHORITY {0,0,0,0,0,9} + +#define SECURITY_NULL_RID (0x00000000L) +#define SECURITY_WORLD_RID (0x00000000L) +#define SECURITY_LOCAL_RID (0x00000000L) +#define SECURITY_LOCAL_LOGON_RID (0x00000001L) + +#define SECURITY_CREATOR_OWNER_RID (0x00000000L) +#define SECURITY_CREATOR_GROUP_RID (0x00000001L) +#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L) +#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L) +#define SECURITY_CREATOR_OWNER_RIGHTS_RID (0x00000004L) + +typedef PVOID PACCESS_TOKEN; +typedef PVOID PCLAIMS_BLOB; + +typedef struct _LUID_AND_ATTRIBUTES +{ + LUID Luid; + DWORD Attributes; +} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES; +typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; +typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY; + +typedef struct _SID_IDENTIFIER_AUTHORITY +{ + BYTE Value[6]; +} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; + +typedef struct _SID +{ + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[ANYSIZE_ARRAY]; +} SID, *PISID; + +typedef enum _SID_NAME_USE +{ + SidTypeUser = 1, + SidTypeGroup, + SidTypeDomain, + SidTypeAlias, + SidTypeWellKnownGroup, + SidTypeDeletedAccount, + SidTypeInvalid, + SidTypeUnknown, + SidTypeComputer, + SidTypeLabel +} SID_NAME_USE, *PSID_NAME_USE; + +typedef struct _SID_AND_ATTRIBUTES +{ + PSID Sid; + DWORD Attributes; +} SID_AND_ATTRIBUTES, * PSID_AND_ATTRIBUTES; + +typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; +typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY; + +typedef ULONG_PTR SID_HASH_ENTRY, *PSID_HASH_ENTRY; + +typedef struct _SID_AND_ATTRIBUTES_HASH +{ + DWORD SidCount; + PSID_AND_ATTRIBUTES SidAttr; + SID_HASH_ENTRY Hash[SID_HASH_SIZE]; +} SID_AND_ATTRIBUTES_HASH, *PSID_AND_ATTRIBUTES_HASH; + +typedef enum _TOKEN_TYPE +{ + TokenPrimary = 1, + TokenImpersonation +} TOKEN_TYPE; +typedef TOKEN_TYPE *PTOKEN_TYPE; + +typedef enum _TOKEN_ELEVATION_TYPE +{ + TokenElevationTypeDefault = 1, + TokenElevationTypeFull, + TokenElevationTypeLimited, +} TOKEN_ELEVATION_TYPE, *PTOKEN_ELEVATION_TYPE; + +typedef enum _TOKEN_INFORMATION_CLASS +{ + TokenUser = 1, + TokenGroups, + TokenPrivileges, + TokenOwner, + TokenPrimaryGroup, + TokenDefaultDacl, + TokenSource, + TokenType, + TokenImpersonationLevel, + TokenStatistics, + TokenRestrictedSids, + TokenSessionId, + TokenGroupsAndPrivileges, + TokenSessionReference, + TokenSandBoxInert, + TokenAuditPolicy, + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + TokenIsAppContainer, + TokenCapabilities, + TokenAppContainerSid, + TokenAppContainerNumber, + TokenUserClaimAttributes, + TokenDeviceClaimAttributes, + TokenRestrictedUserClaimAttributes, + TokenRestrictedDeviceClaimAttributes, + TokenDeviceGroups, + TokenRestrictedDeviceGroups, + TokenSecurityAttributes, + TokenIsRestricted, + MaxTokenInfoClass +} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS; + +typedef struct _TOKEN_USER +{ + SID_AND_ATTRIBUTES User; +} TOKEN_USER, *PTOKEN_USER; + +typedef struct _TOKEN_GROUPS +{ + DWORD GroupCount; + SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; +} TOKEN_GROUPS, *PTOKEN_GROUPS; + +typedef struct _TOKEN_PRIVILEGES +{ + DWORD PrivilegeCount; + LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; +} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES; + +typedef struct _TOKEN_OWNER +{ + PSID Owner; +} TOKEN_OWNER, *PTOKEN_OWNER; + +typedef struct _TOKEN_PRIMARY_GROUP +{ + PSID PrimaryGroup; +} TOKEN_PRIMARY_GROUP, *PTOKEN_PRIMARY_GROUP; + +typedef struct _TOKEN_DEFAULT_DACL +{ + PACL DefaultDacl; +} TOKEN_DEFAULT_DACL, *PTOKEN_DEFAULT_DACL; + +typedef struct _TOKEN_USER_CLAIMS +{ + PCLAIMS_BLOB UserClaims; +} TOKEN_USER_CLAIMS, *PTOKEN_USER_CLAIMS; + +typedef struct _TOKEN_DEVICE_CLAIMS +{ + PCLAIMS_BLOB DeviceClaims; +} TOKEN_DEVICE_CLAIMS, *PTOKEN_DEVICE_CLAIMS; + +typedef struct _TOKEN_GROUPS_AND_PRIVILEGES +{ + DWORD SidCount; + DWORD SidLength; + PSID_AND_ATTRIBUTES Sids; + DWORD RestrictedSidCount; + DWORD RestrictedSidLength; + PSID_AND_ATTRIBUTES RestrictedSids; + DWORD PrivilegeCount; + DWORD PrivilegeLength; + PLUID_AND_ATTRIBUTES Privileges; + LUID AuthenticationId; +} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES; + +typedef struct _TOKEN_LINKED_TOKEN +{ + HANDLE LinkedToken; +} TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN; + +typedef struct _TOKEN_ELEVATION +{ + DWORD TokenIsElevated; +} TOKEN_ELEVATION, *PTOKEN_ELEVATION; + +typedef struct _TOKEN_MANDATORY_LABEL +{ + SID_AND_ATTRIBUTES Label; +} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL; + +typedef struct _TOKEN_MANDATORY_POLICY +{ + DWORD Policy; +} TOKEN_MANDATORY_POLICY, *PTOKEN_MANDATORY_POLICY; + +typedef struct _TOKEN_ACCESS_INFORMATION +{ + PSID_AND_ATTRIBUTES_HASH SidHash; + PSID_AND_ATTRIBUTES_HASH RestrictedSidHash; + PTOKEN_PRIVILEGES Privileges; + LUID AuthenticationId; + TOKEN_TYPE TokenType; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + TOKEN_MANDATORY_POLICY MandatoryPolicy; + DWORD Flags; + DWORD AppContainerNumber; + PSID PackageSid; + PSID_AND_ATTRIBUTES_HASH CapabilitiesHash; +} TOKEN_ACCESS_INFORMATION, *PTOKEN_ACCESS_INFORMATION; + +typedef struct _TOKEN_AUDIT_POLICY +{ + BYTE PerUserPolicy[((POLICY_AUDIT_SUBCATEGORY_COUNT) >> 1) + 1]; +} TOKEN_AUDIT_POLICY, *PTOKEN_AUDIT_POLICY; + +typedef struct _TOKEN_SOURCE +{ + CHAR SourceName[TOKEN_SOURCE_LENGTH]; + LUID SourceIdentifier; +} TOKEN_SOURCE, *PTOKEN_SOURCE; + +typedef struct _TOKEN_STATISTICS +{ + LUID TokenId; + LUID AuthenticationId; + LARGE_INTEGER ExpirationTime; + TOKEN_TYPE TokenType; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + DWORD DynamicCharged; + DWORD DynamicAvailable; + DWORD GroupCount; + DWORD PrivilegeCount; + LUID ModifiedId; +} TOKEN_STATISTICS, *PTOKEN_STATISTICS; + +typedef struct _TOKEN_CONTROL +{ + LUID TokenId; + LUID AuthenticationId; + LUID ModifiedId; + TOKEN_SOURCE TokenSource; +} TOKEN_CONTROL, *PTOKEN_CONTROL; + +typedef struct _TOKEN_ORIGIN +{ + LUID OriginatingLogonSession; +} TOKEN_ORIGIN, *PTOKEN_ORIGIN; + +typedef enum _MANDATORY_LEVEL +{ + MandatoryLevelUntrusted = 0, + MandatoryLevelLow, + MandatoryLevelMedium, + MandatoryLevelHigh, + MandatoryLevelSystem, + MandatoryLevelSecureProcess, + MandatoryLevelCount +} MANDATORY_LEVEL, *PMANDATORY_LEVEL; + +typedef struct _TOKEN_APPCONTAINER_INFORMATION +{ + PSID TokenAppContainer; +} TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION; #endif diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index 7830be31d..c9f8178a5 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -28,6 +28,7 @@ #include "../synch/synch.h" #include "../thread/thread.h" #include "../pipe/pipe.h" +#include "../security/security.h" #ifdef HAVE_UNISTD_H #include @@ -176,6 +177,20 @@ BOOL CloseHandle(HANDLE hObject) return TRUE; } + else if (Type == HANDLE_TYPE_ACCESS_TOKEN) + { + WINPR_ACCESS_TOKEN* token; + + token = (WINPR_ACCESS_TOKEN*) Object; + + if (token->Username) + free(token->Username); + + if (token->Domain) + free(token->Domain); + + free(token); + } return FALSE; } diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index 9ba8982b5..a823801cf 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -31,6 +31,7 @@ #define HANDLE_TYPE_TIMER 6 #define HANDLE_TYPE_NAMED_PIPE 7 #define HANDLE_TYPE_ANONYMOUS_PIPE 8 +#define HANDLE_TYPE_ACCESS_TOKEN 9 #define WINPR_HANDLE_DEF() \ ULONG Type diff --git a/winpr/libwinpr/security/security.c b/winpr/libwinpr/security/security.c index d958e0e15..51250e78b 100644 --- a/winpr/libwinpr/security/security.c +++ b/winpr/libwinpr/security/security.c @@ -138,7 +138,7 @@ #ifndef _WIN32 - +#include "security.h" #endif diff --git a/winpr/libwinpr/security/security.h b/winpr/libwinpr/security/security.h new file mode 100644 index 000000000..523c15f59 --- /dev/null +++ b/winpr/libwinpr/security/security.h @@ -0,0 +1,43 @@ +/** + * WinPR: Windows Portable Runtime + * Base Security Functions + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_SECURITY_PRIVATE_H +#define WINPR_SECURITY_PRIVATE_H + +#ifndef _WIN32 + +#include + +#include "../handle/handle.h" + +struct winpr_access_token +{ + WINPR_HANDLE_DEF(); + + LPSTR Username; + LPSTR Domain; + + DWORD UserId; + DWORD GroupId; +}; +typedef struct winpr_access_token WINPR_ACCESS_TOKEN; + +#endif + +#endif /* WINPR_SECURITY_PRIVATE_H */ diff --git a/winpr/libwinpr/sspicli/sspicli.c b/winpr/libwinpr/sspicli/sspicli.c index 0bad74088..a098fd163 100644 --- a/winpr/libwinpr/sspicli/sspicli.c +++ b/winpr/libwinpr/sspicli/sspicli.c @@ -60,9 +60,46 @@ #include #endif +#include +#include + +#include "../handle/handle.h" + +#include "../security/security.h" + BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken) { + struct passwd* pw; + WINPR_ACCESS_TOKEN* token; + + if (!lpszUsername) + return FALSE; + + token = (WINPR_ACCESS_TOKEN*) malloc(sizeof(WINPR_ACCESS_TOKEN)); + + if (!token) + return FALSE; + + ZeroMemory(token, sizeof(WINPR_ACCESS_TOKEN)); + + WINPR_HANDLE_SET_TYPE(token, HANDLE_TYPE_ACCESS_TOKEN); + + token->Username = _strdup(lpszUsername); + + if (lpszDomain) + token->Domain = _strdup(lpszDomain); + + pw = getpwnam(lpszUsername); + + if (pw) + { + token->UserId = (DWORD) pw->pw_uid; + token->GroupId = (DWORD) pw->pw_gid; + } + + *((ULONG_PTR*) phToken) = (ULONG_PTR) token; + return TRUE; } diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 012edd382..89f3e19b5 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -104,7 +104,8 @@ char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) return envp; } -BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, +BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, + LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { @@ -171,6 +172,16 @@ BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_AT return TRUE; } +BOOL CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) +{ + return _CreateProcessExA(NULL, 0, + lpApplicationName, lpCommandLine, lpProcessAttributes, + lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation); +} + BOOL CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) @@ -182,7 +193,10 @@ BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpComma LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { - return TRUE; + return _CreateProcessExA(hToken, 0, + lpApplicationName, lpCommandLine, lpProcessAttributes, + lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation); } BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, @@ -210,7 +224,10 @@ BOOL CreateProcessWithTokenA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName, LPSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { - return TRUE; + return _CreateProcessExA(NULL, 0, + lpApplicationName, lpCommandLine, NULL, + NULL, FALSE, dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation); } BOOL CreateProcessWithTokenW(HANDLE hToken, DWORD dwLogonFlags, From 4d8c47ce924eb0e6d59c096f13e843dec9036a5d Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 24 Sep 2013 09:23:43 +0200 Subject: [PATCH 193/202] Replaced linkedLen, which is a padded version of the buffer length from being used for reading from a packet. Now just used for sanity checks. --- .../smartcard/client/smartcard_operations.c | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index e87571c51..9bad5b0e2 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1625,7 +1625,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) if (status) goto finish; - DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength,=%d, ptrSendBuffer,=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL,=%d, cbRecvLength=%d", + DEBUG_WARN("dwProtocol=%X, cbPciLength=%d, pioSendPciBufferPtr=%d, cbSendLength,=%d, ptrSendBuffer=%d, ptrIoRecvPciBuffer=%d, recvBufferIsNULL=%d, cbRecvLength=%d", irp->input, ioSendPci.rq->dwProtocol, irp->input, ioSendPci.rq->cbPciLength, irp->input, pioSendPciBufferPtr, @@ -1649,9 +1649,9 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } Stream_Read_UINT32(irp->input, linkedLen); - if (Stream_GetRemainingLength(irp->input) < linkedLen) + if (Stream_GetRemainingLength(irp->input) < ioSendPci.rq->cbPciLength) { - DEBUG_WARN("length violation %d [%d]", linkedLen, + DEBUG_WARN("length violation %d [%d]", ioSendPci.rq->cbPciLength, Stream_GetRemainingLength(irp->input)); status = SCARD_F_INTERNAL_ERROR; goto finish; @@ -1660,7 +1660,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) /* For details see 2.2.1.8 SCardIO_Request in MS-RDPESC and * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379807%28v=vs.85%29.aspx */ - if (linkedLen != ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST)) + if (linkedLen < ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST)) { DEBUG_WARN("SCARD_IO_REQUEST with invalid extra byte length %d [%d]", ioSendPci.rq->cbPciLength - sizeof(SCARD_IO_REQUEST), linkedLen); @@ -1672,7 +1672,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) goto finish; ioSendPci.v = tmp; - Stream_Read(irp->input, &ioSendPci.rq[1], linkedLen); + Stream_Read(irp->input, &ioSendPci.rq[1], ioSendPci.rq->cbPciLength); } else ioSendPci.rq->cbPciLength = sizeof(SCARD_IO_REQUEST); @@ -1689,15 +1689,24 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) } Stream_Read_UINT32(irp->input, linkedLen); - if (Stream_GetRemainingLength(irp->input) < linkedLen) + /* Just check for too few bytes, there may be more actual + * data than is used due to padding. */ + if (linkedLen < cbSendLength) { - DEBUG_WARN("length violation %d [%d]", linkedLen, + DEBUG_WARN("SendBuffer invalid byte length %d [%d]", + cbSendLength, linkedLen); + status = SCARD_F_INTERNAL_ERROR; + goto finish; + } + if (Stream_GetRemainingLength(irp->input) < cbSendLength) + { + DEBUG_WARN("length violation %d [%d]", cbSendLength, Stream_GetRemainingLength(irp->input)); status = SCARD_F_INTERNAL_ERROR; goto finish; } - sendBuf = malloc(linkedLen); - Stream_Read(irp->input, sendBuf, linkedLen); + sendBuf = malloc(cbSendLength); + Stream_Read(irp->input, sendBuf, cbSendLength); } /* Check, if a response is desired. */ @@ -1729,11 +1738,10 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp, size_t inlen) status = SCARD_F_INTERNAL_ERROR; goto finish; } - linkedLen -= 4; - if (Stream_GetRemainingLength(irp->input) < linkedLen) + if (Stream_GetRemainingLength(irp->input) < ioRecvPci.rq->cbPciLength) { - DEBUG_WARN("length violation %d [%d]", linkedLen, + DEBUG_WARN("length violation %d [%d]", ioRecvPci.rq->cbPciLength, Stream_GetRemainingLength(irp->input)); status = SCARD_F_INTERNAL_ERROR; goto finish; From f363b9381939be652d0fefdec2aac08b57622735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 24 Sep 2013 11:03:42 -0400 Subject: [PATCH 194/202] libwinpr-process: add searching of system path --- winpr/libwinpr/thread/CMakeLists.txt | 11 ++- winpr/libwinpr/thread/process.c | 112 ++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 5 deletions(-) diff --git a/winpr/libwinpr/thread/CMakeLists.txt b/winpr/libwinpr/thread/CMakeLists.txt index 5a6690b6f..eeb68ba5b 100644 --- a/winpr/libwinpr/thread/CMakeLists.txt +++ b/winpr/libwinpr/thread/CMakeLists.txt @@ -44,11 +44,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rt) endif() -if(MONOLITHIC_BUILD) - set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) -else() - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr-handle) +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-crt winpr-path winpr-handle) +if(MONOLITHIC_BUILD) + +else() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 89f3e19b5..30d09e8d9 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -56,11 +56,14 @@ #endif #include +#include +#include #include #include #include #include +#include #include #include @@ -68,6 +71,7 @@ #include "thread.h" #include "../handle/handle.h" +#include "../security/security.h" char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) { @@ -104,18 +108,81 @@ char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) return envp; } +/** + * If the file name does not contain a directory path, the system searches for the executable file in the following sequence: + * + * 1) The directory from which the application loaded. + * 2) The current directory for the parent process. + * 3) The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. + * 4) The 16-bit Windows system directory. There is no function that obtains the path of this directory, + * but it is searched. The name of this directory is System. + * 5) The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. + * 6) The directories that are listed in the PATH environment variable. Note that this function + * does not search the per-application path specified by the App Paths registry key. To include + * this per-application path in the search sequence, use the ShellExecute function. + */ + +char* FindApplicationPath(char* application) +{ + char* path; + char* save; + DWORD nSize; + LPSTR lpSystemPath; + char* filename = NULL; + + if (!application) + return NULL; + + if (application[0] == '/') + return application; + + nSize = GetEnvironmentVariableA("PATH", NULL, 0); + + if (!nSize) + return application; + + lpSystemPath = (LPSTR) malloc(nSize); + nSize = GetEnvironmentVariableA("PATH", lpSystemPath, nSize); + + save = NULL; + path = strtok_s(lpSystemPath, ":", &save); + + while (path) + { + filename = GetCombinedPath(path, application); + + if (PathFileExistsA(filename)) + { + break; + } + + free(filename); + filename = NULL; + + path = strtok_s(NULL, ":", &save); + } + + free(lpSystemPath); + + return filename; +} + BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { pid_t pid; + int flags; int status; int numArgs; LPSTR* pArgs; char** envp; + char* filename; WINPR_THREAD* thread; WINPR_PROCESS* process; + posix_spawnattr_t attr; + WINPR_ACCESS_TOKEN* token; LPTCH lpszEnvironmentBlock; pid = 0; @@ -125,6 +192,22 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, pArgs = CommandLineToArgvA(lpCommandLine, &numArgs); + flags = 0; + posix_spawnattr_init(&attr); + + token = (WINPR_ACCESS_TOKEN*) hToken; + + if (token) + { + + } + +#ifdef POSIX_SPAWN_USEVFORK + flags |= POSIX_SPAWN_USEVFORK; +#endif + + posix_spawnattr_setflags(&attr, flags); + if (lpEnvironment) { envp = EnvironmentBlockToEnvpA(lpEnvironment); @@ -135,7 +218,9 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock); } - status = posix_spawnp(&pid, pArgs[0], NULL, NULL, pArgs, envp); + filename = FindApplicationPath(pArgs[0]); + + status = posix_spawn(&pid, filename, NULL, &attr, pArgs, envp); if (status != 0) return FALSE; @@ -169,6 +254,31 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, lpProcessInformation->dwProcessId = (DWORD) pid; lpProcessInformation->dwThreadId = (DWORD) pid; + free(filename); + + if (pArgs) + { + HeapFree(GetProcessHeap(), 0, pArgs); + } + + posix_spawnattr_destroy(&attr); + + if (lpszEnvironmentBlock) + FreeEnvironmentStrings(lpszEnvironmentBlock); + + if (envp) + { + int i = 0; + + while (envp[i]) + { + free(envp[i]); + i++; + } + + free(envp); + } + return TRUE; } From 9a124a1d6006eaf0563db77fb2b0ac325fb57232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 24 Sep 2013 13:08:29 -0400 Subject: [PATCH 195/202] libwinpr-thread: initial CreateProcessAsUser implementation --- winpr/libwinpr/thread/process.c | 54 ++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 30d09e8d9..a1f43a659 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -61,6 +61,9 @@ #include #include +#include +#include + #include #include #include @@ -174,14 +177,12 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, { pid_t pid; int flags; - int status; int numArgs; LPSTR* pArgs; char** envp; char* filename; WINPR_THREAD* thread; WINPR_PROCESS* process; - posix_spawnattr_t attr; WINPR_ACCESS_TOKEN* token; LPTCH lpszEnvironmentBlock; @@ -193,21 +194,9 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, pArgs = CommandLineToArgvA(lpCommandLine, &numArgs); flags = 0; - posix_spawnattr_init(&attr); token = (WINPR_ACCESS_TOKEN*) hToken; - if (token) - { - - } - -#ifdef POSIX_SPAWN_USEVFORK - flags |= POSIX_SPAWN_USEVFORK; -#endif - - posix_spawnattr_setflags(&attr, flags); - if (lpEnvironment) { envp = EnvironmentBlockToEnvpA(lpEnvironment); @@ -220,10 +209,41 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, filename = FindApplicationPath(pArgs[0]); - status = posix_spawn(&pid, filename, NULL, &attr, pArgs, envp); + /* fork and exec */ - if (status != 0) + pid = fork(); + + if (pid < 0) + { + /* fork failure */ return FALSE; + } + + if (pid == 0) + { + /* child process */ + + if (token) + { + if (token->GroupId) + { + setgid((gid_t) token->GroupId); + initgroups(token->Username, (gid_t) token->GroupId); + } + + if (token->UserId) + setuid((uid_t) token->UserId); + } + + if (execve(filename, pArgs, envp) < 0) + { + return FALSE; + } + } + else + { + /* parent process */ + } process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS)); @@ -261,8 +281,6 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, HeapFree(GetProcessHeap(), 0, pArgs); } - posix_spawnattr_destroy(&attr); - if (lpszEnvironmentBlock) FreeEnvironmentStrings(lpszEnvironmentBlock); From f6ee26f15a22ec1c521ff26b59121d876a940722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 24 Sep 2013 14:35:03 -0400 Subject: [PATCH 196/202] winpr: fix noreturn warnings --- winpr/libwinpr/rpc/rpc.c | 3 ++- winpr/libwinpr/thread/process.c | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/rpc/rpc.c b/winpr/libwinpr/rpc/rpc.c index 3f6685925..d82e4fe6c 100644 --- a/winpr/libwinpr/rpc/rpc.c +++ b/winpr/libwinpr/rpc/rpc.c @@ -520,9 +520,10 @@ RPC_STATUS RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BIND return 0; } -DECLSPEC_NORETURN void RpcRaiseException(RPC_STATUS exception) +void RpcRaiseException(RPC_STATUS exception) { fprintf(stderr, "RpcRaiseException: 0x%08luX\n", exception); + exit((int) exception); } RPC_STATUS RpcTestCancel() diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index a1f43a659..62d7f1faf 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -365,9 +365,9 @@ BOOL CreateProcessWithTokenW(HANDLE hToken, DWORD dwLogonFlags, return TRUE; } -DECLSPEC_NORETURN VOID ExitProcess(UINT uExitCode) +VOID ExitProcess(UINT uExitCode) { - + exit((int) uExitCode); } BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) @@ -399,11 +399,28 @@ DWORD GetCurrentProcessId(VOID) DWORD GetProcessId(HANDLE Process) { - return 0; + WINPR_PROCESS* process; + + process = (WINPR_PROCESS*) Process; + + if (!process) + return 0; + + return (DWORD) process->pid; } BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode) { + WINPR_PROCESS* process; + + process = (WINPR_PROCESS*) hProcess; + + if (!process) + return FALSE; + + if (kill(process->pid, SIGTERM)) + return FALSE; + return TRUE; } From c99d9ee72bae06d19a15cce46eb4f3230a97f296 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 24 Sep 2013 23:25:18 +0200 Subject: [PATCH 197/202] core/glyph: copy data when adding glyph to cache fixes #1500 --- libfreerdp/cache/glyph.c | 15 +++++---------- libfreerdp/core/orders.c | 4 ++-- libfreerdp/core/update.c | 2 ++ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index e8650fcd7..3fcbe77ef 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -277,7 +277,7 @@ void update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph) if (y == -32768) y = fast_glyph->bkTop; - if (fast_glyph->cbData > 1) + if (fast_glyph->cbData > 1 && NULL != fast_glyph->glyphData.aj) { /* got option font that needs to go into cache */ glyph_data = &fast_glyph->glyphData; @@ -288,7 +288,8 @@ void update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph) glyph->cx = glyph_data->cx; glyph->cy = glyph_data->cy; glyph->cb = glyph_data->cb; - glyph->aj = glyph_data->aj; + glyph->aj = malloc(glyph_data->cb); + CopyMemory(glyph->aj, glyph_data->aj, glyph->cb); Glyph_New(context, glyph); glyph_cache_put(cache->glyph, fast_glyph->cacheId, fast_glyph->data[0], glyph); @@ -368,16 +369,14 @@ rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, UINT32 id, UINT32 index) if (index > glyph_cache->glyphCache[id].number) { - fprintf(stderr, "invalid glyph cache index: %d in cache id: %d\n", index, id); + fprintf(stderr, "index %d out of range for cache id: %d\n", index, id); return NULL; } glyph = glyph_cache->glyphCache[id].entries[index]; if (glyph == NULL) - { - fprintf(stderr, "invalid glyph at cache index: %d in cache id: %d\n", index, id); - } + fprintf(stderr, "no glyph found at cache index: %d in cache id: %d\n", index, id); return glyph; } @@ -419,9 +418,7 @@ void* glyph_cache_fragment_get(rdpGlyphCache* glyph_cache, UINT32 index, UINT32* *size = (BYTE) glyph_cache->fragCache.entries[index].size; if (fragment == NULL) - { fprintf(stderr, "invalid glyph fragment at index:%d\n", index); - } return fragment; } @@ -436,9 +433,7 @@ void glyph_cache_fragment_put(rdpGlyphCache* glyph_cache, UINT32 index, UINT32 s glyph_cache->fragCache.entries[index].size = size; if (prevFragment != NULL) - { free(prevFragment); - } } void glyph_cache_register_callbacks(rdpUpdate* update) diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index d0f5c9713..e54fc19f8 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -485,9 +485,7 @@ static INLINE BOOL update_write_4byte_unsigned(wStream* s, UINT32 value) Stream_Write_UINT8(s, byte); } else - { return FALSE; - } return TRUE; } @@ -1670,6 +1668,8 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ if (Stream_GetRemainingLength(s) < glyph->cb) return FALSE; + if (glyph->aj) + free(glyph->aj); glyph->aj = (BYTE*) malloc(glyph->cb); Stream_Read(s, glyph->aj, glyph->cb); } diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index bf6829174..de7a4468e 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -1609,6 +1609,8 @@ void update_free(rdpUpdate* update) free(update->primary->polyline.points); free(update->primary->polygon_sc.points); + if (NULL != update->primary->fast_glyph.glyphData.aj) + free(update->primary->fast_glyph.glyphData.aj); free(update->primary); free(update->secondary); From 7ec19ac0f2d7118e4256a81deecdd6c4793c281f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 25 Sep 2013 15:47:18 -0400 Subject: [PATCH 198/202] libwinpr-thread: fix build on Windows --- winpr/include/winpr/thread.h | 5 ++++- winpr/libwinpr/thread/argv.c | 9 ++++----- winpr/libwinpr/thread/test/TestThreadCreateProcess.c | 10 +++++++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/winpr/include/winpr/thread.h b/winpr/include/winpr/thread.h index 4603ed8b1..71beed8ef 100644 --- a/winpr/include/winpr/thread.h +++ b/winpr/include/winpr/thread.h @@ -144,7 +144,6 @@ WINPR_API BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode); /* Process Argument Vector Parsing */ -WINPR_API LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs); WINPR_API LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs); #ifdef UNICODE @@ -199,6 +198,10 @@ WINPR_API BOOL TlsFree(DWORD dwTlsIndex); #endif +/* CommandLineToArgvA is not present in the original Windows API, WinPR always exports it */ + +WINPR_API LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs); + #ifdef __cplusplus } #endif diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 041216131..e33ecf9ee 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -22,12 +22,11 @@ #endif #include +#include #include #include -#ifndef _WIN32 - #ifdef HAVE_UNISTD_H #include #endif @@ -204,13 +203,11 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); - buffer = (char*) malloc(maxBufferSize); + buffer = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, maxBufferSize); if (!buffer) return NULL; - ZeroMemory(buffer, maxBufferSize); - pArgs = (LPSTR*) buffer; pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; @@ -320,6 +317,8 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) return pArgs; } +#ifndef _WIN32 + LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs) { return NULL; diff --git a/winpr/libwinpr/thread/test/TestThreadCreateProcess.c b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c index b57b0a1f9..fb30f619b 100644 --- a/winpr/libwinpr/thread/test/TestThreadCreateProcess.c +++ b/winpr/libwinpr/thread/test/TestThreadCreateProcess.c @@ -26,7 +26,13 @@ int TestThreadCreateProcess(int argc, char* argv[]) lpApplicationName = NULL; //lpCommandLine = _T("ls -l /"); + +#ifdef _WIN32 + lpCommandLine = _T("env"); +#else lpCommandLine = _T("printenv"); +#endif + lpProcessAttributes = NULL; lpThreadAttributes = NULL; bInheritHandles = FALSE; @@ -53,9 +59,11 @@ int TestThreadCreateProcess(int argc, char* argv[]) WaitForSingleObject(ProcessInformation.hProcess, INFINITE); + exitCode = 0; status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode); - printf("Process exited with code: %d\n", exitCode); + printf("GetExitCodeProcess status: %d\n", status); + printf("Process exited with code: 0x%08X\n", exitCode); CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hThread); From b3b6ee57f0d94584b5d118ea75efedd453667c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 25 Sep 2013 16:26:54 -0400 Subject: [PATCH 199/202] libwinpr-thread: add missing link dependencies for tests --- winpr/libwinpr/thread/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/libwinpr/thread/CMakeLists.txt b/winpr/libwinpr/thread/CMakeLists.txt index eeb68ba5b..311290f01 100644 --- a/winpr/libwinpr/thread/CMakeLists.txt +++ b/winpr/libwinpr/thread/CMakeLists.txt @@ -47,7 +47,7 @@ endif() set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL MODULE winpr - MODULES winpr-crt winpr-path winpr-handle) + MODULES winpr-crt winpr-path winpr-handle winpr-heap winpr-synch) if(MONOLITHIC_BUILD) From 8c72211eeaae058e0fbc8f6ae298fcc67e14a31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 25 Sep 2013 16:38:41 -0400 Subject: [PATCH 200/202] libwinpr-thread: fix link libraries --- winpr/libwinpr/thread/CMakeLists.txt | 2 +- winpr/libwinpr/thread/test/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/thread/CMakeLists.txt b/winpr/libwinpr/thread/CMakeLists.txt index 311290f01..eeb68ba5b 100644 --- a/winpr/libwinpr/thread/CMakeLists.txt +++ b/winpr/libwinpr/thread/CMakeLists.txt @@ -47,7 +47,7 @@ endif() set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL MODULE winpr - MODULES winpr-crt winpr-path winpr-handle winpr-heap winpr-synch) + MODULES winpr-crt winpr-path winpr-handle) if(MONOLITHIC_BUILD) diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt index 9ca3a9ac0..258704857 100644 --- a/winpr/libwinpr/thread/test/CMakeLists.txt +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -17,7 +17,7 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-thread winpr-heap winpr-environment) + MODULES winpr-thread winpr-heap winpr-environment winpr-synch) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) From f4e98f29ece25e475eada840e09bee49080a7efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 25 Sep 2013 19:13:39 -0400 Subject: [PATCH 201/202] libwinpr-pipe: add server-side named pipe waiting --- winpr/include/winpr/pipe.h | 2 ++ winpr/libwinpr/file/file.c | 20 ++++++++++++++++++++ winpr/libwinpr/pipe/pipe.c | 4 ++++ winpr/libwinpr/pipe/pipe.h | 1 + winpr/libwinpr/synch/wait.c | 17 +++++++++++++---- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/winpr/include/winpr/pipe.h b/winpr/include/winpr/pipe.h index 188adf859..5c5b12f0f 100644 --- a/winpr/include/winpr/pipe.h +++ b/winpr/include/winpr/pipe.h @@ -114,6 +114,8 @@ WINPR_API char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName); WINPR_API char* GetNamedPipeUnixDomainSocketBaseFilePathA(); WINPR_API char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName); +WINPR_API int GetNamePipeFileDescriptor(HANDLE hNamedPipe); + #ifdef __cplusplus } #endif diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index feb673c77..7720bb8b3 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -216,6 +216,7 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0); pNamedPipe->serverfd = -1; + pNamedPipe->ServerMode = FALSE; if (0) { @@ -733,6 +734,25 @@ char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName) return lpFilePath; } +int GetNamePipeFileDescriptor(HANDLE hNamedPipe) +{ +#ifndef _WIN32 + int fd; + WINPR_NAMED_PIPE* pNamedPipe; + + pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe; + + if (!pNamedPipe) + return -1; + + fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd; + + return fd; +#else + return -1; +#endif +} + int UnixChangeFileMode(const char* filename, int flags) { #ifndef _WIN32 diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 4c984a3db..fa01fff57 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -123,12 +123,16 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA(); if (!PathFileExistsA(lpPipePath)) + { CreateDirectoryA(lpPipePath, 0); + UnixChangeFileMode(lpPipePath, 0xFFFF); + } free(lpPipePath); pNamedPipe->clientfd = -1; pNamedPipe->serverfd = socket(PF_LOCAL, SOCK_STREAM, 0); + pNamedPipe->ServerMode = TRUE; if (0) { diff --git a/winpr/libwinpr/pipe/pipe.h b/winpr/libwinpr/pipe/pipe.h index efc79989a..51b423dfa 100644 --- a/winpr/libwinpr/pipe/pipe.h +++ b/winpr/libwinpr/pipe/pipe.h @@ -45,6 +45,7 @@ struct winpr_named_pipe const char* lpFileName; const char* lpFilePath; + BOOL ServerMode; DWORD dwOpenMode; DWORD dwPipeMode; DWORD nMaxInstances; diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 823a07fd8..0467d66a7 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -260,13 +260,19 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) } else if (Type == HANDLE_TYPE_NAMED_PIPE) { + int fd; int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; + fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; + + if (fd == -1) + return WAIT_FAILED; + FD_ZERO(&rfds); - FD_SET(pipe->clientfd, &rfds); + FD_SET(fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) @@ -274,7 +280,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) timeout.tv_usec = dwMilliseconds * 1000; } - status = select(pipe->clientfd + 1, &rfds, NULL, NULL, + status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) @@ -347,7 +353,10 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl else if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; - fd = pipe->clientfd; + fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; + + if (fd == -1) + return WAIT_FAILED; } else { @@ -397,7 +406,7 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl else if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; - fd = pipe->clientfd; + fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; } if (FD_ISSET(fd, &fds)) From 480071cdeba42c302204e628c32e6dfa6925e32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 25 Sep 2013 23:16:33 -0400 Subject: [PATCH 202/202] libwinpr-io: improve overlapped io with server-side named pipes --- winpr/libwinpr/file/file.c | 13 +++---- winpr/libwinpr/io/io.c | 39 ++++++++++++++++++--- winpr/libwinpr/pipe/pipe.c | 70 +++++++++++++++++++++++++++++--------- 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 7720bb8b3..022f6138a 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -218,13 +218,6 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, pNamedPipe->serverfd = -1; pNamedPipe->ServerMode = FALSE; - if (0) - { - flags = fcntl(pNamedPipe->clientfd, F_GETFL); - flags = flags | O_NONBLOCK; - fcntl(pNamedPipe->clientfd, F_SETFL, flags); - } - ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); @@ -249,7 +242,11 @@ HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, BOOL DeleteFileA(LPCSTR lpFileName) { - return TRUE; + int status; + + status = unlink(lpFileName); + + return (status != -1) ? TRUE : FALSE; } BOOL DeleteFileW(LPCWSTR lpFileName) diff --git a/winpr/libwinpr/io/io.c b/winpr/libwinpr/io/io.c index bf6adaa9c..ad2c3930c 100644 --- a/winpr/libwinpr/io/io.c +++ b/winpr/libwinpr/io/io.c @@ -36,6 +36,13 @@ #include #include +#include +#include +#include +#include + +#include + #include "../handle/handle.h" #include "../pipe/pipe.h" @@ -61,21 +68,45 @@ BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumb if (!(pipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) return FALSE; - if (pipe->clientfd == -1) - return FALSE; - lpBuffer = lpOverlapped->Pointer; request = (DWORD) lpOverlapped->Internal; nNumberOfBytes = (DWORD) lpOverlapped->InternalHigh; if (request == 0) { + if (pipe->clientfd == -1) + return FALSE; + status = read(pipe->clientfd, lpBuffer, nNumberOfBytes); } - else + else if (request == 1) { + if (pipe->clientfd == -1) + return FALSE; + status = write(pipe->clientfd, lpBuffer, nNumberOfBytes); } + else if (request == 2) + { + socklen_t length; + struct sockaddr_un s; + + if (pipe->serverfd == -1) + return FALSE; + + length = sizeof(struct sockaddr_un); + ZeroMemory(&s, sizeof(struct sockaddr_un)); + + status = accept(pipe->serverfd, (struct sockaddr*) &s, &length); + + if (status < 0) + return FALSE; + + pipe->clientfd = status; + pipe->ServerMode = FALSE; + + status = 0; + } if (status < 0) { diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index fa01fff57..83f15d6e1 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -69,8 +69,10 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP { if (pReadPipe) free(pReadPipe); + if (pWritePipe) free(pWritePipe); + return FALSE; } @@ -96,7 +98,6 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD int status; HANDLE hNamedPipe; char* lpPipePath; - unsigned long flags; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; @@ -134,17 +135,12 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD pNamedPipe->serverfd = socket(PF_LOCAL, SOCK_STREAM, 0); pNamedPipe->ServerMode = TRUE; - if (0) - { - flags = fcntl(pNamedPipe->serverfd, F_GETFL); - flags = flags | O_NONBLOCK; - fcntl(pNamedPipe->serverfd, F_SETFL, flags); - } + if (PathFileExistsA(pNamedPipe->lpFilePath)) + DeleteFileA(pNamedPipe->lpFilePath); ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); - unlink(s.sun_path); status = bind(pNamedPipe->serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); @@ -179,21 +175,35 @@ BOOL ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe; - length = sizeof(struct sockaddr_un); - ZeroMemory(&s, sizeof(struct sockaddr_un)); + if (!(pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) + { + length = sizeof(struct sockaddr_un); + ZeroMemory(&s, sizeof(struct sockaddr_un)); - status = accept(pNamedPipe->serverfd, (struct sockaddr*) &s, &length); + status = accept(pNamedPipe->serverfd, (struct sockaddr*) &s, &length); - if (status < 0) - return FALSE; + if (status < 0) + return FALSE; - pNamedPipe->clientfd = status; - - if (pNamedPipe->dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) + pNamedPipe->clientfd = status; + pNamedPipe->ServerMode = FALSE; + } + else { if (!lpOverlapped) return FALSE; + if (pNamedPipe->serverfd == -1) + return FALSE; + + pNamedPipe->lpOverlapped = lpOverlapped; + + /* synchronous behavior */ + + lpOverlapped->Internal = 2; + lpOverlapped->InternalHigh = (ULONG_PTR) 0; + lpOverlapped->Pointer = (PVOID) NULL; + SetEvent(lpOverlapped->hEvent); } @@ -268,13 +278,41 @@ BOOL WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut) BOOL SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout) { + int fd; + unsigned long flags; WINPR_NAMED_PIPE* pNamedPipe; pNamedPipe = (WINPR_NAMED_PIPE*) hNamedPipe; if (lpMode) + { pNamedPipe->dwPipeMode = *lpMode; + fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd; + + if (fd == -1) + return FALSE; + + flags = fcntl(fd, F_GETFL); + + if (pNamedPipe->dwPipeMode & PIPE_NOWAIT) + flags = (flags | O_NONBLOCK); + else + flags = (flags & ~(O_NONBLOCK)); + + fcntl(fd, F_SETFL, flags); + } + + if (lpMaxCollectionCount) + { + + } + + if (lpCollectDataTimeout) + { + + } + return TRUE; }