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); } }
void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) { wts_data_item* item; rdpPeerChannel* channel; if (vcm != NULL) { while ((channel = (rdpPeerChannel*) list_dequeue(vcm->dvc_channel_list)) != NULL) { WTSVirtualChannelClose(channel); } list_free(vcm->dvc_channel_list); if (vcm->drdynvc_channel != NULL) { WTSVirtualChannelClose(vcm->drdynvc_channel); vcm->drdynvc_channel = NULL; } CloseHandle(vcm->send_event); while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL) { wts_data_item_free(item); } list_free(vcm->send_queue); CloseHandle(vcm->mutex); free(vcm); } }
void rdpsnd_server_context_free(rdpsnd_server_context* context) { rdpsnd_server* rdpsnd = (rdpsnd_server*) context; if (rdpsnd->rdpsnd_channel_thread) { freerdp_thread_stop(rdpsnd->rdpsnd_channel_thread); freerdp_thread_free(rdpsnd->rdpsnd_channel_thread); } if (rdpsnd->rdpsnd_channel) WTSVirtualChannelClose(rdpsnd->rdpsnd_channel); if (rdpsnd->rdpsnd_pdu) stream_free(rdpsnd->rdpsnd_pdu); if (rdpsnd->out_buffer) free(rdpsnd->out_buffer); if (rdpsnd->dsp_context) freerdp_dsp_context_free(rdpsnd->dsp_context); if (rdpsnd->context.client_formats) free(rdpsnd->context.client_formats); free(rdpsnd); }
static int rdpsnd_server_start(RdpsndServerContext* context) { context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd"); if (!context->priv->ChannelHandle) return -1; context->priv->rdpsnd_pdu = Stream_New(NULL, 4096); if (!context->priv->rdpsnd_pdu) goto out_close; context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!context->priv->StopEvent) goto out_pdu; context->priv->Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL); if (!context->priv->Thread) goto out_stopEvent; return 0; out_stopEvent: CloseHandle(context->priv->StopEvent); context->priv->StopEvent = NULL; out_pdu: Stream_Free(context->priv->rdpsnd_pdu, TRUE); context->priv->rdpsnd_pdu = NULL; out_close: WTSVirtualChannelClose(context->priv->ChannelHandle); context->priv->ChannelHandle = NULL; return -1; }
static BOOL audin_server_close(audin_server_context* context) { audin_server* audin = (audin_server*) context; if (audin->thread) { SetEvent(audin->stopEvent); if (WaitForSingleObject(audin->thread, INFINITE) == WAIT_FAILED) { WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); return FALSE; } CloseHandle(audin->thread); CloseHandle(audin->stopEvent); audin->thread = NULL; audin->stopEvent = NULL; } if (audin->audin_channel) { WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; } audin->context.selected_client_format = -1; return TRUE; }
void rdpsnd_server_context_free(RdpsndServerContext* context) { if (!context->priv->StopEvent) { SetEvent(context->priv->StopEvent); WaitForSingleObject(context->priv->Thread, INFINITE); } if (context->priv->ChannelHandle) WTSVirtualChannelClose(context->priv->ChannelHandle); if (context->priv->rdpsnd_pdu) Stream_Free(context->priv->rdpsnd_pdu, TRUE); if (context->priv->out_buffer) free(context->priv->out_buffer); if (context->priv->dsp_context) freerdp_dsp_context_free(context->priv->dsp_context); if (context->client_formats) free(context->client_formats); free(context); }
static BOOL rdpgfx_server_close(RdpgfxServerContext* context) { RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; if (priv->ownThread && priv->thread) { SetEvent(priv->stopEvent); if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED) { WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", (unsigned long)GetLastError()); return FALSE; } CloseHandle(priv->thread); CloseHandle(priv->stopEvent); priv->thread = NULL; priv->stopEvent = NULL; } zgfx_context_free(priv->zgfx); priv->zgfx = NULL; if (priv->rdpgfx_channel) { WTSVirtualChannelClose(priv->rdpgfx_channel); priv->rdpgfx_channel = NULL; } priv->channelEvent = NULL; priv->isOpened = FALSE; priv->isReady = FALSE; return TRUE; }
void test_peer_context_free(freerdp_peer* client, testPeerContext* context) { if (context) { if (context->debug_channel_thread) { SetEvent(context->stopEvent); WaitForSingleObject(context->debug_channel_thread, INFINITE); CloseHandle(context->debug_channel_thread); } Stream_Free(context->s, TRUE); free(context->icon_data); free(context->bg_data); rfx_context_free(context->rfx_context); nsc_context_free(context->nsc_context); if (context->debug_channel) WTSVirtualChannelClose(context->debug_channel); if (context->audin) audin_server_context_free(context->audin); if (context->rdpsnd) rdpsnd_server_context_free(context->rdpsnd); WTSCloseServer((HANDLE) context->vcm); } }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT rdpei_server_init(RdpeiServerContext *context) { void *buffer = NULL; DWORD bytesReturned; RdpeiServerPrivate *priv = context->priv; priv->channelHandle = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, RDPEI_DVC_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC); if (!priv->channelHandle) { WLog_ERR(TAG, "WTSVirtualChannelOpenEx failed!"); return CHANNEL_RC_INITIALIZATION_ERROR; } if (!WTSVirtualChannelQuery(priv->channelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE))) { WLog_ERR(TAG, "WTSVirtualChannelQuery failed or invalid invalid returned size(%d)!", bytesReturned); if (buffer) WTSFreeMemory(buffer); goto out_close; } CopyMemory(&priv->eventHandle, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); return CHANNEL_RC_OK; out_close: WTSVirtualChannelClose(priv->channelHandle); return CHANNEL_RC_INITIALIZATION_ERROR; }
void test_peer_context_free(freerdp_peer* client, testPeerContext* context) { if (context) { if (context->debug_channel_thread) { freerdp_thread_stop(context->debug_channel_thread); freerdp_thread_free(context->debug_channel_thread); } stream_free(context->s); free(context->icon_data); free(context->bg_data); rfx_context_free(context->rfx_context); nsc_context_free(context->nsc_context); if (context->debug_channel) WTSVirtualChannelClose(context->debug_channel); if (context->audin) audin_server_context_free(context->audin); if (context->rdpsnd) rdpsnd_server_context_free(context->rdpsnd); WTSDestroyVirtualChannelManager(context->vcm); } }
int rdpei_server_init(RdpeiServerContext *context) { void *buffer = NULL; DWORD bytesReturned; RdpeiServerPrivate *priv = context->priv; priv->channelHandle = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, RDPEI_DVC_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC); if (!priv->channelHandle) { fprintf(stderr, "%s: unable to open channel\n", __FUNCTION__); return -1; } if (!WTSVirtualChannelQuery(priv->channelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE))) { fprintf(stderr, "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n", __FUNCTION__, bytesReturned); if (buffer) WTSFreeMemory(buffer); goto out_close; } CopyMemory(&priv->eventHandle, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); return 0; out_close: WTSVirtualChannelClose(priv->channelHandle); return -1; }
int OurInterface::closeVirtualChannel() { /* channel must be opened first */ if (!channel) return -1; WTSVirtualChannelClose(channel); return 0; }
void rdpei_server_context_free(RdpeiServerContext* context) { RdpeiServerPrivate *priv = context->priv; if (priv->channelHandle != INVALID_HANDLE_VALUE) WTSVirtualChannelClose(priv->channelHandle); Stream_Free(priv->inputStream, TRUE); free(priv); free(context); }
/* * Open a dynamic channel with the name given in szChannelName * the output file handle can be used in ReadFile/WriteFile calls */ DWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE* phFile) { HANDLE hWTSHandle = NULL; HANDLE hWTSFileHandle; PVOID vcFileHandlePtr = NULL; DWORD len; DWORD rc = ERROR_SUCCESS; hWTSHandle = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, (LPSTR)szChannelName, WTS_CHANNEL_OPTION_DYNAMIC); if (!hWTSHandle) { rc = GetLastError(); printf("WTSVirtualChannelOpenEx API Call Failed: GetLastError() = %d\n", GetLastError()); goto exitpt; } BOOL bSucc = WTSVirtualChannelQuery(hWTSHandle, WTSVirtualFileHandle, &vcFileHandlePtr, &len); if ( !bSucc ) { rc = GetLastError(); goto exitpt; } if ( len != sizeof( HANDLE )) { rc = ERROR_INVALID_PARAMETER; goto exitpt; } hWTSFileHandle = *(HANDLE *)vcFileHandlePtr; bSucc = DuplicateHandle( GetCurrentProcess(), hWTSFileHandle, GetCurrentProcess(), phFile, 0, FALSE, DUPLICATE_SAME_ACCESS ); if ( !bSucc ) { rc = GetLastError(); goto exitpt; } rc = ERROR_SUCCESS; exitpt: if ( vcFileHandlePtr ) { WTSFreeMemory( vcFileHandlePtr ); } if ( hWTSHandle ) { WTSVirtualChannelClose( hWTSHandle ); } return rc; }
void remdesk_server_context_free(RemdeskServerContext* context) { if (context) { if (context->priv->ChannelHandle != INVALID_HANDLE_VALUE) WTSVirtualChannelClose(context->priv->ChannelHandle); free(context->priv); free(context); } }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_server_close(CliprdrServerContext* context) { CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; if (cliprdr->ChannelHandle) { WTSVirtualChannelClose(cliprdr->ChannelHandle); cliprdr->ChannelHandle = NULL; } return CHANNEL_RC_OK; }
static int rdpsnd_server_start(RdpsndServerContext* context) { void *buffer = NULL; DWORD bytesReturned; RdpsndServerPrivate *priv = context->priv; priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd"); if (!priv->ChannelHandle) return -1; if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE))) { WLog_ERR(TAG, "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n", __FUNCTION__, bytesReturned); if (buffer) WTSFreeMemory(buffer); goto out_close; } CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); priv->rdpsnd_pdu = Stream_New(NULL, 4096); if (!priv->rdpsnd_pdu) goto out_close; if (priv->ownThread) { context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!context->priv->StopEvent) goto out_pdu; context->priv->Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL); if (!context->priv->Thread) goto out_stopEvent; } return 0; out_stopEvent: CloseHandle(context->priv->StopEvent); context->priv->StopEvent = NULL; out_pdu: Stream_Free(context->priv->rdpsnd_pdu, TRUE); context->priv->rdpsnd_pdu = NULL; out_close: WTSVirtualChannelClose(context->priv->ChannelHandle); context->priv->ChannelHandle = NULL; return -1; }
int main() { // Initialize the data for send/receive char* data; char* data1; data = (char*)malloc(DSIZE); data1 = (char*)malloc(DSIZE); memset(data, 0xca, DSIZE); memset(data1, 0, DSIZE); // Open the skel channel in current session void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); unsigned long written = 0; // Write the data to the channel bool ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); if (!ret) { long err = GetLastError(); fprintf(stderr, "error 0x%8.8x\n", err); return 1; } ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); if (!ret) { long err = GetLastError(); fprintf(stderr, "error 0x%8.8x\n", err); return 1; } if (written != DSIZE) { fprintf(stderr, "error read %d\n", written); return 1; } ret = WTSVirtualChannelClose(channel); if (memcmp(data, data1, DSIZE) == 0) { } else { fprintf(stderr, "error data no match\n"); return 1; } fprintf(stderr, "Success!\n"); Sleep(2000); return 0; }
int TestWtsApiExtraVirtualChannel(int argc, char* argv[]) { BOOL bSuccess; ULONG length; ULONG bytesRead; ULONG bytesWritten; BYTE buffer[1024]; HANDLE hVirtualChannel; length = sizeof(buffer); hVirtualChannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, "sample"); if (hVirtualChannel == INVALID_HANDLE_VALUE) { printf("WTSVirtualChannelOpen failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelOpen opend"); bytesWritten = 0; bSuccess = WTSVirtualChannelWrite(hVirtualChannel, (PCHAR) buffer, length, &bytesWritten); if (!bSuccess) { printf("WTSVirtualChannelWrite failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelWrite written"); bytesRead = 0; bSuccess = WTSVirtualChannelRead(hVirtualChannel, 5000, (PCHAR) buffer, length, &bytesRead); if (!bSuccess) { printf("WTSVirtualChannelRead failed: %d\n", (int) GetLastError()); return -1; } printf("WTSVirtualChannelRead read"); if (!WTSVirtualChannelClose(hVirtualChannel)) { printf("WTSVirtualChannelClose failed\n"); return -1; } return 0; }
void rdpsnd_server_context_free(RdpsndServerContext* context) { if (context->priv->ChannelHandle) WTSVirtualChannelClose(context->priv->ChannelHandle); free(context->priv->out_buffer); if (context->priv->dsp_context) freerdp_dsp_context_free(context->priv->dsp_context); if (context->priv->input_stream) Stream_Free(context->priv->input_stream, TRUE); free(context->client_formats); free(context); }
static BOOL audin_server_close(audin_server_context* context) { audin_server* audin = (audin_server*) context; if (audin->audin_channel_thread) { freerdp_thread_stop(audin->audin_channel_thread); freerdp_thread_free(audin->audin_channel_thread); audin->audin_channel_thread = NULL; } if (audin->audin_channel) { WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; } audin->context.selected_client_format = -1; return TRUE; }
void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) { wts_data_item* item; if (vcm != NULL) { if (vcm->drdynvc_channel != NULL) { WTSVirtualChannelClose(vcm->drdynvc_channel); vcm->drdynvc_channel = NULL; } wait_obj_free(vcm->send_event); while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL) { wts_data_item_free(item); } list_free(vcm->send_queue); freerdp_mutex_free(vcm->mutex); xfree(vcm); } }
static BOOL audin_server_close(audin_server_context* context) { audin_server* audin = (audin_server*) context; if (audin->thread) { SetEvent(audin->stopEvent); WaitForSingleObject(audin->thread, INFINITE); CloseHandle(audin->thread); CloseHandle(audin->stopEvent); audin->thread = NULL; audin->stopEvent = NULL; } if (audin->audin_channel) { WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; } audin->context.selected_client_format = -1; return TRUE; }
static BOOL rdpgfx_server_open(RdpgfxServerContext* context) { RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; void* buffer = NULL; if (!priv->isOpened) { PULONG pSessionId = NULL; DWORD BytesReturned = 0; priv->SessionId = WTS_CURRENT_SESSION; if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION, WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSQuerySessionInformationA failed!"); return FALSE; } priv->SessionId = (DWORD) * pSessionId; WTSFreeMemory(pSessionId); priv->rdpgfx_channel = WTSVirtualChannelOpenEx(priv->SessionId, RDPGFX_DVC_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC); if (!priv->rdpgfx_channel) { WLog_ERR(TAG, "WTSVirtualChannelOpenEx failed!"); return FALSE; } /* Query for channel event handle */ if (!WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) || (BytesReturned != sizeof(HANDLE))) { WLog_ERR(TAG, "WTSVirtualChannelQuery failed " "or invalid returned size(%d)", BytesReturned); if (buffer) WTSFreeMemory(buffer); goto out_close; } CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); if (!(priv->zgfx = zgfx_context_new(TRUE))) { WLog_ERR(TAG, "Create zgfx context failed!"); goto out_close; } if (priv->ownThread) { if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); goto out_zgfx; } if (!(priv->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpgfx_server_thread_func, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); goto out_stopEvent; } } priv->isOpened = TRUE; priv->isReady = FALSE; return TRUE; } WLog_ERR(TAG, "RDPGFX channel is already opened!"); return FALSE; out_stopEvent: CloseHandle(priv->stopEvent); priv->stopEvent = NULL; out_zgfx: zgfx_context_free(priv->zgfx); priv->zgfx = NULL; out_close: WTSVirtualChannelClose(priv->rdpgfx_channel); priv->rdpgfx_channel = NULL; priv->channelEvent = NULL; return FALSE; }
static void* audin_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; BYTE MessageId; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; audin_server* audin = (audin_server*) arg; UINT error = CHANNEL_RC_OK; DWORD status; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } else { WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); error = ERROR_INTERNAL_ERROR; goto out; } nCount = 0; events[nCount++] = audin->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0) goto out; if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); goto out; } if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); error = ERROR_INTERNAL_ERROR; goto out; } ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) break; } s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto out; } if (ready) { if ((error = audin_server_send_version(audin, s))) { WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error); goto out_capacity; } } while (ready) { if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0) break; if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); goto out; } Stream_SetPosition(s, 0); if (!WTSVirtualChannelRead(audin->audin_channel, 0, NULL, 0, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) break; if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } Stream_Read_UINT8(s, MessageId); BytesReturned--; switch (MessageId) { case MSG_SNDIN_VERSION: if ((error = audin_server_recv_version(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error); goto out_capacity; } if ((error = audin_server_send_formats(audin, s))) { WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_FORMATS: if ((error = audin_server_recv_formats(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error); goto out_capacity; } if ((error = audin_server_send_open(audin, s))) { WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_OPEN_REPLY: if ((error = audin_server_recv_open_reply(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error); goto out_capacity; } break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: if ((error = audin_server_recv_data(audin, s, BytesReturned))) { WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error); goto out_capacity; }; break; case MSG_SNDIN_FORMATCHANGE: break; default: WLog_ERR(TAG, "audin_server_thread_func: unknown MessageId %d", MessageId); break; } } out_capacity: Stream_Free(s, TRUE); out: WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; if (error && audin->context.rdpcontext) setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; }
HRESULT CTsTeleportShellExt::GetVirtualChannelHandle(HANDLE *phFile) { HRESULT hr = S_OK; HANDLE hWTSHandle = NULL; PVOID vcFileHandlePtr = NULL; // // Open Virtual channel // hWTSHandle = WTSVirtualChannelOpenEx( WTS_CURRENT_SESSION, TSTELE_CHANNEL_NAME, WTS_CHANNEL_OPTION_DYNAMIC); if (NULL == hWTSHandle) { hr = HRESULT_FROM_WIN32(GetLastError()); } LEAVE_IF_FAILED("WTSVirtualChannelOpenEx failed"); // // Get channel file handle // DWORD len; BOOL bSucc = WTSVirtualChannelQuery( hWTSHandle, WTSVirtualFileHandle, &vcFileHandlePtr, &len); if (!bSucc) { hr = HRESULT_FROM_WIN32(GetLastError()); } LEAVE_IF_FAILED("WTSVirtualChannelQuery failed"); if (len != sizeof(HANDLE)) { hr = E_UNEXPECTED; } LEAVE_IF_FAILED("WTSVirtualChannelQuery return unexpected"); HANDLE hWTSFileHandle = *(HANDLE *)vcFileHandlePtr; // // Duplicate handle so that we can close // bSucc = DuplicateHandle( GetCurrentProcess(), hWTSFileHandle, GetCurrentProcess(), phFile, 0, FALSE, DUPLICATE_SAME_ACCESS); if (!bSucc) { hr = HRESULT_FROM_WIN32(GetLastError()); } LEAVE_IF_FAILED("DuplicateHandle failed"); _Function_Exit: // // Cleanup // if (vcFileHandlePtr) { WTSFreeMemory(vcFileHandlePtr); } if (hWTSHandle) { WTSVirtualChannelClose(hWTSHandle); } return hr; }
static void* audin_server_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; BYTE MessageId; BOOL ready = FALSE; UINT32 bytes_returned = 0; audin_server* audin = (audin_server*) arg; freerdp_thread* thread = audin->audin_channel_thread; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE) break; ready = *((BOOL*)buffer); WTSFreeMemory(buffer); if (ready) break; } s = stream_new(4096); if (ready) { audin_server_send_version(audin, s); } while (ready) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, (int) bytes_returned); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) break; } if (bytes_returned < 1) continue; stream_read_BYTE(s, MessageId); bytes_returned--; switch (MessageId) { case MSG_SNDIN_VERSION: if (audin_server_recv_version(audin, s, bytes_returned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: if (audin_server_recv_formats(audin, s, bytes_returned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: audin_server_recv_open_reply(audin, s, bytes_returned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: audin_server_recv_data(audin, s, bytes_returned); break; case MSG_SNDIN_FORMATCHANGE: break; default: printf("audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } stream_free(s); WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; freerdp_thread_quit(thread); return NULL; }
static void* echo_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; echo_server* echo = (echo_server*) arg; UINT error; DWORD status; if ((error = echo_server_open_channel(echo))) { UINT error2 = 0; WLog_ERR(TAG, "echo_server_open_channel failed with error %lu!", error); IFCALLRET(echo->context.OpenResult, error2, &echo->context, ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED); if (error2) WLog_ERR(TAG, "echo server's OpenResult callback failed with error %lu", error2); goto out; } buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = echo->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Graphics Pipeline dynamic channel is ready */ while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, 100); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); break; } if (status == WAIT_OBJECT_0) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_CLOSED); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_ERROR); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) { IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_OK); if (error) WLog_ERR(TAG, "OpenResult failed with error %lu!", error); break; } } s = Stream_New(NULL, 4096); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); WTSVirtualChannelClose(echo->echo_channel); ExitThread((DWORD)ERROR_NOT_ENOUGH_MEMORY); return NULL; } while (ready) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); break; } if (status == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); WTSVirtualChannelRead(echo->echo_channel, 0, NULL, 0, &BytesReturned); if (BytesReturned < 1) continue; if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); error = CHANNEL_RC_NO_MEMORY; break; } if (WTSVirtualChannelRead(echo->echo_channel, 0, (PCHAR) Stream_Buffer(s), (ULONG) Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } IFCALLRET(echo->context.Response, error, &echo->context, (BYTE*) Stream_Buffer(s), BytesReturned); if (error) { WLog_ERR(TAG, "Response failed with error %lu!", error); break; } } Stream_Free(s, TRUE); WTSVirtualChannelClose(echo->echo_channel); echo->echo_channel = NULL; out: if (error && echo->context.rdpcontext) setChannelError(echo->context.rdpcontext, error, "echo_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; }
int _tmain(int argc, _TCHAR* argv[]) { HANDLE hChannel = NULL; PingPayload payload = { 0 }; ULONG bytesRead=0, bytesWritten=0; UINT32 currentSequenceNo = 0; hChannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, -1, "JDECHO"); if (hChannel == NULL) { Log("Unable to open virtual channel: %i\r\n", GetLastError()); Log("Are you running inside a remote desktop session?"); goto End; } while (true) { // Send the ping packet across the virtual channel payload.SequenceNo = currentSequenceNo++; payload.TimeStamp = GetTickCount(); if (!WTSVirtualChannelWrite(hChannel, (PCHAR)&payload, sizeof(payload), &bytesWritten)) { Log("WTSVirtualChannelWrite failed: %i\t\n", GetLastError()); goto End; } if (bytesWritten != sizeof(payload)) { Log("Error: Partial writes are not handled"); goto End; } // Wait for the echo channel to send the same packet back if (!WTSVirtualChannelRead(hChannel, INFINITE, (PCHAR)&payload, sizeof(payload), &bytesRead)) { Log("WTSVirtualChannelRead failed: %i", GetLastError()); goto End; } if (bytesRead != sizeof(payload)) { Log("Error partial reads are not handled"); goto End; } // Print statistics Log("Got ping reply: %i, %ims", (int)payload.SequenceNo, (int)(GetTickCount()-payload.TimeStamp)); // Wait for a second before pinging again Sleep(1000); } End: if (hChannel != NULL) { WTSVirtualChannelClose(hChannel); } }
static void* audin_server_thread_func(void* arg) { wStream* s; void* buffer; DWORD nCount; BYTE MessageId; HANDLE events[8]; BOOL ready = FALSE; HANDLE ChannelEvent; DWORD BytesReturned = 0; audin_server* audin = (audin_server*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); } nCount = 0; events[nCount++] = audin->stopEvent; events[nCount++] = ChannelEvent; /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { if (WaitForMultipleObjects(nCount, events, FALSE, 100) == WAIT_OBJECT_0) break; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) break; ready = *((BOOL*) buffer); WTSFreeMemory(buffer); if (ready) break; } s = Stream_New(NULL, 4096); if (!s) goto out; if (ready) { audin_server_send_version(audin, s); } while (ready) { if (WaitForMultipleObjects(nCount, events, FALSE, INFINITE) == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { if (BytesReturned == 0) break; Stream_EnsureRemainingCapacity(s, BytesReturned); if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE) { break; } } if (BytesReturned < 1) continue; Stream_Read_UINT8(s, MessageId); BytesReturned--; switch (MessageId) { case MSG_SNDIN_VERSION: if (audin_server_recv_version(audin, s, BytesReturned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: if (audin_server_recv_formats(audin, s, BytesReturned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: audin_server_recv_open_reply(audin, s, BytesReturned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: audin_server_recv_data(audin, s, BytesReturned); break; case MSG_SNDIN_FORMATCHANGE: break; default: fprintf(stderr, "audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } Stream_Free(s, TRUE); out: WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; return NULL; }