int shadow_client_boardcast_msg(rdpShadowServer* server, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam) { wMessage message = {0}; rdpShadowClient* client = NULL; int count = 0; int index = 0; message.context = context; message.id = type; message.wParam = (void *)msg; message.lParam = lParam; message.Free = shadow_msg_out_release; /* First add reference as we reference it in this function. * Therefore it would not be free'ed during post. */ shadow_msg_out_addref(&message); ArrayList_Lock(server->clients); for (index = 0; index < ArrayList_Count(server->clients); index++) { client = (rdpShadowClient*)ArrayList_GetItem(server->clients, index); if (shadow_client_dispatch_msg(client, &message)) { count++; } } ArrayList_Unlock(server->clients); /* Release the reference for this function */ shadow_msg_out_release(&message); return count; }
static rdpChannels* freerdp_channels_find_by_instance(freerdp* instance) { int index; BOOL found = FALSE; rdpChannels* channels = NULL; ArrayList_Lock(g_ChannelsList); index = 0; channels = (rdpChannels*) ArrayList_GetItem(g_ChannelsList, index++); while (channels) { if (channels->instance == instance) { found = TRUE; break; } channels = (rdpChannels*) ArrayList_GetItem(g_ChannelsList, index++); } ArrayList_Unlock(g_ChannelsList); return (found) ? channels : NULL; }
IWTSVirtualChannel *dvcman_find_channel_by_id(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId) { int index; BOOL found = FALSE; DVCMAN_CHANNEL *channel; DVCMAN *dvcman = (DVCMAN *) pChannelMgr; assert(dvcman); ArrayList_Lock(dvcman->channels); index = 0; channel = (DVCMAN_CHANNEL *) ArrayList_GetItem(dvcman->channels, index++); while (channel) { if (channel->channel_id == ChannelId) { found = TRUE; break; } channel = (DVCMAN_CHANNEL *) ArrayList_GetItem(dvcman->channels, index++); } ArrayList_Unlock(dvcman->channels); return (found) ? ((IWTSVirtualChannel *) channel) : NULL; }
static rdpPeerChannel* wts_get_dvc_channel_by_id(WTSVirtualChannelManager* vcm, UINT32 ChannelId) { int index; int count; BOOL found = FALSE; rdpPeerChannel* channel = NULL; ArrayList_Lock(vcm->dynamicVirtualChannels); count = ArrayList_Count(vcm->dynamicVirtualChannels); for (index = 0; index < count; index++) { channel = (rdpPeerChannel*) ArrayList_GetItem(vcm->dynamicVirtualChannels, index); if (channel->channelId == ChannelId) { found = TRUE; break; } } ArrayList_Unlock(vcm->dynamicVirtualChannels); return found ? channel : NULL; }
static rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex) { int i, j; BOOL found = FALSE; rdpChannels* channels = NULL; ArrayList_Lock(g_ChannelsList); i = j = 0; channels = (rdpChannels*) ArrayList_GetItem(g_ChannelsList, i++); while (channels) { for (j = 0; j < channels->channelDataCount; j++) { if (channels->channelDataList[j].open_handle == open_handle) { *pindex = j; found = TRUE; break; } } if (found) break; channels = (rdpChannels*) ArrayList_GetItem(g_ChannelsList, i++); } ArrayList_Unlock(g_ChannelsList); return (found) ? channels : NULL; }
static void _Publish(rdpShadowMultiClientEvent* event) { wArrayList* subscribers; struct rdp_shadow_multiclient_subscriber* subscriber = NULL; int i; subscribers = event->subscribers; assert(event->consuming == 0); /* Count subscribing clients */ ArrayList_Lock(subscribers); for (i = 0; i < ArrayList_Count(subscribers); i++) { subscriber = (struct rdp_shadow_multiclient_subscriber *)ArrayList_GetItem(subscribers, i); /* Set flag to subscriber: I acknowledge and please handle */ subscriber->pleaseHandle = TRUE; event->consuming++; } ArrayList_Unlock(subscribers); if (event->consuming > 0) { event->eventid = (event->eventid & 0xff) + 1; WLog_VRB(TAG, "Server published event %d. %d clients.\n", event->eventid, event->consuming); ResetEvent(event->doneEvent); SetEvent(event->event); } return; }
VOID WINAPI FreeRDP_WTSCloseServer(HANDLE hServer) { int index; int count; rdpPeerChannel* channel; WTSVirtualChannelManager* vcm; vcm = (WTSVirtualChannelManager*) hServer; if (vcm) { HashTable_Remove(g_ServerHandles, (void*)(UINT_PTR) vcm->SessionId); ArrayList_Lock(vcm->dynamicVirtualChannels); count = ArrayList_Count(vcm->dynamicVirtualChannels); for (index = 0; index < count; index++) { channel = (rdpPeerChannel*) ArrayList_GetItem(vcm->dynamicVirtualChannels, index); WTSVirtualChannelClose(channel); } ArrayList_Unlock(vcm->dynamicVirtualChannels); ArrayList_Free(vcm->dynamicVirtualChannels); if (vcm->drdynvc_channel) { WTSVirtualChannelClose(vcm->drdynvc_channel); vcm->drdynvc_channel = NULL; } MessageQueue_Free(vcm->queue); free(vcm); } }
WNDCLASSEXA* FindWindowClass(LPCSTR lpClassName) { int index; int count; BOOL found = FALSE; WNDCLASSEXA* lpwcx = NULL; ArrayList_Lock(g_WindowClasses); count = ArrayList_Count(g_WindowClasses); for (index = 0; index < count; index++) { lpwcx = (WNDCLASSEXA*) ArrayList_GetItem(g_WindowClasses, index); if (strcmp(lpClassName, lpwcx->lpszClassName) == 0) { found = TRUE; break; } } ArrayList_Unlock(g_WindowClasses); return (found) ? lpwcx : NULL; }
static rdpSvcPlugin* svc_plugin_find_by_open_handle(UINT32 open_handle) { int index; BOOL found = FALSE; rdpSvcPlugin* plugin; ArrayList_Lock(g_AddinList); index = 0; plugin = (rdpSvcPlugin*) ArrayList_GetItem(g_AddinList, index++); while (plugin) { if (plugin->open_handle == open_handle) { found = TRUE; break; } plugin = (rdpSvcPlugin*) ArrayList_GetItem(g_AddinList, index++); } ArrayList_Unlock(g_AddinList); return (found) ? plugin : NULL; }
TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE *guid) { UINT32 index; UINT32 count; BOOL found = FALSE; char guid_str[GUID_SIZE * 2 + 1]; TSMF_PRESENTATION* presentation; ArrayList_Lock(presentation_list); count = ArrayList_Count(presentation_list); for (index = 0; index < count; index++) { presentation = (TSMF_PRESENTATION*) ArrayList_GetItem(presentation_list, index); if (memcmp(presentation->presentation_id, guid, GUID_SIZE) == 0) { found = TRUE; break; } } ArrayList_Unlock(presentation_list); if (!found) WLog_WARN(TAG, "presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str))); return (found) ? presentation : NULL; }
BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, UINT32 x, UINT32 y, UINT32 width, UINT32 height, int num_rects, RDP_RECT *rects) { UINT32 index; UINT32 count; TSMF_STREAM* stream; void *tmp_rects = NULL; BOOL ret = TRUE; /* The server may send messages with invalid width / height. * Ignore those messages. */ if (!width || !height) return TRUE; /* Streams can be added/removed from the presentation and the server will resend geometry info when a new stream is * added to the presentation. Also, num_rects is used to indicate whether or not the window is visible. * So, always process a valid message with unchanged position/size and/or no visibility rects. */ presentation->x = x; presentation->y = y; presentation->width = width; presentation->height = height; tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects); if(!num_rects) presentation->rects=NULL; if (!tmp_rects&&num_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); for (index = 0; index < count; index++) { stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); if (!stream->decoder) continue; if (stream->decoder->UpdateRenderingArea) { ret = stream->decoder->UpdateRenderingArea(stream->decoder, x, y, width, height, num_rects, rects); } } ArrayList_Unlock(presentation->stream_list); return ret; }
BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, UINT32 x, UINT32 y, UINT32 width, UINT32 height, int num_rects, RDP_RECT *rects) { UINT32 index; UINT32 count; TSMF_STREAM* stream; void *tmp_rects; BOOL ret = TRUE; if (num_rects < 1 || !rects) return TRUE; /* The server may send messages with invalid width / height. * Ignore those messages. */ if (!width || !height) return TRUE; if ((width == presentation->width) && (height == presentation->height) && (x == presentation->x) && (y == presentation->y) && (num_rects == presentation->nr_rects) && (0 == memcmp(rects, presentation->rects, num_rects * sizeof(RDP_RECT)))) { return TRUE; } presentation->x = x; presentation->y = y; presentation->width = width; presentation->height = height; tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects); if (!tmp_rects) return FALSE; 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); for (index = 0; index < count; index++) { stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); if (!stream->decoder) continue; if (stream->decoder->UpdateRenderingArea) { ret = stream->decoder->UpdateRenderingArea(stream->decoder, x, y, width, height, num_rects, rects); } } ArrayList_Unlock(presentation->stream_list); return ret; }
void freerdp_channels_free(rdpChannels* channels) { MessagePipe_Free(channels->MsgPipe); ArrayList_Lock(g_ChannelsList); ArrayList_Remove(g_ChannelsList, channels); ArrayList_Unlock(g_ChannelsList); free(channels); }
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { int i; if (!lpFileName) return INVALID_HANDLE_VALUE; if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } if (_HandleCreators == NULL) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } ArrayList_Lock(_HandleCreators); for (i=0; i <= ArrayList_Count(_HandleCreators); i++) { HANDLE_CREATOR* creator = ArrayList_GetItem(_HandleCreators, i); if (creator && creator->IsHandled(lpFileName)) { HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); ArrayList_Unlock(_HandleCreators); return newHandle; } } ArrayList_Unlock(_HandleCreators); return INVALID_HANDLE_VALUE; }
void tsmf_presentation_sync(TSMF_PRESENTATION* presentation) { UINT32 index; UINT32 count; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { TSMF_STREAM* stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); WaitForSingleObject(stream->ready, 500); } ArrayList_Unlock(presentation->stream_list); }
void tsmf_presentation_start(TSMF_PRESENTATION* presentation) { UINT32 index; UINT32 count; TSMF_STREAM* stream; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); tsmf_stream_start(stream); } ArrayList_Unlock(presentation->stream_list); }
void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume, UINT32 muted) { UINT32 index; UINT32 count; TSMF_STREAM* stream; presentation->volume = newVolume; presentation->muted = muted; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); tsmf_stream_change_volume(stream, newVolume, muted); } ArrayList_Unlock(presentation->stream_list); }
BOOL tsmf_presentation_restarted(TSMF_PRESENTATION* presentation) { UINT32 index; UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_restart(stream); } ArrayList_Unlock(presentation->stream_list); return ret; }
int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode) { wMessageQueue* queue = NULL; int count = 0; int index = 0; ArrayList_Lock(server->clients); for (index = 0; index < ArrayList_Count(server->clients); index++) { queue = ((rdpShadowClient*)ArrayList_GetItem(server->clients, index))->MsgQueue; if (MessageQueue_PostQuit(queue, nExitCode)) { count++; } } ArrayList_Unlock(server->clients); return count; }
RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId) { int index; int count; RpcClientCall* clientCall; ArrayList_Lock(rpc->client->ClientCallList); clientCall = NULL; count = ArrayList_Count(rpc->client->ClientCallList); for (index = 0; index < count; index++) { clientCall = (RpcClientCall*) ArrayList_GetItem(rpc->client->ClientCallList, index); if (clientCall->CallId == CallId) break; } ArrayList_Unlock(rpc->client->ClientCallList); return clientCall; }
void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) { int i; int count; IWTSPlugin* pPlugin; DVCMAN_LISTENER* listener; DVCMAN_CHANNEL* channel; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; ArrayList_Lock(dvcman->channels); count = ArrayList_Count(dvcman->channels); for (i = 0; i < count; i++) { channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, i); dvcman_channel_free(channel); } ArrayList_Unlock(dvcman->channels); ArrayList_Free(dvcman->channels); for (i = 0; i < dvcman->num_listeners; i++) { listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; free(listener->channel_name); free(listener); } for (i = 0; i < dvcman->num_plugins; i++) { pPlugin = dvcman->plugins[i]; if (pPlugin->Terminated) pPlugin->Terminated(pPlugin); } StreamPool_Free(dvcman->pool); free(dvcman); }
static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe) { int index; NamedPipeServerSocketEntry* baseSocket; if (!pNamedPipe) return; assert(pNamedPipe->name); assert(g_NamedPipeServerSockets); //WLog_VRB(TAG, "%p (%s)", pNamedPipe, pNamedPipe->name); ArrayList_Lock(g_NamedPipeServerSockets); for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++) { baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem( g_NamedPipeServerSockets, index); assert(baseSocket->name); if (!strcmp(baseSocket->name, pNamedPipe->name)) { assert(baseSocket->references > 0); assert(baseSocket->serverfd != -1); if (--baseSocket->references == 0) { //WLog_DBG(TAG, "removing shared server socked resource"); //WLog_DBG(TAG, "closing shared serverfd %d", baseSocket->serverfd); ArrayList_Remove(g_NamedPipeServerSockets, baseSocket); close(baseSocket->serverfd); free(baseSocket->name); free(baseSocket); } break; } } ArrayList_Unlock(g_NamedPipeServerSockets); }
TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION *presentation, UINT32 stream_id) { UINT32 index; UINT32 count; BOOL found = FALSE; TSMF_STREAM *stream; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); if (stream->stream_id == stream_id) { found = TRUE; break; } } ArrayList_Unlock(presentation->stream_list); return (found) ? stream : NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation) { UINT32 index; UINT32 count; UINT error; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { TSMF_STREAM* stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); if (WaitForSingleObject(stream->ready, 500) == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); return error; } } ArrayList_Unlock(presentation->stream_list); return CHANNEL_RC_OK; }
static void winpr_unref_named_pipe(WINPR_NAMED_PIPE* pNamedPipe) { int index; NamedPipeServerSocketEntry *baseSocket; if (!pNamedPipe) return; assert(pNamedPipe->name); assert(g_NamedPipeServerSockets); //fprintf(stderr, "%s: %p (%s)\n", __FUNCTION__, pNamedPipe, pNamedPipe->name); ArrayList_Lock(g_NamedPipeServerSockets); for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++) { baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem( g_NamedPipeServerSockets, index); assert(baseSocket->name); if (!strcmp(baseSocket->name, pNamedPipe->name)) { assert(baseSocket->references > 0); assert(baseSocket->serverfd != -1); if (--baseSocket->references == 0) { //fprintf(stderr, "%s: removing shared server socked resource\n", __FUNCTION__); //fprintf(stderr, "%s: closing shared serverfd %d\n", __FUNCTION__, baseSocket->serverfd); ArrayList_Remove(g_NamedPipeServerSockets, baseSocket); close(baseSocket->serverfd); free(baseSocket->name); free(baseSocket); } break; } } ArrayList_Unlock(g_NamedPipeServerSockets); }
int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem) { SHADOW_MSG_OUT_POINTER_POSITION_UPDATE* msg; UINT32 msgId = SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID; rdpShadowClient* client; rdpShadowServer* server; int count = 0; int index = 0; msg = (SHADOW_MSG_OUT_POINTER_POSITION_UPDATE*) calloc(1, sizeof(SHADOW_MSG_OUT_POINTER_POSITION_UPDATE)); if (!msg) return -1; msg->xPos = subsystem->pointerX; msg->yPos = subsystem->pointerY; msg->Free = x11_shadow_message_free; server = subsystem->server; ArrayList_Lock(server->clients); for (index = 0; index < ArrayList_Count(server->clients); index++) { client = (rdpShadowClient*)ArrayList_GetItem(server->clients, index); /* Skip the client which send us the latest mouse event */ if (client == subsystem->lastMouseClient) continue; if (shadow_client_post_msg(client, NULL, msgId, (SHADOW_MSG_OUT*) msg, NULL)) count++; } ArrayList_Unlock(server->clients); return count; }
int win_shadow_surface_copy(winShadowSubsystem* subsystem) { int x, y; int width; int height; int count; int status = 1; int nDstStep = 0; BYTE* pDstData = NULL; rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 surfaceRect; RECTANGLE_16 invalidRect; const RECTANGLE_16* extents; server = subsystem->server; surface = server->surface; if (ArrayList_Count(server->clients) < 1) { region16_clear(&(subsystem->invalidRegion)); return 1; } surfaceRect.left = surface->x; surfaceRect.top = surface->y; surfaceRect.right = surface->x + surface->width; surfaceRect.bottom = surface->y + surface->height; region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect); if (region16_is_empty(&(subsystem->invalidRegion))) return 1; extents = region16_extents(&(subsystem->invalidRegion)); CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16)); shadow_capture_align_clip_rect(&invalidRect, &surfaceRect); x = invalidRect.left; y = invalidRect.top; width = invalidRect.right - invalidRect.left; height = invalidRect.bottom - invalidRect.top; if (0) { x = 0; y = 0; width = surface->width; height = surface->height; } WLog_INFO(TAG, "SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d", x, y, width, height, x + width, y + height); #if defined(WITH_WDS_API) { rdpGdi* gdi; shwContext* shw; rdpContext* context; shw = subsystem->shw; context = (rdpContext*) shw; gdi = context->gdi; pDstData = gdi->primary_buffer; nDstStep = gdi->width * 4; } #elif defined(WITH_DXGI_1_2) status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height); #endif if (status <= 0) return status; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x - surface->x, y - surface->y, width, height, pDstData, PIXEL_FORMAT_XRGB32, nDstStep, 0, 0, NULL); ArrayList_Lock(server->clients); count = ArrayList_Count(server->clients); shadow_multiclient_publish_and_wait(subsystem->updateEvent); ArrayList_Unlock(server->clients); region16_clear(&(subsystem->invalidRegion)); return 1; }
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { int index; HANDLE hNamedPipe = INVALID_HANDLE_VALUE; char* lpPipePath; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe = NULL; int serverfd = -1; NamedPipeServerSocketEntry* baseSocket = NULL; if (!lpName) return INVALID_HANDLE_VALUE; InitWinPRPipeModule(); pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE)); if (!pNamedPipe) return INVALID_HANDLE_VALUE; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); if (!(pNamedPipe->name = _strdup(lpName))) goto out; if (!(pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName))) goto out; if (!(pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName))) goto out; pNamedPipe->dwOpenMode = dwOpenMode; pNamedPipe->dwPipeMode = dwPipeMode; pNamedPipe->nMaxInstances = nMaxInstances; pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->clientfd = -1; pNamedPipe->ServerMode = TRUE; ArrayList_Lock(g_NamedPipeServerSockets); for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++) { baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem( g_NamedPipeServerSockets, index); if (!strcmp(baseSocket->name, lpName)) { serverfd = baseSocket->serverfd; //WLog_DBG(TAG, "using shared socked resource for pipe %p (%s)", pNamedPipe, lpName); break; } } /* If this is the first instance of the named pipe... */ if (serverfd == -1) { /* Create the UNIX domain socket and start listening. */ if (!(lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA())) goto out; if (!PathFileExistsA(lpPipePath)) { CreateDirectoryA(lpPipePath, 0); UnixChangeFileMode(lpPipePath, 0xFFFF); } free(lpPipePath); if (PathFileExistsA(pNamedPipe->lpFilePath)) { DeleteFileA(pNamedPipe->lpFilePath); } if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: socket error, %s", strerror(errno)); goto out; } ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); if (bind(serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: bind error, %s", strerror(errno)); goto out; } if (listen(serverfd, 2) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: listen error, %s", strerror(errno)); goto out; } UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); if (!(baseSocket = (NamedPipeServerSocketEntry*) malloc(sizeof(NamedPipeServerSocketEntry)))) goto out; if (!(baseSocket->name = _strdup(lpName))) { free(baseSocket); goto out; } baseSocket->serverfd = serverfd; baseSocket->references = 0; ArrayList_Add(g_NamedPipeServerSockets, baseSocket); //WLog_DBG(TAG, "created shared socked resource for pipe %p (%s). base serverfd = %d", pNamedPipe, lpName, serverfd); } pNamedPipe->serverfd = dup(baseSocket->serverfd); //WLog_DBG(TAG, "using serverfd %d (duplicated from %d)", pNamedPipe->serverfd, baseSocket->serverfd); pNamedPipe->pfnUnrefNamedPipe = winpr_unref_named_pipe; baseSocket->references++; if (dwOpenMode & FILE_FLAG_OVERLAPPED) { #if 0 int flags = fcntl(pNamedPipe->serverfd, F_GETFL); if (flags != -1) fcntl(pNamedPipe->serverfd, F_SETFL, flags | O_NONBLOCK); #endif } hNamedPipe = (HANDLE) pNamedPipe; out: if (hNamedPipe == INVALID_HANDLE_VALUE) { if (pNamedPipe) { free((void*)pNamedPipe->name); free((void*)pNamedPipe->lpFileName); free((void*)pNamedPipe->lpFilePath); free(pNamedPipe); } if (serverfd != -1) close(serverfd); } ArrayList_Unlock(g_NamedPipeServerSockets); return hNamedPipe; }
static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync) { UINT32 index; UINT32 count; TSMF_STREAM *s; TSMF_SAMPLE* sample; BOOL pending = FALSE; TSMF_PRESENTATION* presentation = stream->presentation; if (!stream) return NULL; if (Queue_Count(stream->sample_list) < 1) return NULL; if (sync) { if (stream->decoder) { if (stream->decoder->GetDecodedData) { if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO) { /* Check if some other stream has earlier sample that needs to be played first */ /* Start time is more reliable than end time as some stream types seem to have incorrect * end times from the server */ if (stream->last_start_time > AUDIO_TOLERANCE) { ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { s = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); /* Start time is more reliable than end time as some stream types seem to have incorrect * end times from the server */ if (s != stream && !s->eos && s->last_start_time && s->last_start_time < stream->last_start_time - AUDIO_TOLERANCE) { DEBUG_TSMF("Pending due to audio tolerance"); pending = TRUE; break; } } ArrayList_Unlock(presentation->stream_list); } } else { /* Start time is more reliable than end time as some stream types seem to have incorrect * end times from the server */ if (stream->last_start_time > presentation->audio_start_time) { DEBUG_TSMF("Pending due to stream start time > audio start time"); pending = TRUE; } } } } } if (pending) return NULL; sample = (TSMF_SAMPLE *) Queue_Dequeue(stream->sample_list); /* Only update stream last end time if the sample end time is valid and greater than the current stream end time */ if (sample && (sample->end_time > stream->last_end_time) && (!sample->invalidTimestamps)) stream->last_end_time = sample->end_time; /* Only update stream last start time if the sample start time is valid and greater than the current stream start time */ if (sample && (sample->start_time > stream->last_start_time) && (!sample->invalidTimestamps)) stream->last_start_time = sample->start_time; return sample; }
static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) { BOOL ret = FALSE; UINT32 width; UINT32 height; UINT32 pixfmt = 0; TSMF_STREAM* stream = sample->stream; if (stream->decoder) { if (stream->decoder->DecodeEx) { /* Try to "sync" video buffers to audio buffers by looking at the running time for each stream * The difference between the two running times causes an offset between audio and video actual * render times. So, we try to adjust timestamps on the video buffer to match those on the audio buffer. */ if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO) { TSMF_STREAM* temp_stream = NULL; TSMF_PRESENTATION* presentation = stream->presentation; ArrayList_Lock(presentation->stream_list); int count = ArrayList_Count(presentation->stream_list); int index = 0; for (index = 0; index < count; index++) { UINT64 time_diff; temp_stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); if (temp_stream->major_type == TSMF_MAJOR_TYPE_AUDIO) { UINT64 video_time = (UINT64) stream->decoder->GetRunningTime(stream->decoder); UINT64 audio_time = (UINT64) temp_stream->decoder->GetRunningTime(temp_stream->decoder); UINT64 max_adjust = VIDEO_ADJUST_MAX; if (video_time < audio_time) max_adjust = -VIDEO_ADJUST_MAX; if (video_time > audio_time) time_diff = video_time - audio_time; else time_diff = audio_time - video_time; time_diff = time_diff < VIDEO_ADJUST_MAX ? time_diff : max_adjust; sample->start_time += time_diff; sample->end_time += time_diff; break; } } ArrayList_Unlock(presentation->stream_list); } ret = stream->decoder->DecodeEx(stream->decoder, sample->data, sample->data_size, sample->extensions, sample->start_time, sample->end_time, sample->duration); } else { ret = stream->decoder->Decode(stream->decoder, sample->data, sample->data_size, sample->extensions); } } if (!ret) { WLog_ERR(TAG, "decode error, queue ack anyways"); if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); return FALSE; } return TRUE; } free(sample->data); sample->data = NULL; if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO) { if (stream->decoder->GetDecodedFormat) { pixfmt = stream->decoder->GetDecodedFormat(stream->decoder); if (pixfmt == ((UINT32) -1)) { WLog_ERR(TAG, "unable to decode video format"); if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); } return FALSE; } sample->pixfmt = pixfmt; } if (stream->decoder->GetDecodedDimension) { ret = stream->decoder->GetDecodedDimension(stream->decoder, &width, &height); if (ret && (width != stream->width || height != stream->height)) { DEBUG_TSMF("video dimension changed to %d x %d", width, height); stream->width = width; stream->height = height; } } } if (stream->decoder->GetDecodedData) { sample->data = stream->decoder->GetDecodedData(stream->decoder, &sample->decoded_size); switch (sample->stream->major_type) { case TSMF_MAJOR_TYPE_VIDEO: ret = tsmf_sample_playback_video(sample) && tsmf_sample_queue_ack(sample); break; case TSMF_MAJOR_TYPE_AUDIO: ret = tsmf_sample_playback_audio(sample) && tsmf_sample_queue_ack(sample); break; } } else { TSMF_STREAM* stream = sample->stream; UINT64 ack_anticipation_time = get_current_time(); BOOL buffer_filled = TRUE; /* Classify the buffer as filled once it reaches minimum level */ if (stream->decoder->BufferLevel) { if (stream->currentBufferLevel < stream->minBufferLevel) buffer_filled = FALSE; } if (buffer_filled) { ack_anticipation_time += (sample->duration/2 < MAX_ACK_TIME) ? sample->duration/2 : MAX_ACK_TIME; } else { ack_anticipation_time += (sample->duration/2 < MAX_ACK_TIME) ? sample->duration/2 : MAX_ACK_TIME; } switch (sample->stream->major_type) { case TSMF_MAJOR_TYPE_VIDEO: { break; } case TSMF_MAJOR_TYPE_AUDIO: { break; } } sample->ack_time = ack_anticipation_time; if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); ret = FALSE; } } return ret; }