Compare commits

..

1 Commits
1.1.4 ... 1.1.2

Author SHA1 Message Date
rustdesk
ad0a24ba23 source code 2021-03-27 09:41:55 +08:00
13 changed files with 145 additions and 81 deletions

View File

@@ -1,10 +1,10 @@
# RustDesk | Your Remote Desktop Software
### RustDesk | Your Remote Desktop Software
The best open-source remote desktop software, written in Rust. Works out of the box, no configuration required. Great alternative to TeamViewer and AnyDesk! You have full control of your data, with no concerns about security. You can use our rendezvous/relay server, [set up your own](https://rustdesk.com/blog/id-relay-set/), or write your own rendezvous/relay server.
The best open source remote desktop software written with Rust.
[**BINARY DOWNLOAD**](https://github.com/rustdesk/rustdesk/releases)
## Dependences
## Dependence
Desktop versions use [sciter](https://sciter.com/) for GUI, please download sciter dynamic library yourself.
@@ -16,12 +16,12 @@ Desktop versions use [sciter](https://sciter.com/) for GUI, please download scit
* Prepare your Rust development env and C++ build env
* Install [vcpkg](https://github.com/microsoft/vcpkg), and set `VCPKG_ROOT` env variable correctly
* Install [vcpkg](https://github.com/microsoft/vcpkg), and set VCPKG_ROOT env variable correctly
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static
- Linux/Osx: vcpkg install libvpx libyuv opus
* run `cargo run`
* cargo run
## File Structure
@@ -33,14 +33,3 @@ Desktop versions use [sciter](https://sciter.com/) for GUI, please download scit
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: start a peer connection
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
## Snapshot
![image](https://user-images.githubusercontent.com/71636191/113112362-ae4deb80-923b-11eb-957d-ff88daad4f06.png)
![image](https://user-images.githubusercontent.com/71636191/113112619-f705a480-923b-11eb-911d-97e984ef52b6.png)
![image](https://user-images.githubusercontent.com/71636191/113112857-3fbd5d80-923c-11eb-9836-768325faf906.png)
![image](https://user-images.githubusercontent.com/71636191/113112990-65e2fd80-923c-11eb-840e-349b4d6e340d.png)

View File

@@ -1,7 +1,7 @@
#[cfg(windows)]
fn build_windows() {
cc::Build::new().file("src/windows.cc").compile("windows");
println!("cargo:rustc-link-lib=WtsApi32");
cc::Build::new().file("windows.cc").compile("windows");
// println!("cargo:rustc-link-lib=WtsApi32");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=windows.cc");
}

View File

@@ -1,7 +1,7 @@
[package]
name = "hbb_common"
version = "0.1.0"
authors = ["rustdesk<info@rustdesk.com>"]
authors = ["open-trade <info@opentradesolutions.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

118
oboe.cc Normal file
View File

@@ -0,0 +1,118 @@
#include <oboe/Oboe.h>
#include <math.h>
#include <deque>
#include <pthread.h>
// I got link problem with std::mutex, so use pthread instead
class CThreadLock
{
public:
CThreadLock();
virtual ~CThreadLock();
void Lock();
void Unlock();
private:
pthread_mutex_t mutexlock;
};
CThreadLock::CThreadLock()
{
// init lock here
pthread_mutex_init(&mutexlock, 0);
}
CThreadLock::~CThreadLock()
{
// deinit lock here
pthread_mutex_destroy(&mutexlock);
}
void CThreadLock::Lock()
{
// lock
pthread_mutex_lock(&mutexlock);
}
void CThreadLock::Unlock()
{
// unlock
pthread_mutex_unlock(&mutexlock);
}
class Player : public oboe::AudioStreamDataCallback
{
public:
Player(int channels, int sample_rate)
{
this->channels = channels;
oboe::AudioStreamBuilder builder;
// The builder set methods can be chained for convenience.
builder.setSharingMode(oboe::SharingMode::Exclusive)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(channels)
->setSampleRate(sample_rate)
->setFormat(oboe::AudioFormat::Float)
->setDataCallback(this)
->openManagedStream(outStream);
// Typically, start the stream after querying some stream information, as well as some input from the user
outStream->requestStart();
}
~Player() {
outStream->requestStop();
}
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override
{
float *floatData = (float *)audioData;
int i = 0;
mtx.Lock();
auto n = channels * numFrames;
for (; i < n && i < (int)buffer.size(); ++i, ++floatData)
{
*floatData = buffer.front();
buffer.pop_front();
}
mtx.Unlock();
for (; i < n; ++i, ++floatData)
{
*floatData = 0;
}
return oboe::DataCallbackResult::Continue;
}
void push(const float *v, int n)
{
mtx.Lock();
for (auto i = 0; i < n; ++i, ++v)
buffer.push_back(*v);
// in case memory overuse
if (buffer.size() > 48 * 1024 * 120)
buffer.clear();
mtx.Unlock();
}
private:
oboe::ManagedStream outStream;
int channels;
std::deque<float> buffer;
CThreadLock mtx;
};
extern "C"
{
void *create_oboe_player(int channels, int sample_rate)
{
return new Player(channels, sample_rate);
}
void push_oboe_data(void *player, const float* v, int n)
{
static_cast<Player *>(player)->push(v, n);
}
void destroy_oboe_player(void *player)
{
delete static_cast<Player *>(player);
}
}

View File

@@ -638,43 +638,21 @@ pub fn get_active_username() -> String {
if name != "SYSTEM" {
return name;
}
extern "C" {
fn get_active_user(path: *mut u16, n: u32) -> u32;
}
let buff_size = 256;
let mut buff: Vec<u16> = Vec::with_capacity(buff_size);
buff.resize(buff_size, 0);
let n = unsafe { get_active_user(buff.as_mut_ptr(), buff_size as _) };
if n == 0 {
return "".to_owned();
}
let sl = unsafe { std::slice::from_raw_parts(buff.as_ptr(), n as _) };
String::from_utf16(sl).unwrap_or("??".to_owned()).trim_end_matches('\0').to_owned()
}
/*
pub fn get_active_username() -> String {
use std::os::windows::process::CommandExt;
let name = crate::username();
if name != "SYSTEM" {
return name;
}
const CREATE_NO_WINDOW: u32 = 0x08000000;
let mut cmd = std::process::Command::new("query");
cmd.arg("user");
cmd.creation_flags(CREATE_NO_WINDOW);
if let Ok(output) = cmd.output() {
if let Ok(output) = std::process::Command::new("query").arg("user").output() {
for line in String::from_utf8_lossy(&output.stdout).lines() {
if let Some(name) = line.split_whitespace().next() {
if name.starts_with(">") {
return name.replace(">", "");
if line.contains("Active") {
if let Some(name) = line.split_whitespace().next() {
if name.starts_with(">") {
return name.replace(">", "");
} else {
return name.to_string();
}
}
}
}
}
return "".to_owned();
}
*/
pub fn is_prelogin() -> bool {
let username = get_active_username();

View File

@@ -211,11 +211,7 @@ impl RendezvousMediator {
Config::update_latency(&host, -1);
old_latency = 0;
if now.duration_since(last_dns_check).map(|d| d.as_millis() as i64).unwrap_or(0) > DNS_INTERVAL {
if let Ok(_) = rz.dns_check() {
// in some case of network reconnect (dial IP network),
// old UDP socket not work any more after network recover
socket = FramedSocket::new(Config::get_any_listen_addr()).await?;
}
allow_err!(rz.dns_check());
last_dns_check = now;
}
} else if fails > MAX_FAILS1 {

View File

@@ -41,9 +41,9 @@ class Body: Reactor.Component
<div />
{c.is_file_transfer || c.port_forward ? "" : <div>Permissions</div>}
{c.is_file_transfer || c.port_forward ? "" : <div .permissions>
<div class={!c.keyboard ? "disabled" : ""} title="Allow using keyboard and mouse"><icon .keyboard /></div>
<div class={!c.clipboard ? "disabled" : ""} title="Allow using clipboard"><icon .clipboard /></div>
<div class={!c.audio ? "disabled" : ""} title="Allow hearing sound"><icon .audio /></div>
<div class={!c.keyboard ? "disabled" : ""} title="Allow to use keyboard and mouse"><icon .keyboard /></div>
<div class={!c.clipboard ? "disabled" : ""} title="Allow to use clipboard"><icon .clipboard /></div>
<div class={!c.audio ? "disabled" : ""} title="Allow to hear sound"><icon .audio /></div>
</div>}
{c.port_forward ? <div>Port Forwarding: {c.port_forward}</div> : ""}
<div style="size:*"/>

View File

@@ -567,7 +567,7 @@ var create_dir_jobs = {}
function confirmDelete(path, is_remote) {
handler.msgbox("custom-skip", "Confirm Delete", "<div .form> \
<div>Are you sure you want to delete this file?</div> \
<div>Are you sure you want to deelte this file?</div> \
<div.ellipsis style=\"font-weight: bold;\">" + path + "</div> \
</div>", function(res=null) {
if (res) {
@@ -588,7 +588,7 @@ handler.confirmDeleteFiles = function(id, i, name) {
if (name) file_path += handler.get_path_sep(job.is_remote) + name;
handler.msgbox("custom-skip", "Confirm Delete", "<div .form> \
<div>Deleting #" + (i + 1) + " of " + n + " files.</div> \
<div>Are you sure you want to delete this file?</div> \
<div>Are you sure you want to deelte this file?</div> \
<div.ellipsis style=\"font-weight: bold;\" .text>" + name + "</div> \
<div><button|checkbox(remember) {ts}>Do this for all conflicts</button></div> \
</div>", function(res=null) {

View File

@@ -110,7 +110,7 @@ class Header: Reactor.Component {
return <popup>
<menu.context #action-options>
<li #transfer-file>Transfer File</li>
<li #tunnel>TCP Tunneling</li>
<li #tunnel>IP Tunneling</li>
{keyboard_enabled && (pi.platform == "Linux" || pi.sas_enabled) ? <li #ctrl-alt-del>Insert Ctrl + Alt + Del</li> : ""}
{keyboard_enabled ? <li #lock-screen>Insert Lock</li> : ""}
{false && pi.platform == "Windows" ? <li #block-input>Block user input </li> : ""}

View File

@@ -249,7 +249,7 @@ class MyIdMenu: Reactor.Component {
}
if (value == old_value) return;
configOptions["whitelist"] = value.replace("\n", ",");
stdout.println("whitelist updated");
stdin.println("whitelist updated");
handler.set_options(configOptions);
}, 300);
} else if (me.id == "custom-server") {

View File

@@ -21,7 +21,7 @@ class PortForward: Reactor.Component {
});
return <div #file-transfer><section>
{pfs.length ? <div style="background: green; color: white; text-align: center; padding: 0.5em;">
<span style="font-size: 1.2em">Listening ...</span><br/>
<span style="font-size: 1.2em">Listenning ...</span><br/>
<span style="font-size: 0.8em; color: #ddd">Don't close this window while your are using tunnel</span>
</div> : ""}
<table #port-forward>

View File

@@ -1582,7 +1582,7 @@ impl Interface for Handler {
pi_sciter.set_item("sas_enabled", pi.sas_enabled);
if self.is_file_transfer() {
if pi.username.is_empty() {
self.on_error("No active user logged on, please connect and logon first.");
self.on_error("No active console user logged on, please connect and logon first.");
return;
}
} else if !self.is_port_forward() {

View File

@@ -363,21 +363,4 @@ extern "C"
{
SHAddToRecentDocs(SHARD_PATHW, path);
}
uint32_t get_active_user(PWSTR bufin, uint32_t nin)
{
uint32_t nout = 0;
auto id = WTSGetActiveConsoleSessionId();
PWSTR buf = NULL;
DWORD n = 0;
if (WTSQuerySessionInformationW(NULL, id, WTSUserName, &buf, &n))
{
if (buf) {
nout = min(nin, n);
memcpy(bufin, buf, nout);
WTSFreeMemory(buf);
}
}
return nout;
}
} // end of extern "C"
} // end of extern "C"