commit
abb984347b
@ -213,8 +213,13 @@ static BOOL audin_winmm_format_supported(IAudinDevice* device, audinFormat* form
|
||||
{
|
||||
if (winmm->cFormats >= winmm->ppwfx_size)
|
||||
{
|
||||
PWAVEFORMATEX *tmp_ppwfx;
|
||||
tmp_ppwfx = realloc(winmm->ppwfx, sizeof(PWAVEFORMATEX) * winmm->ppwfx_size * 2);
|
||||
if (!tmp_ppwfx)
|
||||
return 0;
|
||||
|
||||
winmm->ppwfx_size *= 2;
|
||||
winmm->ppwfx = realloc(winmm->ppwfx, sizeof(PWAVEFORMATEX) * winmm->ppwfx_size);
|
||||
winmm->ppwfx = tmp_ppwfx;
|
||||
}
|
||||
winmm->ppwfx[winmm->cFormats++] = pwfx;
|
||||
|
||||
|
@ -30,18 +30,33 @@
|
||||
|
||||
static BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
UINT16 new_length;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, unicode_string->length); /* cbString (2 bytes) */
|
||||
Stream_Read_UINT16(s, new_length); /* cbString (2 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < unicode_string->length)
|
||||
if (Stream_GetRemainingLength(s) < new_length)
|
||||
return FALSE;
|
||||
|
||||
if (!unicode_string->string)
|
||||
unicode_string->string = (BYTE*) malloc(unicode_string->length);
|
||||
{
|
||||
unicode_string->string = (BYTE*) malloc(new_length);
|
||||
if (!unicode_string->string)
|
||||
return FALSE;
|
||||
unicode_string->length = new_length;
|
||||
}
|
||||
else
|
||||
unicode_string->string = (BYTE*) realloc(unicode_string->string, unicode_string->length);
|
||||
{
|
||||
BYTE *new_str;
|
||||
|
||||
new_str = (BYTE*) realloc(unicode_string->string, new_length);
|
||||
if (!new_str)
|
||||
return FALSE;
|
||||
unicode_string->string = new_str;
|
||||
unicode_string->length = new_length;
|
||||
}
|
||||
|
||||
Stream_Read(s, unicode_string->string, unicode_string->length);
|
||||
|
||||
|
@ -366,8 +366,14 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE *data, UI
|
||||
/* Ensure enough space for decoding */
|
||||
if (mdecoder->decoded_size_max - mdecoder->decoded_size < MAX_AUDIO_FRAME_SIZE)
|
||||
{
|
||||
BYTE *tmp_data;
|
||||
|
||||
tmp_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max * 2 + 16);
|
||||
if (!tmp_data)
|
||||
return FALSE;
|
||||
mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16;
|
||||
mdecoder->decoded_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max);
|
||||
mdecoder->decoded_data = tmp_data;
|
||||
|
||||
dst = (BYTE *)(((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
|
||||
if (dst - mdecoder->decoded_data != dst_offset)
|
||||
{
|
||||
|
@ -817,6 +817,7 @@ void tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation,
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
void *tmp_rects;
|
||||
|
||||
/* The server may send messages with invalid width / height.
|
||||
* Ignore those messages. */
|
||||
@ -835,11 +836,14 @@ void tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation,
|
||||
presentation->y = y;
|
||||
presentation->width = width;
|
||||
presentation->height = height;
|
||||
presentation->nr_rects = num_rects;
|
||||
presentation->rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects);
|
||||
|
||||
if (presentation->rects)
|
||||
CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects);
|
||||
tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects);
|
||||
if (!tmp_rects)
|
||||
return;
|
||||
presentation->nr_rects = num_rects;
|
||||
presentation->rects = tmp_rects;
|
||||
|
||||
CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects);
|
||||
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
@ -75,9 +75,16 @@ void android_push_event(freerdp * inst, ANDROID_EVENT* event)
|
||||
androidContext* aCtx = (androidContext*)inst->context;
|
||||
if (aCtx->event_queue->count >= aCtx->event_queue->size)
|
||||
{
|
||||
aCtx->event_queue->size = aCtx->event_queue->size * 2;
|
||||
aCtx->event_queue->events = realloc((void*) aCtx->event_queue->events,
|
||||
sizeof(ANDROID_EVENT*) * aCtx->event_queue->size);
|
||||
int new_size;
|
||||
int new_events;
|
||||
|
||||
new_size = aCtx->event_queue->size * 2;
|
||||
new_events = realloc((void*) aCtx->event_queue->events,
|
||||
sizeof(ANDROID_EVENT*) * new_size);
|
||||
if (!new_events)
|
||||
return;
|
||||
aCtx->event_queue->events = new_events;
|
||||
aCtx->event_queue->size = new_size;
|
||||
}
|
||||
|
||||
aCtx->event_queue->events[(aCtx->event_queue->count)++] = event;
|
||||
|
@ -906,9 +906,15 @@ static void map_ensure_capacity(wfClipboard* clipboard)
|
||||
{
|
||||
if (clipboard->map_size >= clipboard->map_capacity)
|
||||
{
|
||||
clipboard->map_capacity *= 2;
|
||||
clipboard->format_mappings = (formatMapping*) realloc(clipboard->format_mappings,
|
||||
sizeof(formatMapping) * clipboard->map_capacity);
|
||||
int new_size;
|
||||
formatMapping *new_map;
|
||||
|
||||
new_map = (formatMapping*) realloc(clipboard->format_mappings,
|
||||
sizeof(formatMapping) * new_size);
|
||||
if (!new_map)
|
||||
return;
|
||||
clipboard->format_mappings = new_map;
|
||||
clipboard->map_capacity = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1348,9 +1354,24 @@ static void wf_cliprdr_array_ensure_capacity(wfClipboard* clipboard)
|
||||
{
|
||||
if (clipboard->nFiles == clipboard->file_array_size)
|
||||
{
|
||||
clipboard->file_array_size *= 2;
|
||||
clipboard->fileDescriptor = (FILEDESCRIPTORW**) realloc(clipboard->fileDescriptor, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*));
|
||||
clipboard->file_names = (WCHAR**) realloc(clipboard->file_names, clipboard->file_array_size * sizeof(WCHAR*));
|
||||
int new_size;
|
||||
FILEDESCRIPTORW **new_fd;
|
||||
WCHAR **new_name;
|
||||
|
||||
new_size = clipboard->file_array_size * 2;
|
||||
|
||||
new_fd = (FILEDESCRIPTORW**) realloc(clipboard->fileDescriptor, new_size * sizeof(FILEDESCRIPTORW*));
|
||||
if (new_fd)
|
||||
clipboard->fileDescriptor = new_fd;
|
||||
|
||||
new_name = (WCHAR**) realloc(clipboard->file_names, new_size * sizeof(WCHAR*));
|
||||
if (new_name)
|
||||
clipboard->file_names = new_name;
|
||||
|
||||
if (!new_fd || !new_name)
|
||||
return;
|
||||
|
||||
clipboard->file_array_size *= new_size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1678,12 +1699,7 @@ static int wf_cliprdr_server_format_data_request(CliprdrClientContext* context,
|
||||
clipboard->file_names[clipboard->nFiles] = (LPWSTR) malloc(cchWideChar * 2);
|
||||
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, clipboard->file_names[clipboard->nFiles], cchWideChar);
|
||||
|
||||
if (clipboard->nFiles == clipboard->file_array_size)
|
||||
{
|
||||
clipboard->file_array_size *= 2;
|
||||
clipboard->fileDescriptor = (FILEDESCRIPTORW**) realloc(clipboard->fileDescriptor, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*));
|
||||
clipboard->file_names = (WCHAR**) realloc(clipboard->file_names, clipboard->file_array_size * sizeof(WCHAR*));
|
||||
}
|
||||
map_ensure_capacity(clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,7 +516,7 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen);
|
||||
xfc->attribs.border_pixel = WhitePixelOfScreen(xfc->screen);
|
||||
xfc->attribs.backing_store = xfc->primary ? NotUseful : Always;
|
||||
xfc->attribs.override_redirect = xfc->grab_keyboard ? xfc->fullscreen : False;
|
||||
xfc->attribs.override_redirect = False;
|
||||
xfc->attribs.colormap = xfc->colormap;
|
||||
xfc->attribs.bit_gravity = NorthWestGravity;
|
||||
xfc->attribs.win_gravity = NorthWestGravity;
|
||||
@ -571,7 +571,7 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
}
|
||||
#endif
|
||||
|
||||
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->decorations);
|
||||
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height);
|
||||
|
||||
free(windowTitle);
|
||||
|
||||
@ -579,6 +579,10 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
|
||||
|
||||
xfc->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
|
||||
|
||||
/* Disallow resize now that any initial fullscreen window operation is complete */
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, FALSE, xfc->width, xfc->height);
|
||||
|
||||
XSetWMProtocols(xfc->display, xfc->window->handle, &(xfc->WM_DELETE_WINDOW), 1);
|
||||
xfc->drawable = xfc->window->handle;
|
||||
}
|
||||
@ -686,16 +690,12 @@ void xf_toggle_fullscreen(xfContext* xfc)
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
xf_lock_x11(xfc, TRUE);
|
||||
|
||||
xf_window_free(xfc);
|
||||
|
||||
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
|
||||
xfc->decorations = (xfc->fullscreen) ? FALSE : settings->Decorations;
|
||||
|
||||
xf_create_window(xfc);
|
||||
|
||||
xf_unlock_x11(xfc, TRUE);
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, TRUE, xfc->width, xfc->height);
|
||||
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, FALSE, xfc->width, xfc->height);
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
|
||||
@ -1697,6 +1697,7 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False);
|
||||
xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False);
|
||||
xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
|
@ -403,8 +403,13 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||
{
|
||||
if (clipboard->incr_starts)
|
||||
{
|
||||
BYTE *new_data;
|
||||
|
||||
bytes_left = length * format_property / 8;
|
||||
clipboard->incr_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left);
|
||||
new_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left);
|
||||
if (!new_data)
|
||||
return FALSE;
|
||||
clipboard->incr_data = new_data;
|
||||
CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, bytes_left);
|
||||
clipboard->incr_data_length += bytes_left;
|
||||
XFree(data);
|
||||
|
@ -545,6 +545,7 @@ static BOOL xf_event_FocusOut(xfContext* xfc, XEvent* event, BOOL app)
|
||||
if (event->xfocus.mode == NotifyWhileGrabbed)
|
||||
XUngrabKeyboard(xfc->display, CurrentTime);
|
||||
|
||||
xf_keyboard_release_all_keypress(xfc);
|
||||
xf_keyboard_clear(xfc);
|
||||
|
||||
if (app)
|
||||
|
@ -173,6 +173,12 @@ void xf_keyboard_release_all_keypress(xfContext* xfc)
|
||||
if (xfc->KeyboardState[keycode] != NoSymbol)
|
||||
{
|
||||
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
|
||||
|
||||
// release tab before releasing the windows key.
|
||||
// this stops the start menu from opening on unfocus event.
|
||||
if (rdp_scancode == RDP_SCANCODE_LWIN)
|
||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, RDP_SCANCODE_TAB);
|
||||
|
||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
|
||||
xfc->KeyboardState[keycode] = NoSymbol;
|
||||
}
|
||||
|
@ -118,13 +118,17 @@ BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
|
||||
BOOL xf_detect_monitors(xfContext* xfc)
|
||||
{
|
||||
int i;
|
||||
int nmonitors;
|
||||
int primaryMonitor;
|
||||
int vWidth, vHeight;
|
||||
int nmonitors = 0;
|
||||
int primaryMonitorFound = FALSE;
|
||||
int vX, vY, vWidth, vHeight;
|
||||
int maxWidth, maxHeight;
|
||||
VIRTUAL_SCREEN* vscreen;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
|
||||
int mouse_x, mouse_y, _dummy_i;
|
||||
Window _dummy_w;
|
||||
int current_monitor = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
int major, minor;
|
||||
XineramaScreenInfo* screenInfo = NULL;
|
||||
@ -134,6 +138,12 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
xfc->desktopWidth = settings->DesktopWidth;
|
||||
xfc->desktopHeight = settings->DesktopHeight;
|
||||
|
||||
/* get mouse location */
|
||||
if (!XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||
&_dummy_w, &_dummy_w, &mouse_x, &mouse_y,
|
||||
&_dummy_i, &_dummy_i, (void *) &_dummy_i))
|
||||
mouse_x = mouse_y = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
if (XineramaQueryExtension(xfc->display, &major, &minor))
|
||||
{
|
||||
@ -153,8 +163,12 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
|
||||
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
|
||||
|
||||
if ((screenInfo[i].x_org == 0) && (screenInfo[i].y_org == 0))
|
||||
vscreen->monitors[i].primary = TRUE;
|
||||
/* Determine which monitor that the mouse cursor is on */
|
||||
if ((mouse_x >= vscreen->monitors[i].area.left) &&
|
||||
(mouse_x <= vscreen->monitors[i].area.right) &&
|
||||
(mouse_y >= vscreen->monitors[i].area.top) &&
|
||||
(mouse_y <= vscreen->monitors[i].area.bottom))
|
||||
current_monitor = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,6 +177,9 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
}
|
||||
#endif
|
||||
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;
|
||||
|
||||
/* WORKAROUND: With Remote Application Mode - using NET_WM_WORKAREA
|
||||
* causes issues with the ability to fully size the window vertically
|
||||
* (the bottom of the window area is never updated). So, we just set
|
||||
@ -194,6 +211,16 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
{
|
||||
xfc->desktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100;
|
||||
xfc->desktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100;
|
||||
|
||||
/* If we have specific monitor information then limit the PercentScreen value
|
||||
* to only affect the current monitor vs. the entire desktop
|
||||
*/
|
||||
if (vscreen->nmonitors > 0)
|
||||
{
|
||||
settings->DesktopWidth = ((vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) / 100;
|
||||
settings->DesktopHeight = ((vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) / 100;
|
||||
}
|
||||
|
||||
maxWidth = xfc->desktopWidth;
|
||||
maxHeight = xfc->desktopHeight;
|
||||
}
|
||||
@ -206,30 +233,24 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon)
|
||||
return TRUE;
|
||||
|
||||
/* If single monitor fullscreen OR workarea without remote app */
|
||||
if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) ||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
{
|
||||
/* Select a single monitor */
|
||||
|
||||
if (settings->NumMonitorIds != 1)
|
||||
/* If no monitors were specified on the command-line then set the current monitor as active */
|
||||
if (!settings->NumMonitorIds)
|
||||
{
|
||||
settings->NumMonitorIds = 1;
|
||||
settings->MonitorIds[0] = 0;
|
||||
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
if (vscreen->monitors[i].primary)
|
||||
{
|
||||
settings->MonitorIds[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
settings->MonitorIds[0] = current_monitor;
|
||||
}
|
||||
|
||||
/* Always sets number of monitors from command-line to just 1.
|
||||
* If the monitor is invalid then we will default back to current monitor
|
||||
* later as a fallback. So, there is no need to validate command-line entry here.
|
||||
*/
|
||||
settings->NumMonitorIds = 1;
|
||||
}
|
||||
|
||||
nmonitors = 0;
|
||||
primaryMonitor = 0;
|
||||
|
||||
/* Create array of all active monitors by taking into account monitors requested on the command-line */
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
if (!xf_is_monitor_id_active(xfc, i))
|
||||
@ -239,43 +260,114 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top;
|
||||
settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, xfc->desktopWidth);
|
||||
settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, xfc->desktopHeight);
|
||||
settings->MonitorDefArray[nmonitors].is_primary = vscreen->monitors[i].primary;
|
||||
settings->MonitorDefArray[nmonitors].orig_screen = i;
|
||||
|
||||
primaryMonitor |= vscreen->monitors[i].primary;
|
||||
nmonitors++;
|
||||
}
|
||||
|
||||
/* If no monitor is active(bogus command-line monitor specification) - then lets try to fallback to go fullscreen on the current monitor only */
|
||||
if (nmonitors == 0 && vscreen->nmonitors > 0)
|
||||
{
|
||||
settings->MonitorDefArray[0].x = vscreen->monitors[current_monitor].area.left;
|
||||
settings->MonitorDefArray[0].y = vscreen->monitors[current_monitor].area.top;
|
||||
settings->MonitorDefArray[0].width = MIN(vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1, xfc->desktopWidth);
|
||||
settings->MonitorDefArray[0].height = MIN(vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1, xfc->desktopHeight);
|
||||
settings->MonitorDefArray[0].orig_screen = current_monitor;
|
||||
|
||||
nmonitors = 1;
|
||||
}
|
||||
|
||||
settings->MonitorCount = nmonitors;
|
||||
|
||||
vWidth = vHeight = 0;
|
||||
settings->DesktopPosX = maxWidth - 1;
|
||||
settings->DesktopPosY = maxHeight - 1;
|
||||
|
||||
for (i = 0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
settings->DesktopPosX = MIN(settings->DesktopPosX, settings->MonitorDefArray[i].x);
|
||||
settings->DesktopPosY = MIN(settings->DesktopPosY, settings->MonitorDefArray[i].y);
|
||||
|
||||
vWidth += settings->MonitorDefArray[i].width;
|
||||
vHeight = MAX(vHeight, settings->MonitorDefArray[i].height);
|
||||
}
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vWidth - 1;
|
||||
vscreen->area.top = 0;
|
||||
vscreen->area.bottom = vHeight - 1;
|
||||
|
||||
if (settings->Workarea)
|
||||
{
|
||||
vscreen->area.top = xfc->workArea.y;
|
||||
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
|
||||
}
|
||||
|
||||
if (nmonitors && !primaryMonitor)
|
||||
settings->MonitorDefArray[0].is_primary = TRUE;
|
||||
|
||||
/* If we have specific monitor information */
|
||||
if (settings->MonitorCount)
|
||||
{
|
||||
/* Initialize bounding rectangle for all monitors */
|
||||
vWidth = settings->MonitorDefArray[0].width;
|
||||
vHeight = settings->MonitorDefArray[0].height;
|
||||
vX = settings->MonitorDefArray[0].x;
|
||||
vY = settings->MonitorDefArray[0].y;
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen;
|
||||
|
||||
/* Calculate bounding rectangle around all monitors to be used AND
|
||||
* also set the Xinerama indices which define left/top/right/bottom monitors.
|
||||
*/
|
||||
for (i = 1; i < settings->MonitorCount; i++)
|
||||
{
|
||||
/* does the same as gdk_rectangle_union */
|
||||
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
||||
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
||||
int destWidth = MAX(vX + vWidth, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width) - destX;
|
||||
int destHeight = MAX(vY + vHeight, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height) - destY;
|
||||
|
||||
if (vX != destX)
|
||||
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vY != destY)
|
||||
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vWidth != destWidth)
|
||||
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vHeight != destHeight)
|
||||
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
vX = destX;
|
||||
vY = destY;
|
||||
vWidth = destWidth;
|
||||
vHeight = destHeight;
|
||||
}
|
||||
|
||||
settings->DesktopPosX = vX;
|
||||
settings->DesktopPosY = vY;
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vWidth - 1;
|
||||
vscreen->area.top = 0;
|
||||
vscreen->area.bottom = vHeight - 1;
|
||||
|
||||
if (settings->Workarea)
|
||||
{
|
||||
vscreen->area.top = xfc->workArea.y;
|
||||
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
|
||||
}
|
||||
|
||||
/* If there are multiple monitors and we have not selected a primary */
|
||||
if (!primaryMonitorFound)
|
||||
{
|
||||
/* First lets try to see if there is a monitor with a 0,0 coordinate */
|
||||
for (i=0; i<settings->MonitorCount; i++)
|
||||
{
|
||||
if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0 && settings->MonitorDefArray[i].y == 0)
|
||||
{
|
||||
settings->MonitorDefArray[i].is_primary = TRUE;
|
||||
settings->MonitorLocalShiftX = settings->MonitorDefArray[i].x;
|
||||
settings->MonitorLocalShiftY = settings->MonitorDefArray[i].y;
|
||||
primaryMonitorFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still do not have a primary monitor then just arbitrarily choose first monitor */
|
||||
if (!primaryMonitorFound)
|
||||
{
|
||||
settings->MonitorDefArray[0].is_primary = TRUE;
|
||||
settings->MonitorLocalShiftX = settings->MonitorDefArray[0].x;
|
||||
settings->MonitorLocalShiftY = settings->MonitorDefArray[0].y;
|
||||
primaryMonitorFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtract monitor shift from monitor variables for server-side use.
|
||||
* We maintain monitor shift value as Window requires the primary monitor to have a coordinate of 0,0
|
||||
* In some X configurations, no monitor may have a coordinate of 0,0. This can also be happen if the user
|
||||
* requests specific monitors from the command-line as well. So, we make sure to translate our primary monitor's
|
||||
* upper-left corner to 0,0 on the server.
|
||||
*/
|
||||
for (i=0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX;
|
||||
settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
/* Set the desktop width and height according to the bounding rectangle around the active monitors */
|
||||
xfc->desktopWidth = vscreen->area.right - vscreen->area.left + 1;
|
||||
xfc->desktopHeight = vscreen->area.bottom - vscreen->area.top + 1;
|
||||
}
|
||||
|
@ -139,19 +139,57 @@ void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int n
|
||||
|
||||
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
{
|
||||
if (fullscreen)
|
||||
int i;
|
||||
int startX = xfc->instance->settings->DesktopPosX;
|
||||
int startY = xfc->instance->settings->DesktopPosY;
|
||||
|
||||
window->decorations = xfc->decorations;
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
|
||||
/* Determine the x,y starting location for the fullscreen window */
|
||||
if (xfc->instance->settings->MonitorCount)
|
||||
{
|
||||
rdpSettings* settings = xfc->settings;
|
||||
/* Initialize startX and startY with reasonable values */
|
||||
startX = xfc->instance->settings->MonitorDefArray[0].x;
|
||||
startY = xfc->instance->settings->MonitorDefArray[0].y;
|
||||
|
||||
xf_SetWindowDecorations(xfc, window->handle, FALSE);
|
||||
/* Search all monitors to find the lowest startX and startY values */
|
||||
for (i=0; i < xfc->instance->settings->MonitorCount; i++)
|
||||
{
|
||||
startX = MIN(startX, xfc->instance->settings->MonitorDefArray[i].x);
|
||||
startY = MIN(startY, xfc->instance->settings->MonitorDefArray[i].y);
|
||||
}
|
||||
|
||||
XMoveResizeWindow(xfc->display, window->handle,
|
||||
settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
|
||||
|
||||
XMapRaised(xfc->display, window->handle);
|
||||
|
||||
window->fullscreen = TRUE;
|
||||
/* Lastly apply any monitor shift(translation from remote to local coordinate system)
|
||||
* to startX and startY values
|
||||
*/
|
||||
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
||||
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
XMoveResizeWindow(xfc->display, window->handle, startX, startY, window->width, window->height);
|
||||
XMapRaised(xfc->display, window->handle);
|
||||
|
||||
/* Set the fullscreen state */
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
|
||||
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
||||
|
||||
/* Only send monitor bounds if they are valid */
|
||||
if ((xfc->fullscreenMonitors.top >= 0) &&
|
||||
(xfc->fullscreenMonitors.bottom >= 0) &&
|
||||
(xfc->fullscreenMonitors.left >= 0) &&
|
||||
(xfc->fullscreenMonitors.right >= 0))
|
||||
{
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
||||
xfc->fullscreenMonitors.top,
|
||||
xfc->fullscreenMonitors.bottom,
|
||||
xfc->fullscreenMonitors.left,
|
||||
xfc->fullscreenMonitors.right,
|
||||
1);
|
||||
}
|
||||
|
||||
window->fullscreen = TRUE;
|
||||
}
|
||||
|
||||
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
|
||||
@ -283,7 +321,7 @@ static const char* get_shm_id()
|
||||
return shm_id;
|
||||
}
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations)
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height)
|
||||
{
|
||||
XEvent xevent;
|
||||
int input_mask;
|
||||
@ -303,7 +341,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
window->fullscreen = FALSE;
|
||||
window->decorations = decorations;
|
||||
window->decorations = xfc->decorations;
|
||||
window->is_mapped = FALSE;
|
||||
window->is_transient = FALSE;
|
||||
|
||||
@ -354,9 +392,15 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
}
|
||||
|
||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||
xf_SetWindowDecorations(xfc, window->handle, decorations);
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
xf_SetWindowPID(xfc, window->handle, 0);
|
||||
|
||||
/* Set the window hints to allow minimal resize, so fullscreen
|
||||
* changes can work in window managers that might disallow otherwise.
|
||||
* We will set back afterwards.
|
||||
*/
|
||||
xf_SetWindowSizeHints(xfc, window, TRUE, xfc->width, xfc->height);
|
||||
|
||||
input_mask =
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
||||
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
|
||||
@ -406,14 +450,20 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
}
|
||||
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height)
|
||||
{
|
||||
xf_SetWindowSizeHints(xfc, window, FALSE, width, height);
|
||||
}
|
||||
|
||||
void xf_SetWindowSizeHints(xfContext* xfc, xfWindow *window, BOOL can_resize, int width, int height)
|
||||
{
|
||||
XSizeHints* size_hints;
|
||||
size_hints = XAllocSizeHints();
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->flags = PMinSize | PMaxSize;
|
||||
size_hints->flags = PMinSize | PMaxSize | PWinGravity;
|
||||
|
||||
size_hints->win_gravity = NorthWestGravity;
|
||||
size_hints->min_width = size_hints->max_width = width;
|
||||
size_hints->min_height = size_hints->max_height = height;
|
||||
|
||||
@ -425,6 +475,17 @@ void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int hei
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allows the window to resize larger by 1 pixel - so we can
|
||||
* fullscreen the window with no worries about window manager disallowing based
|
||||
* on size parameters
|
||||
*/
|
||||
if (can_resize)
|
||||
{
|
||||
size_hints->width_inc = size_hints->height_inc = 1;
|
||||
size_hints->max_width = xfc->width + 1;
|
||||
size_hints->max_height = xfc->height + 1;
|
||||
}
|
||||
|
||||
XSetWMNormalHints(xfc->display, window->handle, size_hints);
|
||||
XResizeWindow(xfc->display, window->handle, width, height);
|
||||
XFree(size_hints);
|
||||
|
@ -46,6 +46,10 @@ typedef struct xf_window xfWindow;
|
||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
||||
|
||||
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
||||
|
||||
enum xf_localmove_state
|
||||
{
|
||||
LMS_NOT_ACTIVE,
|
||||
@ -143,8 +147,9 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen);
|
||||
void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show);
|
||||
void xf_SetWindowUnlisted(xfContext* xfc, Window window);
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations);
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height);
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height);
|
||||
void xf_SetWindowSizeHints(xfContext* xfc, xfWindow* window, BOOL can_resize, int width, int height);
|
||||
void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window);
|
||||
|
||||
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
|
||||
|
@ -38,6 +38,15 @@ typedef struct xf_context xfContext;
|
||||
#include <freerdp/codec/progressive.h>
|
||||
#include <freerdp/codec/region.h>
|
||||
|
||||
struct xf_FullscreenMonitors
|
||||
{
|
||||
UINT32 top;
|
||||
UINT32 bottom;
|
||||
UINT32 left;
|
||||
UINT32 right;
|
||||
};
|
||||
typedef struct xf_FullscreenMonitors xfFullscreenMonitors;
|
||||
|
||||
struct xf_WorkArea
|
||||
{
|
||||
UINT32 x;
|
||||
@ -111,6 +120,7 @@ struct xf_context
|
||||
xfAppWindow* appWindow;
|
||||
xfPointer* pointer;
|
||||
xfWorkArea workArea;
|
||||
xfFullscreenMonitors fullscreenMonitors;
|
||||
int current_desktop;
|
||||
BOOL remote_app;
|
||||
BOOL disconnect;
|
||||
@ -181,6 +191,8 @@ struct xf_context
|
||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||
|
||||
Atom _NET_WM_FULLSCREEN_MONITORS;
|
||||
|
||||
Atom _NET_WM_WINDOW_TYPE;
|
||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||
|
@ -544,10 +544,16 @@ static char** freerdp_command_line_parse_comma_separated_values(char* list, int*
|
||||
static char** freerdp_command_line_parse_comma_separated_values_offset(char* list, int* count)
|
||||
{
|
||||
char** p;
|
||||
char** t;
|
||||
|
||||
p = freerdp_command_line_parse_comma_separated_values(list, count);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p = (char**) realloc(p, sizeof(char*) * (*count + 1));
|
||||
t = (char**) realloc(p, sizeof(char*) * (*count + 1));
|
||||
if (!t)
|
||||
return NULL;
|
||||
p = t;
|
||||
MoveMemory(&p[1], p, sizeof(char*) * *count);
|
||||
(*count)++;
|
||||
|
||||
|
@ -308,8 +308,15 @@ 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*));
|
||||
int new_size;
|
||||
char **new_argv;
|
||||
|
||||
new_size = file->argSize * 2;
|
||||
new_argv = (char**) realloc(file->argv, new_size * sizeof(char*));
|
||||
if (!new_argv)
|
||||
return;
|
||||
file->argv = new_argv;
|
||||
file->argSize = new_size;
|
||||
}
|
||||
|
||||
file->argv[file->argc] = _strdup(option);
|
||||
@ -323,8 +330,15 @@ int freerdp_client_parse_rdp_file_add_line(rdpFile* file, char* line, int index)
|
||||
|
||||
while ((file->lineCount + 1) > file->lineSize)
|
||||
{
|
||||
file->lineSize *= 2;
|
||||
file->lines = (rdpFileLine*) realloc(file->lines, file->lineSize * sizeof(rdpFileLine));
|
||||
int new_size;
|
||||
rdpFileLine *new_line;
|
||||
|
||||
new_size = file->lineSize * 2;
|
||||
new_line = (rdpFileLine*) realloc(file->lines, new_size * sizeof(rdpFileLine));
|
||||
if (!new_line)
|
||||
return -1;
|
||||
file->lines = new_line;
|
||||
file->lineSize = new_size;
|
||||
}
|
||||
|
||||
ZeroMemory(&(file->lines[file->lineCount]), sizeof(rdpFileLine));
|
||||
|
@ -88,6 +88,11 @@ int TestClientCmdLine(int argc, char* argv[])
|
||||
char* cmd19[] = {"xfreerdp", "/monitor-list"};
|
||||
TESTCASE(cmd19, COMMAND_LINE_STATUS_PRINT);
|
||||
|
||||
#if 0
|
||||
char* cmd20[] = {"-z --plugin cliprdr --plugin rdpsnd --data alsa latency:100 -- --plugin rdpdr --data disk:w7share:/home/w7share -- --plugin drdynvc --data tsmf:decoder:gstreamer -- -u test host.example.com"};
|
||||
TESTCASE(cmd20, COMMAND_LINE_STATUS_PRINT);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -399,6 +399,7 @@ struct rdp_monitor
|
||||
INT32 width;
|
||||
INT32 height;
|
||||
UINT32 is_primary;
|
||||
UINT32 orig_screen;
|
||||
};
|
||||
typedef struct rdp_monitor rdpMonitor;
|
||||
|
||||
@ -897,7 +898,10 @@ struct rdp_settings
|
||||
ALIGN64 BOOL ListMonitors; /* 392 */
|
||||
ALIGN64 UINT32* MonitorIds; /* 393 */
|
||||
ALIGN64 UINT32 NumMonitorIds; /* 394 */
|
||||
UINT64 padding0448[448 - 395]; /* 395 */
|
||||
ALIGN64 UINT32 MonitorLocalShiftX; /*395 */
|
||||
ALIGN64 UINT32 MonitorLocalShiftY; /* 396 */
|
||||
UINT64 padding0448[448 - 397]; /* 397 */
|
||||
|
||||
|
||||
/* Client Message Channel Data */
|
||||
UINT64 padding0512[512 - 448]; /* 448 */
|
||||
|
@ -728,6 +728,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
|
||||
|
||||
context->quants = (UINT32 *)realloc((void*) context->quants, context->numQuant * 10 * sizeof(UINT32));
|
||||
if (!context->quants)
|
||||
return FALSE;
|
||||
|
||||
quants = context->quants;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
|
||||
{
|
||||
int i;
|
||||
char **new_argv;
|
||||
|
||||
for (i = 0; i < args->argc; i++)
|
||||
{
|
||||
@ -45,8 +46,11 @@ int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
|
||||
}
|
||||
}
|
||||
|
||||
new_argv = (char**) realloc(args->argv, sizeof(char*) * (args->argc + 1));
|
||||
if (!new_argv)
|
||||
return -1;
|
||||
args->argv = new_argv;
|
||||
args->argc++;
|
||||
args->argv = (char**) realloc(args->argv, sizeof(char*) * args->argc);
|
||||
args->argv[args->argc - 1] = _strdup(argument);
|
||||
|
||||
return 0;
|
||||
@ -55,6 +59,7 @@ int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
|
||||
int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous, char* argument)
|
||||
{
|
||||
int i;
|
||||
char **new_argv;
|
||||
|
||||
for (i = 0; i < args->argc; i++)
|
||||
{
|
||||
@ -67,8 +72,11 @@ int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous, char* argum
|
||||
}
|
||||
}
|
||||
|
||||
new_argv = (char**) realloc(args->argv, sizeof(char*) * (args->argc + 1));
|
||||
if (!new_argv)
|
||||
return -1;
|
||||
args->argv = new_argv;
|
||||
args->argc++;
|
||||
args->argv = (char**) realloc(args->argv, sizeof(char*) * args->argc);
|
||||
args->argv[args->argc - 1] = _strdup(argument);
|
||||
|
||||
return 0;
|
||||
@ -80,6 +88,7 @@ int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value
|
||||
char* p;
|
||||
char* str;
|
||||
int length;
|
||||
char **new_argv;
|
||||
|
||||
length = strlen(option) + strlen(value) + 1;
|
||||
str = (char*) malloc(length + 1);
|
||||
@ -101,8 +110,11 @@ int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value
|
||||
}
|
||||
}
|
||||
|
||||
new_argv = (char**) realloc(args->argv, sizeof(char*) * (args->argc + 1));
|
||||
if (!new_argv)
|
||||
return -1;
|
||||
args->argv = new_argv;
|
||||
args->argc++;
|
||||
args->argv = (char**) realloc(args->argv, sizeof(char*) * args->argc);
|
||||
args->argv[args->argc - 1] = str;
|
||||
|
||||
return 0;
|
||||
@ -113,6 +125,7 @@ int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char*
|
||||
int i;
|
||||
char* str;
|
||||
int length;
|
||||
char **new_argv;
|
||||
|
||||
length = strlen(option) + strlen(value) + 1;
|
||||
str = (char*) malloc(length + 1);
|
||||
@ -129,8 +142,11 @@ int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char*
|
||||
}
|
||||
}
|
||||
|
||||
new_argv = (char**) realloc(args->argv, sizeof(char*) * (args->argc + 1));
|
||||
if (!new_argv)
|
||||
return -1;
|
||||
args->argv = new_argv;
|
||||
args->argc++;
|
||||
args->argv = (char**) realloc(args->argv, sizeof(char*) * args->argc);
|
||||
args->argv[args->argc - 1] = str;
|
||||
|
||||
return 0;
|
||||
@ -138,11 +154,21 @@ int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char*
|
||||
|
||||
void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device)
|
||||
{
|
||||
if (!settings->DeviceArray)
|
||||
return;
|
||||
|
||||
if (settings->DeviceArraySize < (settings->DeviceCount + 1))
|
||||
{
|
||||
settings->DeviceArraySize *= 2;
|
||||
settings->DeviceArray = (RDPDR_DEVICE**)
|
||||
realloc(settings->DeviceArray, settings->DeviceArraySize * sizeof(RDPDR_DEVICE*));
|
||||
UINT32 new_size;
|
||||
RDPDR_DEVICE **new_array;
|
||||
|
||||
new_size = settings->DeviceArraySize * 2;
|
||||
new_array = (RDPDR_DEVICE**)
|
||||
realloc(settings->DeviceArray, new_size * sizeof(RDPDR_DEVICE*));
|
||||
if (!new_array)
|
||||
return;
|
||||
settings->DeviceArray = new_array;
|
||||
settings->DeviceArraySize = new_size;
|
||||
}
|
||||
|
||||
settings->DeviceArray[settings->DeviceCount++] = device;
|
||||
@ -391,11 +417,21 @@ void freerdp_device_collection_free(rdpSettings* settings)
|
||||
|
||||
void freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
|
||||
{
|
||||
if (!settings->StaticChannelArray)
|
||||
return;
|
||||
|
||||
if (settings->StaticChannelArraySize < (settings->StaticChannelCount + 1))
|
||||
{
|
||||
settings->StaticChannelArraySize *= 2;
|
||||
settings->StaticChannelArray = (ADDIN_ARGV**)
|
||||
realloc(settings->StaticChannelArray, settings->StaticChannelArraySize * sizeof(ADDIN_ARGV*));
|
||||
UINT32 new_size;
|
||||
ADDIN_ARGV **new_array;
|
||||
|
||||
new_size = settings->StaticChannelArraySize * 2;
|
||||
new_array = (ADDIN_ARGV**)
|
||||
realloc(settings->StaticChannelArray, new_size * sizeof(ADDIN_ARGV*));
|
||||
if (!new_array)
|
||||
return;
|
||||
settings->StaticChannelArray = new_array;
|
||||
settings->StaticChannelArraySize = new_size;
|
||||
}
|
||||
|
||||
settings->StaticChannelArray[settings->StaticChannelCount++] = channel;
|
||||
@ -471,11 +507,24 @@ void freerdp_static_channel_collection_free(rdpSettings* settings)
|
||||
|
||||
void freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
|
||||
{
|
||||
if (!settings->DynamicChannelArray)
|
||||
return;
|
||||
|
||||
if (settings->DynamicChannelArraySize < (settings->DynamicChannelCount + 1))
|
||||
{
|
||||
settings->DynamicChannelArraySize *= 2;
|
||||
settings->DynamicChannelArray = (ADDIN_ARGV**)
|
||||
realloc(settings->DynamicChannelArray, settings->DynamicChannelArraySize * sizeof(ADDIN_ARGV*));
|
||||
UINT32 new_size;
|
||||
ADDIN_ARGV **new_array;
|
||||
|
||||
new_size = settings->DynamicChannelArraySize * 2;
|
||||
new_array = (ADDIN_ARGV**)
|
||||
realloc(settings->DynamicChannelArray, new_size * sizeof(ADDIN_ARGV*));
|
||||
if (!new_array)
|
||||
return;
|
||||
settings->DynamicChannelArray = new_array;
|
||||
settings->DynamicChannelArraySize = new_size;
|
||||
}
|
||||
|
||||
settings->DynamicChannelArray[settings->DynamicChannelCount++] = channel;
|
||||
|
@ -1314,24 +1314,28 @@ BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER
|
||||
BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline)
|
||||
{
|
||||
UINT16 word;
|
||||
UINT32 new_num;
|
||||
|
||||
ORDER_FIELD_COORD(1, polyline->xStart);
|
||||
ORDER_FIELD_COORD(2, polyline->yStart);
|
||||
ORDER_FIELD_BYTE(3, polyline->bRop2);
|
||||
ORDER_FIELD_UINT16(4, word);
|
||||
ORDER_FIELD_COLOR(5, polyline->penColor);
|
||||
ORDER_FIELD_BYTE(6, polyline->numDeltaEntries);
|
||||
ORDER_FIELD_BYTE(6, new_num);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_07)
|
||||
{
|
||||
DELTA_POINT *new_points;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
Stream_Read_UINT8(s, polyline->cbData);
|
||||
|
||||
if (polyline->points == NULL)
|
||||
polyline->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polyline->numDeltaEntries);
|
||||
else
|
||||
polyline->points = (DELTA_POINT*) realloc(polyline->points, sizeof(DELTA_POINT) * polyline->numDeltaEntries);
|
||||
new_points = (DELTA_POINT*) realloc(polyline->points, sizeof(DELTA_POINT) * new_num);
|
||||
if (!new_points)
|
||||
return FALSE;
|
||||
polyline->points = new_points;
|
||||
polyline->numDeltaEntries = new_num;
|
||||
|
||||
return update_read_delta_points(s, polyline->points, polyline->numDeltaEntries, polyline->xStart, polyline->yStart);
|
||||
}
|
||||
@ -1661,6 +1665,7 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_
|
||||
|
||||
if (fastGlyph->cbData > 1)
|
||||
{
|
||||
UINT32 new_cb;
|
||||
/* parse optional glyph data */
|
||||
glyph->cacheIndex = fastGlyph->data[0];
|
||||
|
||||
@ -1673,12 +1678,20 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_
|
||||
glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy;
|
||||
glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < glyph->cb)
|
||||
new_cb = ((glyph->cx + 7) / 8) * glyph->cy;
|
||||
new_cb += ((new_cb % 4) > 0) ? 4 - (new_cb % 4) : 0;
|
||||
if (Stream_GetRemainingLength(s) < new_cb)
|
||||
return FALSE;
|
||||
|
||||
if (glyph->cb)
|
||||
if (new_cb)
|
||||
{
|
||||
glyph->aj = (BYTE*) realloc(glyph->aj, glyph->cb);
|
||||
BYTE *new_aj;
|
||||
new_aj = (BYTE*) realloc(glyph->aj, new_cb);
|
||||
if (!new_aj)
|
||||
return FALSE;
|
||||
|
||||
glyph->aj = new_aj;
|
||||
glyph->cb = new_cb;
|
||||
Stream_Read(s, glyph->aj, glyph->cb);
|
||||
}
|
||||
}
|
||||
@ -1701,24 +1714,30 @@ BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH
|
||||
|
||||
BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
UINT32 num;
|
||||
|
||||
ORDER_FIELD_COORD(1, polygon_sc->xStart);
|
||||
ORDER_FIELD_COORD(2, polygon_sc->yStart);
|
||||
ORDER_FIELD_BYTE(3, polygon_sc->bRop2);
|
||||
ORDER_FIELD_BYTE(4, polygon_sc->fillMode);
|
||||
ORDER_FIELD_COLOR(5, polygon_sc->brushColor);
|
||||
ORDER_FIELD_BYTE(6, polygon_sc->numPoints);
|
||||
ORDER_FIELD_BYTE(6, num);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_07)
|
||||
{
|
||||
DELTA_POINT *newpoints;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, polygon_sc->cbData);
|
||||
|
||||
if (!polygon_sc->points)
|
||||
polygon_sc->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
else
|
||||
polygon_sc->points = (DELTA_POINT*) realloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
newpoints = (DELTA_POINT*) realloc(polygon_sc->points, sizeof(DELTA_POINT) * num);
|
||||
if (!newpoints)
|
||||
return FALSE;
|
||||
|
||||
polygon_sc->points = newpoints;
|
||||
polygon_sc->numPoints = num;
|
||||
|
||||
return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart);
|
||||
}
|
||||
@ -1738,6 +1757,8 @@ BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC
|
||||
|
||||
BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
UINT32 num;
|
||||
|
||||
ORDER_FIELD_COORD(1, polygon_cb->xStart);
|
||||
ORDER_FIELD_COORD(2, polygon_cb->yStart);
|
||||
ORDER_FIELD_BYTE(3, polygon_cb->bRop2);
|
||||
@ -1748,20 +1769,23 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_
|
||||
if (!update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6))
|
||||
return FALSE;
|
||||
|
||||
ORDER_FIELD_BYTE(12, polygon_cb->numPoints);
|
||||
ORDER_FIELD_BYTE(12, num);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_13)
|
||||
{
|
||||
DELTA_POINT *newpoints;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, polygon_cb->cbData);
|
||||
|
||||
if (!polygon_cb->points)
|
||||
polygon_cb->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
else
|
||||
polygon_cb->points = (DELTA_POINT*) realloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
newpoints = (DELTA_POINT*) realloc(polygon_cb->points, sizeof(DELTA_POINT) * num);
|
||||
if (!newpoints)
|
||||
return FALSE;
|
||||
|
||||
polygon_cb->points = newpoints;
|
||||
polygon_cb->numPoints = num;
|
||||
if (!update_read_delta_points(s, polygon_cb->points, polygon_cb->numPoints, polygon_cb->xStart, polygon_cb->yStart))
|
||||
return FALSE;
|
||||
}
|
||||
@ -2065,6 +2089,8 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_
|
||||
{
|
||||
BYTE bitsPerPixelId;
|
||||
BITMAP_DATA_EX* bitmapData;
|
||||
UINT32 new_len;
|
||||
BYTE *new_data;
|
||||
|
||||
cache_bitmap_v3->cacheId = flags & 0x00000003;
|
||||
cache_bitmap_v3->flags = (flags & 0x0000FF80) >> 7;
|
||||
@ -2092,16 +2118,16 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_
|
||||
Stream_Read_UINT8(s, bitmapData->codecID); /* codecID (1 byte) */
|
||||
Stream_Read_UINT16(s, bitmapData->width); /* width (2 bytes) */
|
||||
Stream_Read_UINT16(s, bitmapData->height); /* height (2 bytes) */
|
||||
Stream_Read_UINT32(s, bitmapData->length); /* length (4 bytes) */
|
||||
Stream_Read_UINT32(s, new_len); /* length (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < bitmapData->length)
|
||||
if (Stream_GetRemainingLength(s) < new_len)
|
||||
return FALSE;
|
||||
|
||||
if (bitmapData->data == NULL)
|
||||
bitmapData->data = (BYTE*) malloc(bitmapData->length);
|
||||
else
|
||||
bitmapData->data = (BYTE*) realloc(bitmapData->data, bitmapData->length);
|
||||
|
||||
new_data = (BYTE*) realloc(bitmapData->data, new_len);
|
||||
if (!new_data)
|
||||
return FALSE;
|
||||
bitmapData->data = new_data;
|
||||
bitmapData->length = new_len;
|
||||
Stream_Read(s, bitmapData->data, bitmapData->length);
|
||||
|
||||
return TRUE;
|
||||
@ -2596,8 +2622,14 @@ BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITM
|
||||
|
||||
if (deleteList->cIndices > deleteList->sIndices)
|
||||
{
|
||||
UINT16 *new_indices;
|
||||
|
||||
new_indices = (UINT16 *)realloc(deleteList->indices, deleteList->cIndices);
|
||||
if (!new_indices)
|
||||
return FALSE;
|
||||
|
||||
deleteList->sIndices = deleteList->cIndices;
|
||||
deleteList->indices = realloc(deleteList->indices, deleteList->sIndices * 2);
|
||||
deleteList->indices = new_indices;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2 * deleteList->cIndices)
|
||||
|
@ -273,6 +273,8 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
settings->MonitorCount = 0;
|
||||
settings->MonitorDefArraySize = 32;
|
||||
settings->MonitorDefArray = (rdpMonitor*) calloc(settings->MonitorDefArraySize, sizeof(rdpMonitor));
|
||||
settings->MonitorLocalShiftX = 0;
|
||||
settings->MonitorLocalShiftY = 0;
|
||||
|
||||
settings->MonitorIds = (UINT32*) calloc(16, sizeof(UINT32));
|
||||
|
||||
|
@ -172,11 +172,16 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bit
|
||||
if (bitmapUpdate->number > bitmapUpdate->count)
|
||||
{
|
||||
UINT16 count;
|
||||
BITMAP_DATA *newdata;
|
||||
|
||||
count = bitmapUpdate->number * 2;
|
||||
|
||||
bitmapUpdate->rectangles = (BITMAP_DATA*) realloc(bitmapUpdate->rectangles,
|
||||
newdata = (BITMAP_DATA*) realloc(bitmapUpdate->rectangles,
|
||||
sizeof(BITMAP_DATA) * count);
|
||||
if (!newdata)
|
||||
return FALSE;
|
||||
|
||||
bitmapUpdate->rectangles = newdata;
|
||||
|
||||
ZeroMemory(&bitmapUpdate->rectangles[bitmapUpdate->count],
|
||||
sizeof(BITMAP_DATA) * (count - bitmapUpdate->count));
|
||||
|
@ -32,19 +32,23 @@
|
||||
|
||||
static BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
UINT16 new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, unicode_string->length); /* cbString (2 bytes) */
|
||||
Stream_Read_UINT16(s, new_len); /* cbString (2 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < unicode_string->length)
|
||||
if (Stream_GetRemainingLength(s) < new_len)
|
||||
return FALSE;
|
||||
|
||||
if (!unicode_string->string)
|
||||
unicode_string->string = (BYTE*) malloc(unicode_string->length);
|
||||
else
|
||||
unicode_string->string = (BYTE*) realloc(unicode_string->string, unicode_string->length);
|
||||
new_str = (BYTE*) realloc(unicode_string->string, new_len);
|
||||
if (!new_str)
|
||||
return FALSE;
|
||||
|
||||
unicode_string->string = new_str;
|
||||
unicode_string->length = new_len;
|
||||
Stream_Read(s, unicode_string->string, unicode_string->length);
|
||||
|
||||
return TRUE;
|
||||
@ -108,7 +112,12 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
|
||||
}
|
||||
else if (iconInfo->cbColorTable)
|
||||
{
|
||||
iconInfo->colorTable = (BYTE*) realloc(iconInfo->colorTable, iconInfo->cbColorTable);
|
||||
BYTE *new_tab;
|
||||
|
||||
new_tab = (BYTE*) realloc(iconInfo->colorTable, iconInfo->cbColorTable);
|
||||
if (!new_tab)
|
||||
return FALSE;
|
||||
iconInfo->colorTable = new_tab;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -476,6 +485,8 @@ BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO*
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
|
||||
{
|
||||
UINT32 *newid;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
@ -486,10 +497,9 @@ BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO*
|
||||
|
||||
size = sizeof(UINT32) * monitored_desktop->numWindowIds;
|
||||
|
||||
if (monitored_desktop->windowIds == NULL)
|
||||
monitored_desktop->windowIds = (UINT32*) malloc(size);
|
||||
else
|
||||
monitored_desktop->windowIds = (UINT32*) realloc(monitored_desktop->windowIds, size);
|
||||
newid = (UINT32*) realloc(monitored_desktop->windowIds, size);
|
||||
if (!newid)
|
||||
return FALSE;
|
||||
|
||||
/* windowIds */
|
||||
for (i = 0; i < (int) monitored_desktop->numWindowIds; i++)
|
||||
|
@ -523,7 +523,7 @@ BOOL x509_verify_certificate(CryptoCert cert, char* certificate_store_path)
|
||||
|
||||
if (certificate_store_path != NULL)
|
||||
{
|
||||
X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_ASN1);
|
||||
X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_PEM);
|
||||
}
|
||||
|
||||
csc = X509_STORE_CTX_new();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
@ -924,7 +925,7 @@ BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
||||
{
|
||||
if (strlen(hostname) == pattern_length)
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0)
|
||||
if (_strnicmp( hostname, pattern, pattern_length) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -932,7 +933,7 @@ BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
||||
{
|
||||
char* check_hostname = &hostname[strlen(hostname) - pattern_length + 1];
|
||||
|
||||
if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0)
|
||||
if (_strnicmp( check_hostname, &pattern[1], pattern_length - 1) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@ -1000,8 +1001,15 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
pemCert = (BYTE*) realloc(pemCert, length + 1);
|
||||
int new_len;
|
||||
BYTE *new_cert;
|
||||
|
||||
new_len = length * 2;
|
||||
new_cert = (BYTE*) realloc(pemCert, new_len + 1);
|
||||
if (!new_cert)
|
||||
return -1;
|
||||
length = new_len;
|
||||
pemCert = new_cert;
|
||||
|
||||
status = BIO_read(bio, &pemCert[offset], length);
|
||||
|
||||
|
@ -384,8 +384,15 @@ INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h)
|
||||
|
||||
if ((hdc->hwnd->ninvalid + 1) > hdc->hwnd->count)
|
||||
{
|
||||
hdc->hwnd->count *= 2;
|
||||
cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count));
|
||||
int new_cnt;
|
||||
HGDI_RGN new_rgn;
|
||||
|
||||
new_cnt = hdc->hwnd->count * 2;
|
||||
new_rgn = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * new_cnt);
|
||||
if (!new_rgn)
|
||||
return -1;
|
||||
hdc->hwnd->count = new_cnt;
|
||||
cinvalid = new_rgn;
|
||||
}
|
||||
|
||||
gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h);
|
||||
|
@ -225,15 +225,24 @@ RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types)
|
||||
{
|
||||
int num, length, i;
|
||||
RDP_KEYBOARD_LAYOUT* layouts;
|
||||
RDP_KEYBOARD_LAYOUT* new;
|
||||
|
||||
num = 0;
|
||||
layouts = (RDP_KEYBOARD_LAYOUT*) malloc((num + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
if (!layouts)
|
||||
return NULL;
|
||||
|
||||
if ((types & RDP_KEYBOARD_LAYOUT_TYPE_STANDARD) != 0)
|
||||
{
|
||||
length = ARRAYSIZE(RDP_KEYBOARD_LAYOUT_TABLE);
|
||||
layouts = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
new = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
if (!new)
|
||||
{
|
||||
free(layouts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layouts = new;
|
||||
for (i = 0; i < length; i++, num++)
|
||||
{
|
||||
layouts[num].code = RDP_KEYBOARD_LAYOUT_TABLE[i].code;
|
||||
@ -243,8 +252,14 @@ RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types)
|
||||
if ((types & RDP_KEYBOARD_LAYOUT_TYPE_VARIANT) != 0)
|
||||
{
|
||||
length = ARRAYSIZE(RDP_KEYBOARD_LAYOUT_VARIANT_TABLE);
|
||||
layouts = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
new = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
if (!new)
|
||||
{
|
||||
free(layouts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layouts = new;
|
||||
for (i = 0; i < length; i++, num++)
|
||||
{
|
||||
layouts[num].code = RDP_KEYBOARD_LAYOUT_VARIANT_TABLE[i].code;
|
||||
@ -254,8 +269,14 @@ RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types)
|
||||
if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0)
|
||||
{
|
||||
length = ARRAYSIZE(RDP_KEYBOARD_IME_TABLE);
|
||||
layouts = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
new = (RDP_KEYBOARD_LAYOUT*) realloc(layouts, (num + length + 1) * sizeof(RDP_KEYBOARD_LAYOUT));
|
||||
if (!new)
|
||||
{
|
||||
free(layouts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
layouts = new;
|
||||
for (i = 0; i < length; i++, num++)
|
||||
{
|
||||
layouts[num].code = RDP_KEYBOARD_IME_TABLE[i].code;
|
||||
|
@ -71,9 +71,19 @@ static COMM_DEVICE **_CommDevices = NULL;
|
||||
static CRITICAL_SECTION _CommDevicesLock;
|
||||
|
||||
static HANDLE_CREATOR *_CommHandleCreator = NULL;
|
||||
static HANDLE_CLOSE_CB *_CommHandleCloseCb = NULL;
|
||||
|
||||
static pthread_once_t _CommInitialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static int CommGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_COMM *comm = (WINPR_COMM *)handle;
|
||||
|
||||
if (!CommIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return comm->fd;
|
||||
}
|
||||
|
||||
static void _CommInit()
|
||||
{
|
||||
/* NB: error management to be done outside of this function */
|
||||
@ -81,7 +91,6 @@ static void _CommInit()
|
||||
assert(_Log == NULL);
|
||||
assert(_CommDevices == NULL);
|
||||
assert(_CommHandleCreator == NULL);
|
||||
assert(_CommHandleCloseCb == NULL);
|
||||
|
||||
_Log = WLog_Get("com.winpr.comm");
|
||||
|
||||
@ -97,19 +106,9 @@ static void _CommInit()
|
||||
RegisterHandleCreator(_CommHandleCreator);
|
||||
}
|
||||
|
||||
_CommHandleCloseCb = (HANDLE_CLOSE_CB*)malloc(sizeof(HANDLE_CLOSE_CB));
|
||||
if (_CommHandleCloseCb)
|
||||
{
|
||||
_CommHandleCloseCb->IsHandled = CommIsHandled;
|
||||
_CommHandleCloseCb->CloseHandle = CommCloseHandle;
|
||||
|
||||
RegisterHandleCloseCb(_CommHandleCloseCb);
|
||||
}
|
||||
|
||||
assert(_Log != NULL);
|
||||
assert(_CommDevices != NULL);
|
||||
assert(_CommHandleCreator != NULL);
|
||||
assert(_CommHandleCloseCb != NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -1321,6 +1320,10 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
|
||||
|
||||
WINPR_HANDLE_SET_TYPE(pComm, HANDLE_TYPE_COMM);
|
||||
|
||||
pComm->cb.GetFd = CommGetFd;
|
||||
pComm->cb.CloseHandle = CommCloseHandle;
|
||||
pComm->cb.IsHandled = CommIsHandled;
|
||||
|
||||
/* error_handle */
|
||||
|
||||
pComm->fd = open(devicePath, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
@ -1452,7 +1455,6 @@ BOOL CommIsHandled(HANDLE handle)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CommCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_COMM *pComm;
|
||||
|
@ -91,7 +91,7 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
UCHAR vmin = 0;
|
||||
UCHAR vtime = 0;
|
||||
ULONGLONG Tmax = 0;
|
||||
struct timeval tmaxTimeout;
|
||||
struct timeval tmaxTimeout, *pTmaxTimeout;
|
||||
struct termios currentTermios;
|
||||
|
||||
EnterCriticalSection(&pComm->ReadLock); /* KISSer by the function's beginning */
|
||||
@ -144,13 +144,13 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439614%28v=vs.85%29.aspx
|
||||
*
|
||||
* ReadIntervalTimeout | ReadTotalTimeoutMultiplier | ReadTotalTimeoutConstant | VMIN | VTIME | TMAX |
|
||||
* 0 | 0 | 0 | N | 0 | 0 | Blocks for N bytes available.
|
||||
* 0< Ti <MAXULONG | 0 | 0 | N | Ti | 0 | Block on first byte, then use Ti between bytes.
|
||||
* 0 | 0 | 0 | N | 0 | INDEF | Blocks for N bytes available.
|
||||
* 0< Ti <MAXULONG | 0 | 0 | N | Ti | INDEF | Blocks on first byte, then use Ti between bytes.
|
||||
* MAXULONG | 0 | 0 | 0 | 0 | 0 | Returns immediately with bytes available (don't block)
|
||||
* MAXULONG | MAXULONG | 0< Tc <MAXULONG | N | 0 | Tc | Blocks on first byte during Tc or returns immediately whith bytes available
|
||||
* MAXULONG | m | MAXULONG | | Invalid
|
||||
* 0 | m | 0< Tc <MAXULONG | N | 0 | Tmax | Block on first byte during Tmax or returns immediately whith bytes available
|
||||
* 0< Ti <MAXULONG | m | 0< Tc <MAXULONG | N | Ti | Tmax | Block on first byte, then use Ti between bytes. Tmax is use for the whole system call.
|
||||
* 0 | m | 0< Tc <MAXULONG | N | 0 | Tmax | Blocks on first byte during Tmax or returns immediately whith bytes available
|
||||
* 0< Ti <MAXULONG | m | 0< Tc <MAXULONG | N | Ti | Tmax | Blocks on first byte, then use Ti between bytes. Tmax is used for the whole system call.
|
||||
*/
|
||||
|
||||
/* NB: timeouts are in milliseconds, VTIME are in deciseconds and is an unsigned char */
|
||||
@ -195,6 +195,8 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
|
||||
/* TMAX */
|
||||
|
||||
pTmaxTimeout = &tmaxTimeout;
|
||||
|
||||
if ((pTimeouts->ReadIntervalTimeout == MAXULONG) && (pTimeouts->ReadTotalTimeoutMultiplier == MAXULONG))
|
||||
{
|
||||
/* Tc */
|
||||
@ -204,6 +206,10 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
{
|
||||
/* Tmax */
|
||||
Tmax = nNumberOfBytesToRead * pTimeouts->ReadTotalTimeoutMultiplier + pTimeouts->ReadTotalTimeoutConstant;
|
||||
|
||||
/* INDEFinitely */
|
||||
if((Tmax == 0) && (pTimeouts->ReadIntervalTimeout < MAXULONG) && (pTimeouts->ReadTotalTimeoutMultiplier == 0))
|
||||
pTmaxTimeout = NULL;
|
||||
}
|
||||
|
||||
if ((currentTermios.c_cc[VMIN] != vmin) || (currentTermios.c_cc[VTIME] != vtime))
|
||||
@ -219,11 +225,16 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
}
|
||||
}
|
||||
|
||||
ZeroMemory(&tmaxTimeout, sizeof(struct timeval));
|
||||
if (Tmax > 0) /* no timeout if Tmax == 0 */
|
||||
/* wait indefinitely if pTmaxTimeout is NULL */
|
||||
|
||||
if(pTmaxTimeout != NULL)
|
||||
{
|
||||
tmaxTimeout.tv_sec = Tmax / 1000; /* s */
|
||||
tmaxTimeout.tv_usec = (Tmax % 1000) * 1000; /* us */
|
||||
ZeroMemory(pTmaxTimeout, sizeof(struct timeval));
|
||||
if (Tmax > 0) /* return immdiately if Tmax == 0 */
|
||||
{
|
||||
pTmaxTimeout->tv_sec = Tmax / 1000; /* s */
|
||||
pTmaxTimeout->tv_usec = (Tmax % 1000) * 1000; /* us */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -244,7 +255,7 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
FD_SET(pComm->fd_read_event, &read_set);
|
||||
FD_SET(pComm->fd_read, &read_set);
|
||||
|
||||
nbFds = select(biggestFd+1, &read_set, NULL, NULL, &tmaxTimeout);
|
||||
nbFds = select(biggestFd+1, &read_set, NULL, NULL, pTmaxTimeout);
|
||||
if (nbFds < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "select() failure, errno=[%d] %s\n", errno, strerror(errno));
|
||||
@ -358,7 +369,7 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
WINPR_COMM* pComm = (WINPR_COMM*) hDevice;
|
||||
struct timeval tmaxTimeout;
|
||||
struct timeval tmaxTimeout, *pTmaxTimeout;
|
||||
|
||||
EnterCriticalSection(&pComm->WriteLock); /* KISSer by the function's beginning */
|
||||
|
||||
@ -406,13 +417,18 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite
|
||||
* how much time was left. Keep the timeout variable out of
|
||||
* the while() */
|
||||
|
||||
|
||||
ZeroMemory(&tmaxTimeout, sizeof(struct timeval));
|
||||
if (Tmax > 0) /* no timeout if Tmax == 0 */
|
||||
pTmaxTimeout = &tmaxTimeout;
|
||||
ZeroMemory(pTmaxTimeout, sizeof(struct timeval));
|
||||
if (Tmax > 0)
|
||||
{
|
||||
tmaxTimeout.tv_sec = Tmax / 1000; /* s */
|
||||
tmaxTimeout.tv_usec = (Tmax % 1000) * 1000; /* us */
|
||||
pTmaxTimeout->tv_sec = Tmax / 1000; /* s */
|
||||
pTmaxTimeout->tv_usec = (Tmax % 1000) * 1000; /* us */
|
||||
}
|
||||
else if ((pComm->timeouts.WriteTotalTimeoutMultiplier == 0) && (pComm->timeouts.WriteTotalTimeoutConstant == 0))
|
||||
{
|
||||
pTmaxTimeout = NULL;
|
||||
}
|
||||
/* else return immdiately */
|
||||
|
||||
while (*lpNumberOfBytesWritten < nNumberOfBytesToWrite)
|
||||
{
|
||||
@ -433,7 +449,7 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite
|
||||
FD_SET(pComm->fd_write_event, &event_set);
|
||||
FD_SET(pComm->fd_write, &write_set);
|
||||
|
||||
nbFds = select(biggestFd+1, &event_set, &write_set, NULL, &tmaxTimeout);
|
||||
nbFds = select(biggestFd+1, &event_set, &write_set, NULL, pTmaxTimeout);
|
||||
if (nbFds < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "select() failure, errno=[%d] %s\n", errno, strerror(errno));
|
||||
|
@ -849,6 +849,12 @@ static BOOL _set_timeouts(WINPR_COMM *pComm, const SERIAL_TIMEOUTS *pTimeouts)
|
||||
pComm->timeouts.WriteTotalTimeoutMultiplier = pTimeouts->WriteTotalTimeoutMultiplier;
|
||||
pComm->timeouts.WriteTotalTimeoutConstant = pTimeouts->WriteTotalTimeoutConstant;
|
||||
|
||||
CommLog_Print(WLOG_DEBUG, "ReadIntervalTimeout %d", pComm->timeouts.ReadIntervalTimeout);
|
||||
CommLog_Print(WLOG_DEBUG, "ReadTotalTimeoutMultiplier %d", pComm->timeouts.ReadTotalTimeoutMultiplier);
|
||||
CommLog_Print(WLOG_DEBUG, "ReadTotalTimeoutConstant %d", pComm->timeouts.ReadTotalTimeoutConstant);
|
||||
CommLog_Print(WLOG_DEBUG, "WriteTotalTimeoutMultiplier %d", pComm->timeouts.WriteTotalTimeoutMultiplier);
|
||||
CommLog_Print(WLOG_DEBUG, "WriteTotalTimeoutConstant %d", pComm->timeouts.WriteTotalTimeoutConstant);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,8 @@ LPCH GetEnvironmentStrings(VOID)
|
||||
|
||||
cchEnvironmentBlock = 128;
|
||||
lpszEnvironmentBlock = (LPCH) malloc(cchEnvironmentBlock * sizeof(CHAR));
|
||||
if (!lpszEnvironmentBlock)
|
||||
return NULL;
|
||||
|
||||
while (*envp)
|
||||
{
|
||||
@ -237,8 +239,19 @@ LPCH GetEnvironmentStrings(VOID)
|
||||
|
||||
while ((offset + length + 8) > cchEnvironmentBlock)
|
||||
{
|
||||
cchEnvironmentBlock *= 2;
|
||||
lpszEnvironmentBlock = (LPCH) realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
|
||||
DWORD new_size;
|
||||
LPCH new_blk;
|
||||
|
||||
new_size = cchEnvironmentBlock * 2;
|
||||
new_blk = (LPCH) realloc(lpszEnvironmentBlock, new_size * sizeof(CHAR));
|
||||
if (!new_blk)
|
||||
{
|
||||
free(lpszEnvironmentBlock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpszEnvironmentBlock = new_blk;
|
||||
cchEnvironmentBlock = new_size;
|
||||
}
|
||||
|
||||
p = &(lpszEnvironmentBlock[offset]);
|
||||
@ -327,11 +340,16 @@ LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
|
||||
|
||||
if (mergeStringLength == mergeArraySize)
|
||||
{
|
||||
mergeArraySize += 128;
|
||||
mergeStrings = (const char**) realloc((void*) mergeStrings, mergeArraySize * sizeof(char*));
|
||||
const char** new_str;
|
||||
|
||||
if (!mergeStrings)
|
||||
mergeArraySize += 128;
|
||||
new_str = (const char**) realloc((void*) mergeStrings, mergeArraySize * sizeof(char*));
|
||||
|
||||
if (!new_str)
|
||||
{
|
||||
free(mergeStrings);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mergeStrings[mergeStringLength] = cp;
|
||||
|
@ -201,6 +201,71 @@ static HANDLE_CREATOR** _HandleCreators = NULL;
|
||||
static CRITICAL_SECTION _HandleCreatorsLock;
|
||||
|
||||
static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static BOOL FileCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL FileIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_NAMED_PIPE* pFile = (WINPR_NAMED_PIPE*) handle;
|
||||
|
||||
if (!pFile || pFile->Type != HANDLE_TYPE_NAMED_PIPE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FileCloseHandle(HANDLE handle) {
|
||||
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*) handle;
|
||||
|
||||
|
||||
if (!FileIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if (pNamedPipe->clientfd != -1)
|
||||
{
|
||||
//WLOG_DBG(TAG, "closing clientfd %d", pNamedPipe->clientfd);
|
||||
close(pNamedPipe->clientfd);
|
||||
}
|
||||
|
||||
if (pNamedPipe->serverfd != -1)
|
||||
{
|
||||
//WLOG_DBG(TAG, "closing serverfd %d", pNamedPipe->serverfd);
|
||||
close(pNamedPipe->serverfd);
|
||||
}
|
||||
|
||||
if (pNamedPipe->pfnUnrefNamedPipe)
|
||||
pNamedPipe->pfnUnrefNamedPipe(pNamedPipe);
|
||||
|
||||
if (pNamedPipe->lpFileName)
|
||||
free((void*)pNamedPipe->lpFileName);
|
||||
|
||||
if (pNamedPipe->lpFilePath)
|
||||
free((void*)pNamedPipe->lpFilePath);
|
||||
|
||||
if (pNamedPipe->name)
|
||||
free((void*)pNamedPipe->name);
|
||||
|
||||
free(pNamedPipe);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int FileGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_NAMED_PIPE *file = (WINPR_NAMED_PIPE *)handle;
|
||||
|
||||
if (!FileIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
if (file->ServerMode)
|
||||
return file->serverfd;
|
||||
else
|
||||
return file->clientfd;
|
||||
}
|
||||
|
||||
static void _HandleCreatorsInit()
|
||||
{
|
||||
/* NB: error management to be done outside of this function */
|
||||
@ -352,6 +417,10 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
||||
strcpy(s.sun_path, pNamedPipe->lpFilePath);
|
||||
status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un));
|
||||
|
||||
pNamedPipe->cb.IsHandled = FileIsHandled;
|
||||
pNamedPipe->cb.CloseHandle = FileCloseHandle;
|
||||
pNamedPipe->cb.GetFd = FileGetFd;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
close(pNamedPipe->clientfd);
|
||||
|
@ -43,215 +43,16 @@
|
||||
|
||||
#include "../handle/handle.h"
|
||||
|
||||
/* _HandleCreators is a NULL-terminated array with a maximun of HANDLE_CREATOR_MAX HANDLE_CREATOR */
|
||||
#define HANDLE_CLOSE_CB_MAX 128
|
||||
static HANDLE_CLOSE_CB** _HandleCloseCbs = NULL;
|
||||
static CRITICAL_SECTION _HandleCloseCbsLock;
|
||||
|
||||
static pthread_once_t _HandleCloseCbsInitialized = PTHREAD_ONCE_INIT;
|
||||
static void _HandleCloseCbsInit()
|
||||
{
|
||||
/* NB: error management to be done outside of this function */
|
||||
assert(_HandleCloseCbs == NULL);
|
||||
_HandleCloseCbs = (HANDLE_CLOSE_CB**)calloc(HANDLE_CLOSE_CB_MAX+1, sizeof(HANDLE_CLOSE_CB*));
|
||||
InitializeCriticalSection(&_HandleCloseCbsLock);
|
||||
assert(_HandleCloseCbs != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE on success, FALSE otherwise.
|
||||
*/
|
||||
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB* pHandleCloseCb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pthread_once(&_HandleCloseCbsInitialized, _HandleCloseCbsInit) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_HandleCloseCbs == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&_HandleCloseCbsLock);
|
||||
|
||||
for (i=0; i<HANDLE_CLOSE_CB_MAX; i++)
|
||||
{
|
||||
if (_HandleCloseCbs[i] == NULL)
|
||||
{
|
||||
_HandleCloseCbs[i] = pHandleCloseCb;
|
||||
LeaveCriticalSection(&_HandleCloseCbsLock);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_HandleCloseCbsLock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL CloseHandle(HANDLE hObject)
|
||||
{
|
||||
int i;
|
||||
ULONG Type;
|
||||
PVOID Object;
|
||||
WINPR_HANDLE *Object;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hObject, &Type, &Object))
|
||||
if (!winpr_Handle_GetInfo(hObject, &Type, (PVOID*)&Object))
|
||||
return FALSE;
|
||||
|
||||
if (pthread_once(&_HandleCloseCbsInitialized, _HandleCloseCbsInit) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_HandleCloseCbs == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&_HandleCloseCbsLock);
|
||||
|
||||
for (i=0; _HandleCloseCbs[i] != NULL; i++)
|
||||
{
|
||||
HANDLE_CLOSE_CB* close_cb = (HANDLE_CLOSE_CB*)_HandleCloseCbs[i];
|
||||
|
||||
if (close_cb && close_cb->IsHandled(hObject))
|
||||
{
|
||||
BOOL result = close_cb->CloseHandle(hObject);
|
||||
LeaveCriticalSection(&_HandleCloseCbsLock);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&_HandleCloseCbsLock);
|
||||
|
||||
if (Type == HANDLE_TYPE_MUTEX)
|
||||
{
|
||||
WINPR_MUTEX* mutex;
|
||||
mutex = (WINPR_MUTEX*) Object;
|
||||
pthread_mutex_destroy(&mutex->mutex);
|
||||
free(Object);
|
||||
return TRUE;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_EVENT)
|
||||
{
|
||||
WINPR_EVENT* event;
|
||||
event = (WINPR_EVENT*) Object;
|
||||
|
||||
if (!event->bAttached)
|
||||
{
|
||||
if (event->pipe_fd[0] != -1)
|
||||
{
|
||||
close(event->pipe_fd[0]);
|
||||
event->pipe_fd[0] = -1;
|
||||
}
|
||||
|
||||
if (event->pipe_fd[1] != -1)
|
||||
{
|
||||
close(event->pipe_fd[1]);
|
||||
event->pipe_fd[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(Object);
|
||||
return TRUE;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
WINPR_SEMAPHORE* semaphore;
|
||||
semaphore = (WINPR_SEMAPHORE*) Object;
|
||||
#ifdef WINPR_PIPE_SEMAPHORE
|
||||
|
||||
if (semaphore->pipe_fd[0] != -1)
|
||||
{
|
||||
close(semaphore->pipe_fd[0]);
|
||||
semaphore->pipe_fd[0] = -1;
|
||||
|
||||
if (semaphore->pipe_fd[1] != -1)
|
||||
{
|
||||
close(semaphore->pipe_fd[1]);
|
||||
semaphore->pipe_fd[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined __APPLE__
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) semaphore->sem));
|
||||
#else
|
||||
sem_destroy((winpr_sem_t*) semaphore->sem);
|
||||
#endif
|
||||
#endif
|
||||
free(Object);
|
||||
return TRUE;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
WINPR_TIMER* timer;
|
||||
timer = (WINPR_TIMER*) Object;
|
||||
#ifdef __linux__
|
||||
|
||||
if (timer->fd != -1)
|
||||
close(timer->fd);
|
||||
|
||||
#endif
|
||||
free(Object);
|
||||
return TRUE;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
|
||||
{
|
||||
WINPR_PIPE* pipe;
|
||||
pipe = (WINPR_PIPE*) Object;
|
||||
|
||||
if (pipe->fd != -1)
|
||||
{
|
||||
close(pipe->fd);
|
||||
}
|
||||
|
||||
free(Object);
|
||||
return TRUE;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
||||
{
|
||||
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*) Object;
|
||||
|
||||
if (pNamedPipe->clientfd != -1)
|
||||
{
|
||||
//WLOG_DBG(TAG, "closing clientfd %d", pNamedPipe->clientfd);
|
||||
close(pNamedPipe->clientfd);
|
||||
}
|
||||
|
||||
if (pNamedPipe->serverfd != -1)
|
||||
{
|
||||
//WLOG_DBG(TAG, "closing serverfd %d", pNamedPipe->serverfd);
|
||||
close(pNamedPipe->serverfd);
|
||||
}
|
||||
|
||||
if (pNamedPipe->pfnUnrefNamedPipe)
|
||||
pNamedPipe->pfnUnrefNamedPipe(pNamedPipe);
|
||||
|
||||
free((void*)pNamedPipe->lpFileName);
|
||||
free((void*)pNamedPipe->lpFilePath);
|
||||
free((void*)pNamedPipe->name);
|
||||
free(pNamedPipe);
|
||||
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 TRUE;
|
||||
}
|
||||
if (Object && Object->cb.CloseHandle)
|
||||
return Object->cb.CloseHandle(hObject);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <winpr/handle.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#define HANDLE_TYPE_NONE 0
|
||||
#define HANDLE_TYPE_PROCESS 1
|
||||
@ -39,7 +40,21 @@
|
||||
#define HANDLE_TYPE_COMM 13
|
||||
|
||||
#define WINPR_HANDLE_DEF() \
|
||||
ULONG Type
|
||||
ULONG Type; \
|
||||
HANDLE_CLOSE_CB cb
|
||||
|
||||
typedef BOOL (*pcIsHandled)(HANDLE handle);
|
||||
typedef BOOL (*pcCloseHandle)(HANDLE handle);
|
||||
typedef int (*pcGetFd)(HANDLE handle);
|
||||
typedef DWORD (*pcCleanupHandle)(HANDLE handle);
|
||||
|
||||
typedef struct _HANDLE_CLOSE_CB
|
||||
{
|
||||
pcIsHandled IsHandled;
|
||||
pcCloseHandle CloseHandle;
|
||||
pcGetFd GetFd;
|
||||
pcCleanupHandle CleanupHandle;
|
||||
} HANDLE_CLOSE_CB;
|
||||
|
||||
struct winpr_handle
|
||||
{
|
||||
@ -65,15 +80,36 @@ static INLINE BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef BOOL (*pcIsHandled)(HANDLE handle);
|
||||
typedef BOOL (*pcCloseHandle)(HANDLE handle);
|
||||
|
||||
typedef struct _HANDLE_CLOSE_CB
|
||||
static INLINE int winpr_Handle_getFd(HANDLE handle)
|
||||
{
|
||||
pcIsHandled IsHandled;
|
||||
pcCloseHandle CloseHandle;
|
||||
} HANDLE_CLOSE_CB;
|
||||
WINPR_HANDLE *hdl;
|
||||
ULONG type;
|
||||
|
||||
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB *pHandleClose);
|
||||
if (!winpr_Handle_GetInfo(handle, &type, (PVOID*)&hdl))
|
||||
return -1;
|
||||
|
||||
if (!hdl || !hdl->cb.GetFd)
|
||||
return -1;
|
||||
|
||||
return hdl->cb.GetFd(handle);
|
||||
}
|
||||
|
||||
static INLINE DWORD winpr_Handle_cleanup(HANDLE handle)
|
||||
{
|
||||
WINPR_HANDLE *hdl;
|
||||
ULONG type;
|
||||
|
||||
if (!winpr_Handle_GetInfo(handle, &type, (PVOID*)&hdl))
|
||||
return WAIT_FAILED;
|
||||
|
||||
if (!hdl)
|
||||
return WAIT_FAILED;
|
||||
|
||||
/* If there is no cleanup function, assume all ok. */
|
||||
if (!hdl->cb.CleanupHandle)
|
||||
return WAIT_OBJECT_0;
|
||||
|
||||
return hdl->cb.CleanupHandle(handle);
|
||||
}
|
||||
|
||||
#endif /* WINPR_HANDLE_PRIVATE_H */
|
||||
|
@ -28,9 +28,6 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static HANDLE_CLOSE_CB _NoneHandleCloseCb;
|
||||
static pthread_once_t none_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static BOOL NoneHandleCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_NONE_HANDLE* none = (WINPR_NONE_HANDLE*) handle;
|
||||
@ -51,11 +48,12 @@ static BOOL NoneHandleIsHandle(HANDLE handle)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void NoneHandleInitialize(void)
|
||||
static int NoneHandleGetFd(HANDLE handle)
|
||||
{
|
||||
_NoneHandleCloseCb.IsHandled = NoneHandleIsHandle;
|
||||
_NoneHandleCloseCb.CloseHandle = NoneHandleCloseHandle;
|
||||
RegisterHandleCloseCb(&_NoneHandleCloseCb);
|
||||
if (!NoneHandleIsHandle(handle))
|
||||
return -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
HANDLE CreateNoneHandle()
|
||||
@ -66,7 +64,9 @@ HANDLE CreateNoneHandle()
|
||||
if (!none)
|
||||
return NULL;
|
||||
|
||||
pthread_once(&none_initialized, NoneHandleInitialize);
|
||||
none->cb.IsHandled = NoneHandleIsHandle;
|
||||
none->cb.CloseHandle = NoneHandleCloseHandle;
|
||||
none->cb.GetFd = NoneHandleGetFd;
|
||||
|
||||
return (HANDLE)none;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "pipe.h"
|
||||
|
||||
@ -70,6 +71,46 @@ typedef struct _NamedPipeServerSocketEntry
|
||||
int references;
|
||||
} NamedPipeServerSocketEntry;
|
||||
|
||||
static BOOL PipeCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL PipeIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_PIPE* pPipe = (WINPR_PIPE*) handle;
|
||||
|
||||
if (!pPipe || pPipe->Type != HANDLE_TYPE_ANONYMOUS_PIPE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int PipeGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_PIPE *pipe = (WINPR_PIPE *)handle;
|
||||
|
||||
if (!PipeIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return pipe->fd;
|
||||
}
|
||||
|
||||
BOOL PipeCloseHandle(HANDLE handle) {
|
||||
WINPR_PIPE* pipe = (WINPR_PIPE *)handle;
|
||||
|
||||
if (!PipeIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if (pipe->fd != -1)
|
||||
{
|
||||
close(pipe->fd);
|
||||
}
|
||||
|
||||
free(handle);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void InitWinPRPipeModule()
|
||||
{
|
||||
if (g_NamedPipeServerSockets)
|
||||
@ -97,8 +138,8 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pReadPipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE));
|
||||
pWritePipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE));
|
||||
pReadPipe = (WINPR_PIPE*) calloc(1, sizeof(WINPR_PIPE));
|
||||
pWritePipe = (WINPR_PIPE*) calloc(1, sizeof(WINPR_PIPE));
|
||||
|
||||
if (!pReadPipe || !pWritePipe)
|
||||
{
|
||||
@ -114,8 +155,15 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
|
||||
pReadPipe->fd = pipe_fd[0];
|
||||
pWritePipe->fd = pipe_fd[1];
|
||||
WINPR_HANDLE_SET_TYPE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE);
|
||||
pReadPipe->cb.GetFd = PipeGetFd;
|
||||
pReadPipe->cb.CloseHandle = PipeCloseHandle;
|
||||
pReadPipe->cb.IsHandled = PipeIsHandled;
|
||||
|
||||
*((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe;
|
||||
WINPR_HANDLE_SET_TYPE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE);
|
||||
pWritePipe->cb.GetFd = PipeGetFd;
|
||||
pWritePipe->cb.CloseHandle = PipeCloseHandle;
|
||||
pWritePipe->cb.IsHandled = PipeIsHandled;
|
||||
*((ULONG_PTR*) hWritePipe) = (ULONG_PTR) pWritePipe;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
@ -67,6 +69,51 @@
|
||||
|
||||
#include "../security/security.h"
|
||||
|
||||
static BOOL LogonUserCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL LogonUserIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_ACCESS_TOKEN* pLogonUser = (WINPR_ACCESS_TOKEN*) handle;
|
||||
|
||||
if (!pLogonUser || pLogonUser->Type != HANDLE_TYPE_ACCESS_TOKEN)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int LogonUserGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_ACCESS_TOKEN *pLogonUser = (WINPR_ACCESS_TOKEN *)handle;
|
||||
|
||||
if (!LogonUserIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
/* TODO: File fd not supported */
|
||||
(void)pLogonUser;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL LogonUserCloseHandle(HANDLE handle) {
|
||||
WINPR_ACCESS_TOKEN *token = (WINPR_ACCESS_TOKEN *) handle;
|
||||
|
||||
if (!LogonUserIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if (token->Username)
|
||||
free(token->Username);
|
||||
|
||||
if (token->Domain)
|
||||
free(token->Domain);
|
||||
|
||||
free(token);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword,
|
||||
DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken)
|
||||
{
|
||||
@ -76,15 +123,17 @@ BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword,
|
||||
if (!lpszUsername)
|
||||
return FALSE;
|
||||
|
||||
token = (WINPR_ACCESS_TOKEN*) malloc(sizeof(WINPR_ACCESS_TOKEN));
|
||||
token = (WINPR_ACCESS_TOKEN*) calloc(1, sizeof(WINPR_ACCESS_TOKEN));
|
||||
|
||||
if (!token)
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory(token, sizeof(WINPR_ACCESS_TOKEN));
|
||||
|
||||
WINPR_HANDLE_SET_TYPE(token, HANDLE_TYPE_ACCESS_TOKEN);
|
||||
|
||||
token->cb.GetFd = LogonUserGetFd;
|
||||
token->cb.CloseHandle = LogonUserCloseHandle;
|
||||
token->cb.IsHandled = LogonUserIsHandled;
|
||||
|
||||
token->Username = _strdup(lpszUsername);
|
||||
|
||||
if (lpszDomain)
|
||||
|
@ -48,15 +48,66 @@
|
||||
|
||||
CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 };
|
||||
|
||||
static BOOL EventCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL EventIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER* pEvent = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!pEvent || pEvent->Type != HANDLE_TYPE_EVENT)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int EventGetFd(HANDLE handle) {
|
||||
WINPR_EVENT *event = (WINPR_EVENT *)handle;
|
||||
if (!EventIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return event->pipe_fd[0];
|
||||
}
|
||||
|
||||
BOOL EventCloseHandle(HANDLE handle) {
|
||||
WINPR_EVENT* event = (WINPR_EVENT*) handle;
|
||||
|
||||
if (!EventIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if (!event->bAttached)
|
||||
{
|
||||
if (event->pipe_fd[0] != -1)
|
||||
{
|
||||
close(event->pipe_fd[0]);
|
||||
event->pipe_fd[0] = -1;
|
||||
}
|
||||
|
||||
if (event->pipe_fd[1] != -1)
|
||||
{
|
||||
close(event->pipe_fd[1]);
|
||||
event->pipe_fd[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(event);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
|
||||
{
|
||||
WINPR_EVENT* event;
|
||||
event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
|
||||
|
||||
event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
|
||||
if (event)
|
||||
{
|
||||
event->bAttached = FALSE;
|
||||
event->bManualReset = bManualReset;
|
||||
event->cb.IsHandled = EventIsHandled;
|
||||
event->cb.CloseHandle = EventCloseHandle;
|
||||
event->cb.GetFd = EventGetFd;
|
||||
|
||||
if (!event->bManualReset)
|
||||
{
|
||||
@ -225,7 +276,7 @@ HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL
|
||||
#ifndef _WIN32
|
||||
WINPR_EVENT* event;
|
||||
HANDLE handle = NULL;
|
||||
event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
|
||||
event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
|
||||
|
||||
if (event)
|
||||
{
|
||||
@ -233,6 +284,9 @@ HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL
|
||||
event->bManualReset = bManualReset;
|
||||
event->pipe_fd[0] = FileDescriptor;
|
||||
event->pipe_fd[1] = -1;
|
||||
event->cb.CloseHandle = EventCloseHandle;
|
||||
event->cb.GetFd = EventGetFd;
|
||||
event->cb.IsHandled = EventIsHandled;
|
||||
WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT);
|
||||
handle = (HANDLE) event;
|
||||
}
|
||||
|
@ -28,19 +28,62 @@
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "../handle/handle.h"
|
||||
static BOOL MutexCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL MutexIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER* pMutex = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!pMutex || pMutex->Type != HANDLE_TYPE_MUTEX)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int MutexGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_MUTEX *mux = (WINPR_MUTEX *)handle;
|
||||
if (!MutexIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
/* TODO: Mutex does not support file handles... */
|
||||
(void)mux;
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL MutexCloseHandle(HANDLE handle) {
|
||||
WINPR_MUTEX *mutex = (WINPR_MUTEX *) handle;
|
||||
|
||||
if (!MutexIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if(pthread_mutex_destroy(&mutex->mutex))
|
||||
return FALSE;
|
||||
|
||||
free(handle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
WINPR_MUTEX* mutex;
|
||||
|
||||
mutex = (WINPR_MUTEX*) malloc(sizeof(WINPR_MUTEX));
|
||||
mutex = (WINPR_MUTEX*) calloc(1, sizeof(WINPR_MUTEX));
|
||||
|
||||
if (mutex)
|
||||
{
|
||||
pthread_mutex_init(&mutex->mutex, 0);
|
||||
|
||||
WINPR_HANDLE_SET_TYPE(mutex, HANDLE_TYPE_MUTEX);
|
||||
mutex->cb.GetFd = MutexGetFd;
|
||||
mutex->cb.CloseHandle = MutexCloseHandle;
|
||||
mutex->cb.IsHandled = MutexIsHandled;
|
||||
|
||||
handle = (HANDLE) mutex;
|
||||
|
||||
if (bInitialOwner)
|
||||
|
@ -31,15 +31,92 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <errno.h>
|
||||
#include "../handle/handle.h"
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("synch.semaphore")
|
||||
|
||||
static BOOL SemaphoreCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL SemaphoreIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER* pSemaphore = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!pSemaphore || pSemaphore->Type != HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int SemaphoreGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_SEMAPHORE *sem = (WINPR_SEMAPHORE *)handle;
|
||||
|
||||
if (!SemaphoreIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return sem->pipe_fd[0];
|
||||
}
|
||||
|
||||
static DWORD SemaphoreCleanupHandle(HANDLE handle)
|
||||
{
|
||||
int length;
|
||||
WINPR_SEMAPHORE *sem = (WINPR_SEMAPHORE *)handle;
|
||||
|
||||
if (!SemaphoreIsHandled(handle))
|
||||
return WAIT_FAILED;
|
||||
|
||||
length = read(sem->pipe_fd[0], &length, 1);
|
||||
|
||||
if (length != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "semaphore read() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
BOOL SemaphoreCloseHandle(HANDLE handle) {
|
||||
WINPR_SEMAPHORE *semaphore = (WINPR_SEMAPHORE *) handle;
|
||||
|
||||
if (!SemaphoreIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
#ifdef WINPR_PIPE_SEMAPHORE
|
||||
|
||||
if (semaphore->pipe_fd[0] != -1)
|
||||
{
|
||||
close(semaphore->pipe_fd[0]);
|
||||
semaphore->pipe_fd[0] = -1;
|
||||
|
||||
if (semaphore->pipe_fd[1] != -1)
|
||||
{
|
||||
close(semaphore->pipe_fd[1]);
|
||||
semaphore->pipe_fd[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined __APPLE__
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) semaphore->sem));
|
||||
#else
|
||||
sem_destroy((winpr_sem_t*) semaphore->sem);
|
||||
#endif
|
||||
#endif
|
||||
free(semaphore);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName)
|
||||
{
|
||||
HANDLE handle;
|
||||
WINPR_SEMAPHORE* semaphore;
|
||||
semaphore = (WINPR_SEMAPHORE*) malloc(sizeof(WINPR_SEMAPHORE));
|
||||
|
||||
semaphore = (WINPR_SEMAPHORE*) calloc(1, sizeof(WINPR_SEMAPHORE));
|
||||
|
||||
if (!semaphore)
|
||||
return NULL;
|
||||
@ -47,6 +124,10 @@ HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lIniti
|
||||
semaphore->pipe_fd[0] = -1;
|
||||
semaphore->pipe_fd[0] = -1;
|
||||
semaphore->sem = (winpr_sem_t*) NULL;
|
||||
semaphore->cb.IsHandled = SemaphoreIsHandled;
|
||||
semaphore->cb.CloseHandle = SemaphoreCloseHandle;
|
||||
semaphore->cb.GetFd = SemaphoreGetFd;
|
||||
semaphore->cb.CleanupHandle = SemaphoreCleanupHandle;
|
||||
|
||||
if (semaphore)
|
||||
{
|
||||
|
@ -42,6 +42,80 @@
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("synch.timer")
|
||||
|
||||
static BOOL TimerCloseHandle(HANDLE handle);
|
||||
|
||||
static BOOL TimerIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER* pTimer = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!pTimer || pTimer->Type != HANDLE_TYPE_TIMER)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int TimerGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *)handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return timer->fd;
|
||||
}
|
||||
|
||||
static DWORD TimerCleanupHandle(HANDLE handle)
|
||||
{
|
||||
int length;
|
||||
UINT64 expirations;
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *)handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return WAIT_FAILED;
|
||||
|
||||
length = read(timer->fd, (void *) &expirations, sizeof(UINT64));
|
||||
|
||||
if (length != 8)
|
||||
{
|
||||
if (length == -1)
|
||||
{
|
||||
if (errno == ETIMEDOUT)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
WLog_ERR(TAG, "timer read() failure [%d] %s", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "timer read() failure - incorrect number of bytes read");
|
||||
}
|
||||
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
BOOL TimerCloseHandle(HANDLE handle) {
|
||||
WINPR_TIMER* timer;
|
||||
timer = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
if (timer->fd != -1)
|
||||
close(timer->fd);
|
||||
|
||||
#endif
|
||||
free(timer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_POSIX_TIMER
|
||||
|
||||
static BOOL g_WaitableTimerSignalHandlerInstalled = FALSE;
|
||||
@ -143,8 +217,8 @@ HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManua
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
WINPR_TIMER* timer;
|
||||
timer = (WINPR_TIMER*) malloc(sizeof(WINPR_TIMER));
|
||||
|
||||
timer = (WINPR_TIMER*) calloc(1, sizeof(WINPR_TIMER));
|
||||
if (timer)
|
||||
{
|
||||
WINPR_HANDLE_SET_TYPE(timer, HANDLE_TYPE_TIMER);
|
||||
@ -155,6 +229,10 @@ HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManua
|
||||
timer->pfnCompletionRoutine = NULL;
|
||||
timer->lpArgToCompletionRoutine = NULL;
|
||||
timer->bInit = FALSE;
|
||||
timer->cb.GetFd = TimerGetFd;
|
||||
timer->cb.CloseHandle = TimerCloseHandle;
|
||||
timer->cb.IsHandled = TimerIsHandled;
|
||||
timer->cb.CleanupHandle = TimerCleanupHandle;
|
||||
}
|
||||
|
||||
return handle;
|
||||
|
@ -199,41 +199,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
int status;
|
||||
WINPR_THREAD *thread = (WINPR_THREAD *)Object;
|
||||
status = waitOnFd(thread->pipe_fd[0], dwMilliseconds);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "waitOnFd() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (status != 1)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
pthread_mutex_lock(&thread->mutex);
|
||||
|
||||
if (!thread->joined)
|
||||
{
|
||||
status = pthread_join(thread->thread, NULL);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "pthread_join failure: [%d] %s",
|
||||
status, strerror(status));
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
else
|
||||
thread->joined = TRUE;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_PROCESS)
|
||||
if (Type == HANDLE_TYPE_PROCESS)
|
||||
{
|
||||
WINPR_PROCESS *process;
|
||||
process = (WINPR_PROCESS *) Object;
|
||||
@ -245,6 +211,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
}
|
||||
|
||||
process->dwExitCode = (DWORD) process->status;
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_MUTEX)
|
||||
{
|
||||
@ -266,144 +233,31 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
}
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_EVENT)
|
||||
else
|
||||
{
|
||||
int status;
|
||||
WINPR_EVENT *event;
|
||||
event = (WINPR_EVENT *) Object;
|
||||
status = waitOnFd(event->pipe_fd[0], dwMilliseconds);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "event select() failure [%d] %s", errno, strerror(errno));
|
||||
int fd = winpr_Handle_getFd(Object);
|
||||
if (fd < 0)
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (status != 1)
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
WINPR_SEMAPHORE *semaphore;
|
||||
semaphore = (WINPR_SEMAPHORE *) Object;
|
||||
#ifdef WINPR_PIPE_SEMAPHORE
|
||||
|
||||
if (semaphore->pipe_fd[0] != -1)
|
||||
{
|
||||
int status;
|
||||
int length;
|
||||
status = waitOnFd(semaphore->pipe_fd[0], dwMilliseconds);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "semaphore select() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (status != 1)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
length = read(semaphore->pipe_fd[0], &length, 1);
|
||||
|
||||
if (length != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "semaphore read failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined __APPLE__
|
||||
semaphore_wait(*((winpr_sem_t *) semaphore->sem));
|
||||
#else
|
||||
sem_wait((winpr_sem_t *) semaphore->sem);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
WINPR_TIMER *timer;
|
||||
timer = (WINPR_TIMER *) Object;
|
||||
#ifdef HAVE_EVENTFD_H
|
||||
|
||||
if (timer->fd != -1)
|
||||
{
|
||||
int status;
|
||||
UINT64 expirations;
|
||||
status = waitOnFd(timer->fd, dwMilliseconds);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "timer select() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (status != 1)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
status = read(timer->fd, (void *) &expirations, sizeof(UINT64));
|
||||
|
||||
if (status != 8)
|
||||
{
|
||||
if (status == -1)
|
||||
{
|
||||
if (errno == ETIMEDOUT)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
WLog_ERR(TAG, "timer read() failure [%d] %s", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "timer read() failure - incorrect number of bytes read");
|
||||
}
|
||||
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "invalid timer file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
#else
|
||||
WLog_ERR(TAG, "file descriptors not supported");
|
||||
return WAIT_FAILED;
|
||||
#endif
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
WINPR_NAMED_PIPE *pipe = (WINPR_NAMED_PIPE *) Object;
|
||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid pipe file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
status = waitOnFd(fd, dwMilliseconds);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "named pipe select() failure [%d] %s", errno, strerror(errno));
|
||||
WLog_ERR(TAG, "waitOnFd() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (status != 1)
|
||||
{
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "unknown handle type %d", (int) Type);
|
||||
|
||||
return winpr_Handle_cleanup(Object);
|
||||
}
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
@ -482,63 +336,7 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAl
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (Type == HANDLE_TYPE_EVENT)
|
||||
{
|
||||
fd = ((WINPR_EVENT *) Object)->pipe_fd[0];
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid event file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
#ifdef WINPR_PIPE_SEMAPHORE
|
||||
fd = ((WINPR_SEMAPHORE *) Object)->pipe_fd[0];
|
||||
#else
|
||||
WLog_ERR(TAG, "semaphore not supported");
|
||||
return WAIT_FAILED;
|
||||
#endif
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *) Object;
|
||||
fd = timer->fd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid timer file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
WINPR_THREAD *thread = (WINPR_THREAD *) Object;
|
||||
fd = thread->pipe_fd[0];
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid thread file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
||||
{
|
||||
WINPR_NAMED_PIPE *pipe = (WINPR_NAMED_PIPE *) Object;
|
||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid timer file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "unknown handle type %d", (int) Type);
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
fd = winpr_Handle_getFd(Object);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
@ -620,30 +418,18 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAl
|
||||
else
|
||||
idx = index;
|
||||
|
||||
winpr_Handle_GetInfo(lpHandles[idx], &Type, &Object);
|
||||
if (!winpr_Handle_GetInfo(lpHandles[idx], &Type, &Object))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid hHandle.");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (Type == HANDLE_TYPE_EVENT)
|
||||
fd = winpr_Handle_getFd(lpHandles[idx]);
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
fd = ((WINPR_EVENT *) Object)->pipe_fd[0];
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
fd = ((WINPR_SEMAPHORE *) Object)->pipe_fd[0];
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *) Object;
|
||||
fd = timer->fd;
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
WINPR_THREAD *thread = (WINPR_THREAD *) Object;
|
||||
fd = thread->pipe_fd[0];
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_NAMED_PIPE)
|
||||
{
|
||||
WINPR_NAMED_PIPE *pipe = (WINPR_NAMED_PIPE *) Object;
|
||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||
WLog_ERR(TAG, "invalid file descriptor");
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
@ -653,63 +439,9 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAl
|
||||
if (FD_ISSET(fd, &fds))
|
||||
#endif
|
||||
{
|
||||
if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
int length;
|
||||
length = read(fd, &length, 1);
|
||||
|
||||
if (length != 1)
|
||||
{
|
||||
WLog_ERR(TAG, "semaphore read() failure [%d] %s", errno, strerror(errno));
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
int length;
|
||||
UINT64 expirations;
|
||||
length = read(fd, (void *) &expirations, sizeof(UINT64));
|
||||
|
||||
if (length != 8)
|
||||
{
|
||||
if (length == -1)
|
||||
{
|
||||
if (errno == ETIMEDOUT)
|
||||
return WAIT_TIMEOUT;
|
||||
|
||||
WLog_ERR(TAG, "timer read() failure [%d] %s", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "timer read() failure - incorrect number of bytes read");
|
||||
}
|
||||
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
}
|
||||
else if (Type == HANDLE_TYPE_THREAD)
|
||||
{
|
||||
WINPR_THREAD *thread = (WINPR_THREAD *)Object;
|
||||
pthread_mutex_lock(&thread->mutex);
|
||||
|
||||
if (!thread->joined)
|
||||
{
|
||||
int status;
|
||||
status = pthread_join(thread->thread, NULL);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "pthread_join failure: [%d] %s",
|
||||
status, strerror(status));
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
else
|
||||
thread->joined = TRUE;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
}
|
||||
DWORD rc = winpr_Handle_cleanup(lpHandles[idx]);
|
||||
if (rc != WAIT_OBJECT_0)
|
||||
return rc;
|
||||
|
||||
if (bWaitAll)
|
||||
{
|
||||
|
@ -80,9 +80,6 @@
|
||||
#include "../handle/handle.h"
|
||||
#include "../security/security.h"
|
||||
|
||||
static HANDLE_CLOSE_CB _ProcessHandleCloseCb;
|
||||
static pthread_once_t process_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
|
||||
{
|
||||
char* p;
|
||||
@ -478,11 +475,16 @@ static BOOL ProcessHandleIsHandle(HANDLE handle)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ProcessHandleInitialize(void)
|
||||
static int ProcessGetFd(HANDLE handle)
|
||||
{
|
||||
_ProcessHandleCloseCb.IsHandled = ProcessHandleIsHandle;
|
||||
_ProcessHandleCloseCb.CloseHandle = ProcessHandleCloseHandle;
|
||||
RegisterHandleCloseCb(&_ProcessHandleCloseCb);
|
||||
WINPR_PROCESS *process = (WINPR_PROCESS *)handle;
|
||||
|
||||
if (!ProcessHandleIsHandle(handle))
|
||||
return -1;
|
||||
|
||||
/* TODO: Process does not support fd... */
|
||||
(void)process;
|
||||
return -1;
|
||||
}
|
||||
|
||||
HANDLE CreateProcessHandle(pid_t pid)
|
||||
@ -493,9 +495,11 @@ HANDLE CreateProcessHandle(pid_t pid)
|
||||
if (!process)
|
||||
return NULL;
|
||||
|
||||
pthread_once(&process_initialized, ProcessHandleInitialize);
|
||||
process->pid = pid;
|
||||
process->Type = HANDLE_TYPE_PROCESS;
|
||||
process->cb.GetFd = ProcessGetFd;
|
||||
process->cb.CloseHandle = ProcessHandleCloseHandle;
|
||||
process->cb.IsHandled = ProcessHandleIsHandle;
|
||||
|
||||
return (HANDLE)process;
|
||||
}
|
||||
|
@ -93,9 +93,6 @@
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("thread")
|
||||
|
||||
static pthread_once_t thread_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static HANDLE_CLOSE_CB _ThreadHandleCloseCb;
|
||||
static wListDictionary* thread_list = NULL;
|
||||
|
||||
static BOOL ThreadCloseHandle(HANDLE handle);
|
||||
@ -114,11 +111,44 @@ static BOOL ThreadIsHandled(HANDLE handle)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ThreadInitialize(void)
|
||||
static int ThreadGetFd(HANDLE handle)
|
||||
{
|
||||
_ThreadHandleCloseCb.IsHandled = ThreadIsHandled;
|
||||
_ThreadHandleCloseCb.CloseHandle = ThreadCloseHandle;
|
||||
RegisterHandleCloseCb(&_ThreadHandleCloseCb);
|
||||
WINPR_THREAD* pThread = (WINPR_THREAD*) handle;
|
||||
|
||||
if (!ThreadIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return pThread->pipe_fd[0];
|
||||
}
|
||||
|
||||
static DWORD ThreadCleanupHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_THREAD* thread = (WINPR_THREAD*) handle;
|
||||
|
||||
if (!ThreadIsHandled(handle))
|
||||
return WAIT_FAILED;
|
||||
|
||||
pthread_mutex_lock(&thread->mutex);
|
||||
|
||||
if (!thread->joined)
|
||||
{
|
||||
int status;
|
||||
status = pthread_join(thread->thread, NULL);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "pthread_join failure: [%d] %s",
|
||||
status, strerror(status));
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
else
|
||||
thread->joined = TRUE;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&thread->mutex);
|
||||
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
static void dump_thread(WINPR_THREAD* thread)
|
||||
@ -305,11 +335,14 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
pthread_once(&thread_initialized, ThreadInitialize);
|
||||
thread->dwStackSize = dwStackSize;
|
||||
thread->lpParameter = lpParameter;
|
||||
thread->lpStartAddress = lpStartAddress;
|
||||
thread->lpThreadAttributes = lpThreadAttributes;
|
||||
thread->cb.IsHandled = ThreadIsHandled;
|
||||
thread->cb.CloseHandle = ThreadCloseHandle;
|
||||
thread->cb.GetFd = ThreadGetFd;
|
||||
thread->cb.CleanupHandle = ThreadCleanupHandle;
|
||||
|
||||
#if defined(WITH_DEBUG_THREADS)
|
||||
thread->create_stack = winpr_backtrace(20);
|
||||
|
@ -75,12 +75,16 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
{
|
||||
int old_capacity;
|
||||
int new_capacity;
|
||||
wMessage* new_arr;
|
||||
|
||||
old_capacity = queue->capacity;
|
||||
new_capacity = queue->capacity * 2;
|
||||
|
||||
new_arr = (wMessage*) realloc(queue->array, sizeof(wMessage) * new_capacity);
|
||||
if (!new_arr)
|
||||
return;
|
||||
queue->array = new_arr;
|
||||
queue->capacity = new_capacity;
|
||||
queue->array = (wMessage*) realloc(queue->array, sizeof(wMessage) * queue->capacity);
|
||||
ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(wMessage));
|
||||
|
||||
if (queue->tail < old_capacity)
|
||||
|
@ -74,8 +74,15 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
pool->capacity *= 2;
|
||||
pool->array = (void**) realloc(pool->array, sizeof(void*) * pool->capacity);
|
||||
int new_cap;
|
||||
void **new_arr;
|
||||
|
||||
new_cap = pool->capacity * 2;
|
||||
new_arr = (void**) realloc(pool->array, sizeof(void*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->array = new_arr;
|
||||
pool->capacity = new_cap;
|
||||
}
|
||||
|
||||
pool->array[(pool->size)++] = obj;
|
||||
|
@ -61,7 +61,7 @@ wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
|
||||
int index;
|
||||
wEventType* event = NULL;
|
||||
|
||||
for (index = 0; pubSub->count; index++)
|
||||
for (index = 0; index < pubSub->count; index++)
|
||||
{
|
||||
if (strcmp(pubSub->events[index].EventName, EventName) == 0)
|
||||
{
|
||||
@ -80,8 +80,15 @@ void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count)
|
||||
|
||||
while (pubSub->count + count >= pubSub->size)
|
||||
{
|
||||
pubSub->size *= 2;
|
||||
pubSub->events = (wEventType*) realloc(pubSub->events, pubSub->size);
|
||||
int new_size;
|
||||
wEventType *new_event;
|
||||
|
||||
new_size = pubSub->size * 2;
|
||||
new_event = (wEventType*) realloc(pubSub->events, new_size);
|
||||
if (!new_event)
|
||||
return;
|
||||
pubSub->size = new_size;
|
||||
pubSub->events = new_event;
|
||||
}
|
||||
|
||||
CopyMemory(&pubSub->events[pubSub->count], events, count * sizeof(wEventType));
|
||||
@ -144,7 +151,7 @@ int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler Eve
|
||||
event->EventHandlers[index] = NULL;
|
||||
event->EventHandlerCount--;
|
||||
MoveMemory(&event->EventHandlers[index], &event->EventHandlers[index + 1],
|
||||
(MAX_EVENT_HANDLERS - index - 1) * sizeof(wEventType));
|
||||
(MAX_EVENT_HANDLERS - index - 1) * sizeof(pEventHandler));
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ wReference* ReferenceTable_GetFreeEntry(wReferenceTable* referenceTable)
|
||||
|
||||
if (!found)
|
||||
{
|
||||
UINT32 new_size;
|
||||
wReference *new_ref;
|
||||
|
||||
if (!referenceTable->size)
|
||||
{
|
||||
if (referenceTable->array)
|
||||
@ -78,10 +81,14 @@ wReference* ReferenceTable_GetFreeEntry(wReferenceTable* referenceTable)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
referenceTable->size *= 2;
|
||||
referenceTable->array = (wReference*) realloc(referenceTable->array,
|
||||
sizeof(wReference) * referenceTable->size);
|
||||
new_size = referenceTable->size * 2;
|
||||
new_ref = (wReference*) realloc(referenceTable->array,
|
||||
sizeof(wReference) * new_size);
|
||||
if (!new_ref)
|
||||
return NULL;
|
||||
|
||||
referenceTable->size = new_size;
|
||||
referenceTable->array = new_ref;
|
||||
ZeroMemory(&referenceTable->array[(referenceTable->size / 2)],
|
||||
sizeof(wReference) * (referenceTable->size / 2));
|
||||
|
||||
|
@ -127,8 +127,15 @@ void Stack_Push(wStack* stack, void* obj)
|
||||
|
||||
if ((stack->size + 1) >= stack->capacity)
|
||||
{
|
||||
stack->capacity *= 2;
|
||||
stack->array = (void**) realloc(stack->array, sizeof(void*) * stack->capacity);
|
||||
int new_cap;
|
||||
void **new_arr;
|
||||
|
||||
new_cap = stack->capacity * 2;
|
||||
new_arr = (void**) realloc(stack->array, sizeof(void*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
stack->array = new_arr;
|
||||
stack->capacity = new_cap;
|
||||
}
|
||||
|
||||
stack->array[(stack->size)++] = obj;
|
||||
|
@ -35,8 +35,15 @@ void StreamPool_ShiftUsed(wStreamPool* pool, int index, int count)
|
||||
{
|
||||
if (pool->uSize + count > pool->uCapacity)
|
||||
{
|
||||
pool->uCapacity *= 2;
|
||||
pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity);
|
||||
int new_cap;
|
||||
wStream **new_arr;
|
||||
|
||||
new_cap = pool->uCapacity * 2;
|
||||
new_arr = (wStream**) realloc(pool->uArray, sizeof(wStream*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->uCapacity = new_cap;
|
||||
pool->uArray = new_arr;
|
||||
}
|
||||
|
||||
MoveMemory(&pool->uArray[index + count], &pool->uArray[index], (pool->uSize - index) * sizeof(wStream*));
|
||||
@ -62,8 +69,15 @@ void StreamPool_AddUsed(wStreamPool* pool, wStream* s)
|
||||
{
|
||||
if ((pool->uSize + 1) >= pool->uCapacity)
|
||||
{
|
||||
pool->uCapacity *= 2;
|
||||
pool->uArray = (wStream**) realloc(pool->uArray, sizeof(wStream*) * pool->uCapacity);
|
||||
int new_cap;
|
||||
wStream **new_arr;
|
||||
|
||||
new_cap = pool->uCapacity * 2;
|
||||
new_arr = (wStream**) realloc(pool->uArray, sizeof(wStream*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->uCapacity = new_cap;
|
||||
pool->uArray = new_arr;
|
||||
}
|
||||
|
||||
pool->uArray[(pool->uSize)++] = s;
|
||||
@ -97,8 +111,15 @@ void StreamPool_ShiftAvailable(wStreamPool* pool, int index, int count)
|
||||
{
|
||||
if (pool->aSize + count > pool->aCapacity)
|
||||
{
|
||||
pool->aCapacity *= 2;
|
||||
pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity);
|
||||
int new_cap;
|
||||
wStream **new_arr;
|
||||
|
||||
new_cap = pool->aCapacity * 2;
|
||||
new_arr = (wStream**) realloc(pool->aArray, sizeof(wStream*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->aCapacity = new_cap;
|
||||
pool->aArray = new_arr;
|
||||
}
|
||||
|
||||
MoveMemory(&pool->aArray[index + count], &pool->aArray[index], (pool->aSize - index) * sizeof(wStream*));
|
||||
@ -179,13 +200,27 @@ void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
|
||||
if ((pool->aSize + 1) >= pool->aCapacity)
|
||||
{
|
||||
pool->aCapacity *= 2;
|
||||
pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity);
|
||||
int new_cap;
|
||||
wStream **new_arr;
|
||||
|
||||
new_cap = pool->aCapacity * 2;
|
||||
new_arr = (wStream**) realloc(pool->aArray, sizeof(wStream*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->aCapacity = new_cap;
|
||||
pool->aArray = new_arr;
|
||||
}
|
||||
else if ((pool->aSize + 1) * 3 < pool->aCapacity)
|
||||
{
|
||||
pool->aCapacity /= 2;
|
||||
pool->aArray = (wStream**) realloc(pool->aArray, sizeof(wStream*) * pool->aCapacity);
|
||||
int new_cap;
|
||||
wStream **new_arr;
|
||||
|
||||
new_cap = pool->aCapacity / 2;
|
||||
new_arr = (wStream**) realloc(pool->aArray, sizeof(wStream*) * new_cap);
|
||||
if (!new_arr)
|
||||
return;
|
||||
pool->aCapacity = new_cap;
|
||||
pool->aArray = new_arr;
|
||||
}
|
||||
|
||||
pool->aArray[(pool->aSize)++] = s;
|
||||
|
@ -224,8 +224,15 @@ wIniFileSection* IniFile_AddSection(wIniFile* ini, const char* name)
|
||||
{
|
||||
if ((ini->nSections + 1) >= (ini->cSections))
|
||||
{
|
||||
ini->cSections *= 2;
|
||||
ini->sections = (wIniFileSection**) realloc(ini->sections, sizeof(wIniFileSection*) * ini->cSections);
|
||||
int new_size;
|
||||
wIniFileSection** new_sect;
|
||||
|
||||
new_size = ini->cSections * 2;
|
||||
new_sect = (wIniFileSection**) realloc(ini->sections, sizeof(wIniFileSection*) * new_size);
|
||||
if (!new_sect)
|
||||
return NULL;
|
||||
ini->cSections = new_size;
|
||||
ini->sections = new_sect;
|
||||
}
|
||||
|
||||
section = IniFile_Section_New(name);
|
||||
@ -269,8 +276,15 @@ wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char*
|
||||
{
|
||||
if ((section->nKeys + 1) >= (section->cKeys))
|
||||
{
|
||||
section->cKeys *= 2;
|
||||
section->keys = (wIniFileKey**) realloc(section->keys, sizeof(wIniFileKey*) * section->cKeys);
|
||||
int new_size;
|
||||
wIniFileKey** new_key;
|
||||
|
||||
new_size = section->cKeys * 2;
|
||||
new_key = (wIniFileKey**) realloc(section->keys, sizeof(wIniFileKey*) * new_size);
|
||||
if (!new_key)
|
||||
return NULL;
|
||||
section->cKeys = new_size;
|
||||
section->keys = new_key;
|
||||
}
|
||||
|
||||
key = IniFile_Key_New(name, value);
|
||||
|
@ -32,6 +32,7 @@ void Stream_EnsureCapacity(wStream* s, size_t size)
|
||||
size_t position;
|
||||
size_t old_capacity;
|
||||
size_t new_capacity;
|
||||
BYTE* new_buf;
|
||||
|
||||
old_capacity = s->capacity;
|
||||
new_capacity = old_capacity;
|
||||
@ -42,13 +43,15 @@ void Stream_EnsureCapacity(wStream* s, size_t size)
|
||||
}
|
||||
while (new_capacity < size);
|
||||
|
||||
s->capacity = new_capacity;
|
||||
s->length = new_capacity;
|
||||
|
||||
position = Stream_GetPosition(s);
|
||||
|
||||
s->buffer = (BYTE*) realloc(s->buffer, s->capacity);
|
||||
|
||||
new_buf = (BYTE*) realloc(s->buffer, new_capacity);
|
||||
if (!new_buf)
|
||||
return;
|
||||
s->buffer = new_buf;
|
||||
s->capacity = new_capacity;
|
||||
s->length = new_capacity;
|
||||
ZeroMemory(&s->buffer[old_capacity], s->capacity - old_capacity);
|
||||
|
||||
Stream_SetPosition(s, position);
|
||||
|
@ -544,8 +544,19 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
x509_str = (BYTE*) realloc(x509_str, length);
|
||||
int new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
new_len = length * 2;
|
||||
new_str = (BYTE*) realloc(x509_str, new_len);
|
||||
if (!new_str)
|
||||
{
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
length = new_len;
|
||||
x509_str = new_str;
|
||||
|
||||
status = BIO_read(bio, &x509_str[offset], length);
|
||||
|
||||
@ -557,7 +568,7 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
free(x509_str);
|
||||
free(x509_str);
|
||||
free(filename);
|
||||
free(fullpath);
|
||||
fclose (fp);
|
||||
@ -602,8 +613,19 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
x509_str = (BYTE*) realloc(x509_str, length);
|
||||
int new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
new_len = length * 2;
|
||||
new_str = (BYTE*) realloc(x509_str, new_len);
|
||||
if (!new_str)
|
||||
{
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
length = new_len;
|
||||
x509_str = new_str;
|
||||
|
||||
status = BIO_read(bio, &x509_str[offset], length);
|
||||
|
||||
@ -664,8 +686,19 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
x509_str = (BYTE*) realloc(x509_str, length);
|
||||
int new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
new_len = length * 2;
|
||||
new_str = (BYTE*) realloc(x509_str, new_len);
|
||||
if (!new_str)
|
||||
{
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
length = new_len;
|
||||
x509_str = new_str;
|
||||
|
||||
status = BIO_read(bio, &x509_str[offset], length);
|
||||
|
||||
@ -770,8 +803,19 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
x509_str = (BYTE*) realloc(x509_str, length);
|
||||
int new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
new_len = length * 2;
|
||||
new_str = (BYTE*) realloc(x509_str, new_len);
|
||||
if (!new_str)
|
||||
{
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
length = new_len;
|
||||
x509_str = new_str;
|
||||
|
||||
status = BIO_read(bio, &x509_str[offset], length);
|
||||
|
||||
@ -980,8 +1024,19 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
x509_str = (BYTE*) realloc(x509_str, length + 1);
|
||||
int new_len;
|
||||
BYTE *new_str;
|
||||
|
||||
new_len = length * 2;
|
||||
new_str = (BYTE*) realloc(x509_str, new_len);
|
||||
if (!new_str)
|
||||
{
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
length = new_len;
|
||||
x509_str = new_str;
|
||||
|
||||
status = BIO_read(bio, &x509_str[offset], length);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user