int rpc_client_stop(rdpRpc* rpc) { if (rpc->client->Thread) { SetEvent(rpc->client->StopEvent); WaitForSingleObject(rpc->client->Thread, INFINITE); rpc->client->Thread = NULL; } return rpc_client_free(rpc); }
rdpRpc* rpc_new(rdpTransport* transport) { rdpRpc* rpc = (rdpRpc*) calloc(1, sizeof(rdpRpc)); if (!rpc) return NULL; rpc->State = RPC_CLIENT_STATE_INITIAL; rpc->transport = transport; rpc->settings = transport->settings; rpc->context = transport->context; rpc->SendSeqNum = 0; rpc->ntlm = ntlm_new(); if (!rpc->ntlm) goto out_free; rpc->PipeCallId = 0; rpc->StubCallId = 0; rpc->StubFragCount = 0; rpc->rpc_vers = 5; rpc->rpc_vers_minor = 0; /* little-endian data representation */ rpc->packed_drep[0] = 0x10; rpc->packed_drep[1] = 0x00; rpc->packed_drep[2] = 0x00; rpc->packed_drep[3] = 0x00; rpc->max_xmit_frag = 0x0FF8; rpc->max_recv_frag = 0x0FF8; rpc->ReceiveWindow = 0x00010000; rpc->ChannelLifetime = 0x40000000; rpc->KeepAliveInterval = 300000; rpc->CurrentKeepAliveInterval = rpc->KeepAliveInterval; rpc->CurrentKeepAliveTime = 0; rpc->CallId = 2; if (rpc_client_new(rpc) < 0) goto out_free_rpc_client; return rpc; out_free_rpc_client: rpc_client_free(rpc); out_free: free(rpc); return NULL; }
static void* rpc_client_thread(void* arg) { rdpRpc* rpc; DWORD status; DWORD nCount; HANDLE events[3]; HANDLE ReadEvent; rpc = (rdpRpc*) arg; ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, rpc->TlsOut->sockfd); nCount = 0; events[nCount++] = rpc->client->StopEvent; events[nCount++] = Queue_Event(rpc->client->SendQueue); events[nCount++] = ReadEvent; while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0) { break; } if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) { if (rpc_client_on_read_event(rpc) < 0) break; } if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0) { rpc_send_dequeue_pdu(rpc); } } CloseHandle(ReadEvent); rpc_client_free(rpc); return NULL; }
void rpc_free(rdpRpc* rpc) { if (rpc) { rpc_client_free(rpc); if (rpc->ntlm) { ntlm_client_uninit(rpc->ntlm); ntlm_free(rpc->ntlm); rpc->ntlm = NULL; } if (rpc->VirtualConnection) { rpc_virtual_connection_free(rpc->VirtualConnection); rpc->VirtualConnection = NULL; } free(rpc); } }