[INFO] cloning repository https://github.com/EduContin/hidden-vnc [INFO] running `Command { std: "git" "-c" "credential.helper=" "-c" "credential.helper=/workspace/cargo-home/bin/git-credential-null" "clone" "--bare" "https://github.com/EduContin/hidden-vnc" "/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2FEduContin%2Fhidden-vnc", kill_on_drop: false }` [INFO] [stderr] Cloning into bare repository '/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2FEduContin%2Fhidden-vnc'... [INFO] running `Command { std: "git" "rev-parse" "HEAD", kill_on_drop: false }` [INFO] [stdout] 1ecc050a3d1e33f225e0a0be138b305f0d219074 [INFO] linting EduContin/hidden-vnc against nightly for clippy-nonminimal_bool-denied [INFO] running `Command { std: "git" "clone" "/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2FEduContin%2Fhidden-vnc" "/workspace/builds/worker-6-tc1/source", kill_on_drop: false }` [INFO] [stderr] Cloning into '/workspace/builds/worker-6-tc1/source'... [INFO] [stderr] done. [INFO] started tweaking git repo https://github.com/EduContin/hidden-vnc [INFO] finished tweaking git repo https://github.com/EduContin/hidden-vnc [INFO] tweaked toml for git repo https://github.com/EduContin/hidden-vnc written to /workspace/builds/worker-6-tc1/source/Cargo.toml [INFO] validating manifest of git repo https://github.com/EduContin/hidden-vnc on toolchain nightly [INFO] running `Command { std: CARGO_HOME="/workspace/cargo-home" RUSTUP_HOME="/workspace/rustup-home" "/workspace/cargo-home/bin/cargo" "+nightly" "metadata" "--manifest-path" "Cargo.toml" "--no-deps", kill_on_drop: false }` [INFO] crate git repo https://github.com/EduContin/hidden-vnc already has a lockfile, it will not be regenerated [INFO] running `Command { std: CARGO_HOME="/workspace/cargo-home" RUSTUP_HOME="/workspace/rustup-home" "/workspace/cargo-home/bin/cargo" "+nightly" "fetch" "--manifest-path" "Cargo.toml", kill_on_drop: false }` [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-6-tc1/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-6-tc1/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:d429b63d4308055ea97f60fb1d3dfca48854a00942f1bd2ad806beaf015945ec" "/opt/rustwide/cargo-home/bin/cargo" "+nightly" "metadata" "--no-deps" "--format-version=1", kill_on_drop: false }` [INFO] [stdout] 72ff1784c277150bb299fe720e836c0ccff2c52219939c234377cd98fddab07a [INFO] running `Command { std: "docker" "start" "-a" "72ff1784c277150bb299fe720e836c0ccff2c52219939c234377cd98fddab07a", kill_on_drop: false }` [INFO] running `Command { std: "docker" "inspect" "72ff1784c277150bb299fe720e836c0ccff2c52219939c234377cd98fddab07a", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "72ff1784c277150bb299fe720e836c0ccff2c52219939c234377cd98fddab07a", kill_on_drop: false }` [INFO] [stdout] 72ff1784c277150bb299fe720e836c0ccff2c52219939c234377cd98fddab07a [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-6-tc1/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-6-tc1/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_INCREMENTAL=0" "-e" "RUST_BACKTRACE=full" "-e" "RUSTFLAGS=--cap-lints=forbid" "-e" "RUSTDOCFLAGS=--cap-lints=forbid" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:d429b63d4308055ea97f60fb1d3dfca48854a00942f1bd2ad806beaf015945ec" "/opt/rustwide/cargo-home/bin/cargo" "+nightly" "clippy" "--frozen" "--all" "--all-targets" "--message-format=json", kill_on_drop: false }` [INFO] [stdout] d9bc61b56c9901e6727e86cae97df2b98fc4e2c243fd5e8ec37dd21412e99c3d [INFO] running `Command { std: "docker" "start" "-a" "d9bc61b56c9901e6727e86cae97df2b98fc4e2c243fd5e8ec37dd21412e99c3d", kill_on_drop: false }` [INFO] [stderr] Compiling rayon-core v1.12.1 [INFO] [stderr] Checking adler2 v2.0.0 [INFO] [stderr] Compiling windows_x86_64_gnu v0.52.6 [INFO] [stderr] Checking either v1.15.0 [INFO] [stderr] Checking weezl v0.1.8 [INFO] [stderr] Checking smallvec v1.15.0 [INFO] [stderr] Compiling anyhow v1.0.98 [INFO] [stderr] Checking bytemuck v1.22.0 [INFO] [stderr] Checking crc32fast v1.4.2 [INFO] [stderr] Compiling num-traits v0.2.19 [INFO] [stderr] Checking half v2.6.0 [INFO] [stderr] Checking iana-time-zone v0.1.63 [INFO] [stderr] Checking miniz_oxide v0.8.8 [INFO] [stderr] Checking gif v0.13.1 [INFO] [stderr] Checking windows-targets v0.52.6 [INFO] [stderr] Checking windows-core v0.52.0 [INFO] [stderr] Checking qoi v0.4.1 [INFO] [stderr] Checking rayon v1.10.0 [INFO] [stderr] Checking flate2 v1.1.1 [INFO] [stderr] Checking exr v1.73.0 [INFO] [stderr] Checking windows v0.52.0 [INFO] [stderr] Checking png v0.17.16 [INFO] [stderr] Checking chrono v0.4.40 [INFO] [stderr] Checking jpeg-decoder v0.3.1 [INFO] [stderr] Checking tiff v0.9.1 [INFO] [stderr] Checking image v0.24.9 [INFO] [stderr] Checking hidden-vnc v0.1.0 (/opt/rustwide/workdir) [INFO] [stdout] warning: unused import: `std::thread` [INFO] [stdout] --> src/main.rs:4:5 [INFO] [stdout] | [INFO] [stdout] 4 | use std::thread; [INFO] [stdout] | ^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused import: `std::time::Duration` [INFO] [stdout] --> src/main.rs:5:5 [INFO] [stdout] | [INFO] [stdout] 5 | use std::time::Duration; [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this import is redundant [INFO] [stdout] --> src/main.rs:18:1 [INFO] [stdout] | [INFO] [stdout] 18 | use image; [INFO] [stdout] | ^^^^^^^^^^ help: remove it entirely [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports [INFO] [stdout] = note: `#[warn(clippy::single_component_path_imports)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: function `find_chrome_process_id` is never used [INFO] [stdout] --> src/main.rs:102:4 [INFO] [stdout] | [INFO] [stdout] 102 | fn find_chrome_process_id() -> Option { [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:54:14 [INFO] [stdout] | [INFO] [stdout] 54 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] = note: `#[warn(clippy::unnecessary_mut_passed)]` on by default [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 54 - Some(&mut sa), [INFO] [stdout] 54 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this boolean expression can be simplified [INFO] [stdout] --> src/main.rs:94:8 [INFO] [stdout] | [INFO] [stdout] 94 | if !result.is_ok() { [INFO] [stdout] | ^^^^^^^^^^^^^^^ help: try: `result.is_err()` [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool [INFO] [stdout] = note: `#[warn(clippy::nonminimal_bool)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: field assignment outside of initializer for an instance created with Default::default() [INFO] [stdout] --> src/main.rs:73:5 [INFO] [stdout] | [INFO] [stdout] 73 | si.cb = std::mem::size_of::() as u32; [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] note: consider initializing the variable with `windows::Win32::System::Threading::STARTUPINFOA { cb: std::mem::size_of::() as u32, ..Default::default() }` and removing relevant reassignments [INFO] [stdout] --> src/main.rs:72:5 [INFO] [stdout] | [INFO] [stdout] 72 | let mut si = STARTUPINFOA::default(); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default [INFO] [stdout] = note: `#[warn(clippy::field_reassign_with_default)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:85:14 [INFO] [stdout] | [INFO] [stdout] 85 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 85 - Some(&mut sa), [INFO] [stdout] 85 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:86:14 [INFO] [stdout] | [INFO] [stdout] 86 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 86 - Some(&mut sa), [INFO] [stdout] 86 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused import: `std::thread` [INFO] [stdout] --> src/main.rs:4:5 [INFO] [stdout] | [INFO] [stdout] 4 | use std::thread; [INFO] [stdout] | ^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: casting to the same type is unnecessary (`u32` -> `u32`) [INFO] [stdout] --> src/main.rs:218:32 [INFO] [stdout] | [INFO] [stdout] 218 | biCompression: BI_RGB.0 as u32, [INFO] [stdout] | ^^^^^^^^^^^^^^^ help: try: `BI_RGB.0` [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast [INFO] [stdout] = note: `#[warn(clippy::unnecessary_cast)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused import: `std::time::Duration` [INFO] [stdout] --> src/main.rs:5:5 [INFO] [stdout] | [INFO] [stdout] 5 | use std::time::Duration; [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this import is redundant [INFO] [stdout] --> src/main.rs:18:1 [INFO] [stdout] | [INFO] [stdout] 18 | use image; [INFO] [stdout] | ^^^^^^^^^^ help: remove it entirely [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports [INFO] [stdout] = note: `#[warn(clippy::single_component_path_imports)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unnecessary `if let` since only the `Ok` variant of the iterator element is used [INFO] [stdout] --> src/main.rs:350:13 [INFO] [stdout] | [INFO] [stdout] 350 | / for entry in entries { [INFO] [stdout] 351 | | if let Ok(entry) = entry { [INFO] [stdout] 352 | | let path = entry.path(); [INFO] [stdout] 353 | | if path.is_dir() { [INFO] [stdout] ... | [INFO] [stdout] 477 | | } [INFO] [stdout] | |_____________^ [INFO] [stdout] | [INFO] [stdout] help: try `.flatten()` and remove the `if let` statement in the for loop [INFO] [stdout] --> src/main.rs:351:17 [INFO] [stdout] | [INFO] [stdout] 351 | / if let Ok(entry) = entry { [INFO] [stdout] 352 | | let path = entry.path(); [INFO] [stdout] 353 | | if path.is_dir() { [INFO] [stdout] 354 | | if let Some(profile_name_osstr) = path.file_name() { [INFO] [stdout] ... | [INFO] [stdout] 476 | | } [INFO] [stdout] | |_________________^ [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [INFO] [stdout] = note: `#[warn(clippy::manual_flatten)]` on by default [INFO] [stdout] help: try [INFO] [stdout] | [INFO] [stdout] 350 ~ for entry in entries.flatten() { [INFO] [stdout] 351 + let path = entry.path(); [INFO] [stdout] 352 + if path.is_dir() { [INFO] [stdout] 353 + if let Some(profile_name_osstr) = path.file_name() { [INFO] [stdout] 354 + if let Some(profile_name) = profile_name_osstr.to_str() { [INFO] [stdout] 355 + if profile_name == "Default" || profile_name.starts_with("Profile") { [INFO] [stdout] 356 + println!("\n[+] Attempting to launch Chrome with profile: {}", profile_name); [INFO] [stdout] 357 + [INFO] [stdout] 358 + println!("[+] Launching Chrome in hidden desktop for profile: {}...", profile_name); [INFO] [stdout] 359 + let chrome_proc_info = match unsafe { launch_chrome_on_desktop(desktop_name, chrome_path, chrome_user_data_path, profile_name) } { [INFO] [stdout] 360 + Ok(pi) => pi, [INFO] [stdout] 361 + Err(e) => { [INFO] [stdout] 362 + println!("[-] Failed to launch Chrome for profile {}: {:?}", profile_name, e); [INFO] [stdout] 363 + continue; // Try next profile [INFO] [stdout] 364 + } [INFO] [stdout] 365 + }; [INFO] [stdout] 366 + [INFO] [stdout] 367 + println!("[+] Chrome launched for profile {}. Waiting for it to initialize...", profile_name); [INFO] [stdout] 368 + std::thread::sleep(std::time::Duration::from_secs(10)); [INFO] [stdout] 369 + [INFO] [stdout] 370 + println!("[+] Searching for Chrome processes for profile {}...", profile_name); [INFO] [stdout] 371 + let chrome_pids = find_all_chrome_process_ids(); [INFO] [stdout] 372 + if chrome_pids.is_empty() { [INFO] [stdout] 373 + println!("[-] Could not find any Chrome process for profile {}.", profile_name); [INFO] [stdout] 374 + // Terminate the launched Chrome process if it's still running without a window [INFO] [stdout] 375 + unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] 376 + continue; // Try next profile [INFO] [stdout] 377 + } [INFO] [stdout] 378 + println!("[+] Found Chrome PIDs for profile {}: {:?}", profile_name, chrome_pids); [INFO] [stdout] 379 + [INFO] [stdout] 380 + let (tx, rx) = mpsc::channel(); [INFO] [stdout] 381 + let desktop_handle_clone = hidden_desktop; // Clone or copy if HDESK is Copy [INFO] [stdout] 382 + let chrome_pids_clone = chrome_pids.clone(); [INFO] [stdout] 383 + let screenshots_dir_clone = screenshots_dir.to_path_buf(); [INFO] [stdout] 384 + [INFO] [stdout] 385 + SCREENSHOT_SAVED.store(false, Ordering::Relaxed); // Reset for each profile [INFO] [stdout] 386 + [INFO] [stdout] 387 + std::thread::spawn(move || { [INFO] [stdout] 388 + unsafe { [INFO] [stdout] 389 + if SetThreadDesktop(desktop_handle_clone).is_err() { [INFO] [stdout] 390 + let _ = tx.send(Err(anyhow!("Failed to set thread desktop in capture thread for profile"))); [INFO] [stdout] 391 + return; [INFO] [stdout] 392 + } [INFO] [stdout] 393 + let mut msg = MSG::default(); [INFO] [stdout] 394 + let start = std::time::Instant::now(); [INFO] [stdout] 395 + while start.elapsed().as_secs() < 3 { [INFO] [stdout] 396 + while PeekMessageW(&mut msg, HWND(0), 0, 0, PM_REMOVE).as_bool() { [INFO] [stdout] 397 + TranslateMessage(&msg); [INFO] [stdout] 398 + DispatchMessageW(&msg); [INFO] [stdout] 399 + } [INFO] [stdout] 400 + std::thread::sleep(std::time::Duration::from_millis(10)); [INFO] [stdout] 401 + } [INFO] [stdout] 402 + } [INFO] [stdout] 403 + let mut any_valid_screenshot_for_profile = false; [INFO] [stdout] 404 + for pid in chrome_pids_clone { [INFO] [stdout] 405 + println!("[+] [HVNC thread] Attempting to capture Chrome window for PID {} (Profile)...", pid); [INFO] [stdout] 406 + CHROME_PROCESS_ID.store(pid, Ordering::Relaxed); [INFO] [stdout] 407 + unsafe { [INFO] [stdout] 408 + let enum_result = EnumWindows(Some(enum_windows_proc), LPARAM(0)); [INFO] [stdout] 409 + if enum_result.is_err() { [INFO] [stdout] 410 + println!("[-] [HVNC thread] EnumWindows failed for PID {} (Profile)", pid); [INFO] [stdout] 411 + continue; [INFO] [stdout] 412 + } [INFO] [stdout] 413 + } [INFO] [stdout] 414 + if SCREENSHOT_SAVED.load(Ordering::Relaxed) { [INFO] [stdout] 415 + let mut latest: Option = None; [INFO] [stdout] 416 + if let Ok(entries) = std::fs::read_dir(&screenshots_dir_clone) { [INFO] [stdout] 417 + for entry in entries.flatten() { [INFO] [stdout] 418 + let path = entry.path(); [INFO] [stdout] 419 + if path.extension().map(|e| e == "png").unwrap_or(false) { [INFO] [stdout] 420 + if let Ok(metadata) = path.metadata() { [INFO] [stdout] 421 + if let Ok(time) = metadata.modified() { [INFO] [stdout] 422 + if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] 423 + l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 424 + }) { [INFO] [stdout] 425 + latest = Some(path); [INFO] [stdout] 426 + } [INFO] [stdout] 427 + } [INFO] [stdout] 428 + } [INFO] [stdout] 429 + } [INFO] [stdout] 430 + } [INFO] [stdout] 431 + } [INFO] [stdout] 432 + if let Some(ref img_path) = latest { [INFO] [stdout] 433 + if is_image_blank(img_path) { [INFO] [stdout] 434 + println!("[-] [HVNC thread] Screenshot at {:?} for profile is blank.", img_path); [INFO] [stdout] 435 + } else { [INFO] [stdout] 436 + println!("[+] [HVNC thread] Screenshot at {:?} is a valid Chrome window for profile!", img_path); [INFO] [stdout] 437 + any_valid_screenshot_for_profile = true; [INFO] [stdout] 438 + // If one valid screenshot is found for this profile, we can break from PID loop for this profile. [INFO] [stdout] 439 + // break; [INFO] [stdout] 440 + } [INFO] [stdout] 441 + } [INFO] [stdout] 442 + SCREENSHOT_SAVED.store(false, Ordering::Relaxed); // Reset for next PID or next screenshot attempt [INFO] [stdout] 443 + } [INFO] [stdout] 444 + } [INFO] [stdout] 445 + if any_valid_screenshot_for_profile { [INFO] [stdout] 446 + let _ = tx.send(Ok(())); [INFO] [stdout] 447 + } else { [INFO] [stdout] 448 + let _ = tx.send(Err(anyhow!("No valid screenshot for this profile."))); [INFO] [stdout] 449 + } [INFO] [stdout] 450 + }); [INFO] [stdout] 451 + [INFO] [stdout] 452 + match rx.recv() { [INFO] [stdout] 453 + Ok(Ok(())) => { [INFO] [stdout] 454 + println!("[+] Successfully captured screenshot for profile: {}", profile_name); [INFO] [stdout] 455 + overall_success = true; [INFO] [stdout] 456 + // Optional: break here if you only need one profile to work [INFO] [stdout] 457 + // break; [INFO] [stdout] 458 + }, [INFO] [stdout] 459 + Ok(Err(e)) => { [INFO] [stdout] 460 + println!("[-] Failed to capture for profile {}: {}", profile_name, e); [INFO] [stdout] 461 + }, [INFO] [stdout] 462 + Err(e) => { [INFO] [stdout] 463 + println!("[-] Failed to receive from capture thread for profile {}: {}", profile_name, e); [INFO] [stdout] 464 + } [INFO] [stdout] 465 + } [INFO] [stdout] 466 + // Clean up the launched Chrome process for the current profile [INFO] [stdout] 467 + println!("[+] Closing Chrome process for profile: {}", profile_name); [INFO] [stdout] 468 + unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] 469 + println!("[+] Chrome process for profile {} closed.", profile_name); [INFO] [stdout] 470 + [INFO] [stdout] 471 + } [INFO] [stdout] 472 + } [INFO] [stdout] 473 + } [INFO] [stdout] 474 + } [INFO] [stdout] 475 + } [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this `map_or` can be simplified [INFO] [stdout] --> src/main.rs:423:72 [INFO] [stdout] | [INFO] [stdout] 423 | ... if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] | __________________________^ [INFO] [stdout] 424 | | ... l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 425 | | ... }) { [INFO] [stdout] | |________________________^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or [INFO] [stdout] = note: `#[warn(clippy::unnecessary_map_or)]` on by default [INFO] [stdout] help: use `is_none_or` instead [INFO] [stdout] | [INFO] [stdout] 423 - if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] 423 + if latest.as_ref().is_none_or(|l_path| { [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this `map_or` can be simplified [INFO] [stdout] --> src/main.rs:424:73 [INFO] [stdout] | [INFO] [stdout] 424 | ... l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or [INFO] [stdout] help: use `is_some_and` instead [INFO] [stdout] | [INFO] [stdout] 424 - l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 424 + l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).is_some_and(|l_time| time > l_time) [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:125:17 [INFO] [stdout] | [INFO] [stdout] 125 | CloseHandle(snapshot); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] = note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 125 | let _ = CloseHandle(snapshot); [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:130:9 [INFO] [stdout] | [INFO] [stdout] 130 | CloseHandle(snapshot); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 130 | let _ = CloseHandle(snapshot); [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:50 [INFO] [stdout] | [INFO] [stdout] 376 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { let _ = TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:98 [INFO] [stdout] | [INFO] [stdout] 376 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); let _ = CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:138 [INFO] [stdout] | [INFO] [stdout] 376 | ... 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); let _ = CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:46 [INFO] [stdout] | [INFO] [stdout] 469 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { let _ = TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:94 [INFO] [stdout] | [INFO] [stdout] 469 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); let _ = CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:134 [INFO] [stdout] | [INFO] [stdout] 469 | ... 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); let _ = CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: function `find_chrome_process_id` is never used [INFO] [stdout] --> src/main.rs:102:4 [INFO] [stdout] | [INFO] [stdout] 102 | fn find_chrome_process_id() -> Option { [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:54:14 [INFO] [stdout] | [INFO] [stdout] 54 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] = note: `#[warn(clippy::unnecessary_mut_passed)]` on by default [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 54 - Some(&mut sa), [INFO] [stdout] 54 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this boolean expression can be simplified [INFO] [stdout] --> src/main.rs:94:8 [INFO] [stdout] | [INFO] [stdout] 94 | if !result.is_ok() { [INFO] [stdout] | ^^^^^^^^^^^^^^^ help: try: `result.is_err()` [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool [INFO] [stdout] = note: `#[warn(clippy::nonminimal_bool)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: field assignment outside of initializer for an instance created with Default::default() [INFO] [stdout] --> src/main.rs:73:5 [INFO] [stdout] | [INFO] [stdout] 73 | si.cb = std::mem::size_of::() as u32; [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] note: consider initializing the variable with `windows::Win32::System::Threading::STARTUPINFOA { cb: std::mem::size_of::() as u32, ..Default::default() }` and removing relevant reassignments [INFO] [stdout] --> src/main.rs:72:5 [INFO] [stdout] | [INFO] [stdout] 72 | let mut si = STARTUPINFOA::default(); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default [INFO] [stdout] = note: `#[warn(clippy::field_reassign_with_default)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:85:14 [INFO] [stdout] | [INFO] [stdout] 85 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 85 - Some(&mut sa), [INFO] [stdout] 85 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: the function `Some` doesn't need a mutable reference [INFO] [stdout] --> src/main.rs:86:14 [INFO] [stdout] | [INFO] [stdout] 86 | Some(&mut sa), [INFO] [stdout] | ^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [INFO] [stdout] help: remove this `mut` [INFO] [stdout] | [INFO] [stdout] 86 - Some(&mut sa), [INFO] [stdout] 86 + Some(&sa), [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: casting to the same type is unnecessary (`u32` -> `u32`) [INFO] [stdout] --> src/main.rs:218:32 [INFO] [stdout] | [INFO] [stdout] 218 | biCompression: BI_RGB.0 as u32, [INFO] [stdout] | ^^^^^^^^^^^^^^^ help: try: `BI_RGB.0` [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast [INFO] [stdout] = note: `#[warn(clippy::unnecessary_cast)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unnecessary `if let` since only the `Ok` variant of the iterator element is used [INFO] [stdout] --> src/main.rs:350:13 [INFO] [stdout] | [INFO] [stdout] 350 | / for entry in entries { [INFO] [stdout] 351 | | if let Ok(entry) = entry { [INFO] [stdout] 352 | | let path = entry.path(); [INFO] [stdout] 353 | | if path.is_dir() { [INFO] [stdout] ... | [INFO] [stdout] 477 | | } [INFO] [stdout] | |_____________^ [INFO] [stdout] | [INFO] [stdout] help: try `.flatten()` and remove the `if let` statement in the for loop [INFO] [stdout] --> src/main.rs:351:17 [INFO] [stdout] | [INFO] [stdout] 351 | / if let Ok(entry) = entry { [INFO] [stdout] 352 | | let path = entry.path(); [INFO] [stdout] 353 | | if path.is_dir() { [INFO] [stdout] 354 | | if let Some(profile_name_osstr) = path.file_name() { [INFO] [stdout] ... | [INFO] [stdout] 476 | | } [INFO] [stdout] | |_________________^ [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [INFO] [stdout] = note: `#[warn(clippy::manual_flatten)]` on by default [INFO] [stdout] help: try [INFO] [stdout] | [INFO] [stdout] 350 ~ for entry in entries.flatten() { [INFO] [stdout] 351 + let path = entry.path(); [INFO] [stdout] 352 + if path.is_dir() { [INFO] [stdout] 353 + if let Some(profile_name_osstr) = path.file_name() { [INFO] [stdout] 354 + if let Some(profile_name) = profile_name_osstr.to_str() { [INFO] [stdout] 355 + if profile_name == "Default" || profile_name.starts_with("Profile") { [INFO] [stdout] 356 + println!("\n[+] Attempting to launch Chrome with profile: {}", profile_name); [INFO] [stdout] 357 + [INFO] [stdout] 358 + println!("[+] Launching Chrome in hidden desktop for profile: {}...", profile_name); [INFO] [stdout] 359 + let chrome_proc_info = match unsafe { launch_chrome_on_desktop(desktop_name, chrome_path, chrome_user_data_path, profile_name) } { [INFO] [stdout] 360 + Ok(pi) => pi, [INFO] [stdout] 361 + Err(e) => { [INFO] [stdout] 362 + println!("[-] Failed to launch Chrome for profile {}: {:?}", profile_name, e); [INFO] [stdout] 363 + continue; // Try next profile [INFO] [stdout] 364 + } [INFO] [stdout] 365 + }; [INFO] [stdout] 366 + [INFO] [stdout] 367 + println!("[+] Chrome launched for profile {}. Waiting for it to initialize...", profile_name); [INFO] [stdout] 368 + std::thread::sleep(std::time::Duration::from_secs(10)); [INFO] [stdout] 369 + [INFO] [stdout] 370 + println!("[+] Searching for Chrome processes for profile {}...", profile_name); [INFO] [stdout] 371 + let chrome_pids = find_all_chrome_process_ids(); [INFO] [stdout] 372 + if chrome_pids.is_empty() { [INFO] [stdout] 373 + println!("[-] Could not find any Chrome process for profile {}.", profile_name); [INFO] [stdout] 374 + // Terminate the launched Chrome process if it's still running without a window [INFO] [stdout] 375 + unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] 376 + continue; // Try next profile [INFO] [stdout] 377 + } [INFO] [stdout] 378 + println!("[+] Found Chrome PIDs for profile {}: {:?}", profile_name, chrome_pids); [INFO] [stdout] 379 + [INFO] [stdout] 380 + let (tx, rx) = mpsc::channel(); [INFO] [stdout] 381 + let desktop_handle_clone = hidden_desktop; // Clone or copy if HDESK is Copy [INFO] [stdout] 382 + let chrome_pids_clone = chrome_pids.clone(); [INFO] [stdout] 383 + let screenshots_dir_clone = screenshots_dir.to_path_buf(); [INFO] [stdout] 384 + [INFO] [stdout] 385 + SCREENSHOT_SAVED.store(false, Ordering::Relaxed); // Reset for each profile [INFO] [stdout] 386 + [INFO] [stdout] 387 + std::thread::spawn(move || { [INFO] [stdout] 388 + unsafe { [INFO] [stdout] 389 + if SetThreadDesktop(desktop_handle_clone).is_err() { [INFO] [stdout] 390 + let _ = tx.send(Err(anyhow!("Failed to set thread desktop in capture thread for profile"))); [INFO] [stdout] 391 + return; [INFO] [stdout] 392 + } [INFO] [stdout] 393 + let mut msg = MSG::default(); [INFO] [stdout] 394 + let start = std::time::Instant::now(); [INFO] [stdout] 395 + while start.elapsed().as_secs() < 3 { [INFO] [stdout] 396 + while PeekMessageW(&mut msg, HWND(0), 0, 0, PM_REMOVE).as_bool() { [INFO] [stdout] 397 + TranslateMessage(&msg); [INFO] [stdout] 398 + DispatchMessageW(&msg); [INFO] [stdout] 399 + } [INFO] [stdout] 400 + std::thread::sleep(std::time::Duration::from_millis(10)); [INFO] [stdout] 401 + } [INFO] [stdout] 402 + } [INFO] [stdout] 403 + let mut any_valid_screenshot_for_profile = false; [INFO] [stdout] 404 + for pid in chrome_pids_clone { [INFO] [stdout] 405 + println!("[+] [HVNC thread] Attempting to capture Chrome window for PID {} (Profile)...", pid); [INFO] [stdout] 406 + CHROME_PROCESS_ID.store(pid, Ordering::Relaxed); [INFO] [stdout] 407 + unsafe { [INFO] [stdout] 408 + let enum_result = EnumWindows(Some(enum_windows_proc), LPARAM(0)); [INFO] [stdout] 409 + if enum_result.is_err() { [INFO] [stdout] 410 + println!("[-] [HVNC thread] EnumWindows failed for PID {} (Profile)", pid); [INFO] [stdout] 411 + continue; [INFO] [stdout] 412 + } [INFO] [stdout] 413 + } [INFO] [stdout] 414 + if SCREENSHOT_SAVED.load(Ordering::Relaxed) { [INFO] [stdout] 415 + let mut latest: Option = None; [INFO] [stdout] 416 + if let Ok(entries) = std::fs::read_dir(&screenshots_dir_clone) { [INFO] [stdout] 417 + for entry in entries.flatten() { [INFO] [stdout] 418 + let path = entry.path(); [INFO] [stdout] 419 + if path.extension().map(|e| e == "png").unwrap_or(false) { [INFO] [stdout] 420 + if let Ok(metadata) = path.metadata() { [INFO] [stdout] 421 + if let Ok(time) = metadata.modified() { [INFO] [stdout] 422 + if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] 423 + l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 424 + }) { [INFO] [stdout] 425 + latest = Some(path); [INFO] [stdout] 426 + } [INFO] [stdout] 427 + } [INFO] [stdout] 428 + } [INFO] [stdout] 429 + } [INFO] [stdout] 430 + } [INFO] [stdout] 431 + } [INFO] [stdout] 432 + if let Some(ref img_path) = latest { [INFO] [stdout] 433 + if is_image_blank(img_path) { [INFO] [stdout] 434 + println!("[-] [HVNC thread] Screenshot at {:?} for profile is blank.", img_path); [INFO] [stdout] 435 + } else { [INFO] [stdout] 436 + println!("[+] [HVNC thread] Screenshot at {:?} is a valid Chrome window for profile!", img_path); [INFO] [stdout] 437 + any_valid_screenshot_for_profile = true; [INFO] [stdout] 438 + // If one valid screenshot is found for this profile, we can break from PID loop for this profile. [INFO] [stdout] 439 + // break; [INFO] [stdout] 440 + } [INFO] [stdout] 441 + } [INFO] [stdout] 442 + SCREENSHOT_SAVED.store(false, Ordering::Relaxed); // Reset for next PID or next screenshot attempt [INFO] [stdout] 443 + } [INFO] [stdout] 444 + } [INFO] [stdout] 445 + if any_valid_screenshot_for_profile { [INFO] [stdout] 446 + let _ = tx.send(Ok(())); [INFO] [stdout] 447 + } else { [INFO] [stdout] 448 + let _ = tx.send(Err(anyhow!("No valid screenshot for this profile."))); [INFO] [stdout] 449 + } [INFO] [stdout] 450 + }); [INFO] [stdout] 451 + [INFO] [stdout] 452 + match rx.recv() { [INFO] [stdout] 453 + Ok(Ok(())) => { [INFO] [stdout] 454 + println!("[+] Successfully captured screenshot for profile: {}", profile_name); [INFO] [stdout] 455 + overall_success = true; [INFO] [stdout] 456 + // Optional: break here if you only need one profile to work [INFO] [stdout] 457 + // break; [INFO] [stdout] 458 + }, [INFO] [stdout] 459 + Ok(Err(e)) => { [INFO] [stdout] 460 + println!("[-] Failed to capture for profile {}: {}", profile_name, e); [INFO] [stdout] 461 + }, [INFO] [stdout] 462 + Err(e) => { [INFO] [stdout] 463 + println!("[-] Failed to receive from capture thread for profile {}: {}", profile_name, e); [INFO] [stdout] 464 + } [INFO] [stdout] 465 + } [INFO] [stdout] 466 + // Clean up the launched Chrome process for the current profile [INFO] [stdout] 467 + println!("[+] Closing Chrome process for profile: {}", profile_name); [INFO] [stdout] 468 + unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] 469 + println!("[+] Chrome process for profile {} closed.", profile_name); [INFO] [stdout] 470 + [INFO] [stdout] 471 + } [INFO] [stdout] 472 + } [INFO] [stdout] 473 + } [INFO] [stdout] 474 + } [INFO] [stdout] 475 + } [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this `map_or` can be simplified [INFO] [stdout] --> src/main.rs:423:72 [INFO] [stdout] | [INFO] [stdout] 423 | ... if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] | __________________________^ [INFO] [stdout] 424 | | ... l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 425 | | ... }) { [INFO] [stdout] | |________________________^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or [INFO] [stdout] = note: `#[warn(clippy::unnecessary_map_or)]` on by default [INFO] [stdout] help: use `is_none_or` instead [INFO] [stdout] | [INFO] [stdout] 423 - if latest.as_ref().map_or(true, |l_path| { [INFO] [stdout] 423 + if latest.as_ref().is_none_or(|l_path| { [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: this `map_or` can be simplified [INFO] [stdout] --> src/main.rs:424:73 [INFO] [stdout] | [INFO] [stdout] 424 | ... l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or [INFO] [stdout] help: use `is_some_and` instead [INFO] [stdout] | [INFO] [stdout] 424 - l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).map_or(false, |l_time| time > l_time) [INFO] [stdout] 424 + l_path.metadata().ok().and_then(|l_meta| l_meta.modified().ok()).is_some_and(|l_time| time > l_time) [INFO] [stdout] | [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:125:17 [INFO] [stdout] | [INFO] [stdout] 125 | CloseHandle(snapshot); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] = note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 125 | let _ = CloseHandle(snapshot); [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:130:9 [INFO] [stdout] | [INFO] [stdout] 130 | CloseHandle(snapshot); [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 130 | let _ = CloseHandle(snapshot); [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:50 [INFO] [stdout] | [INFO] [stdout] 376 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { let _ = TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:98 [INFO] [stdout] | [INFO] [stdout] 376 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); let _ = CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:376:138 [INFO] [stdout] | [INFO] [stdout] 376 | ... 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 376 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); let _ = CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:46 [INFO] [stdout] | [INFO] [stdout] 469 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { let _ = TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:94 [INFO] [stdout] | [INFO] [stdout] 469 | ... unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info... [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); let _ = CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused `std::result::Result` that must be used [INFO] [stdout] --> src/main.rs:469:134 [INFO] [stdout] | [INFO] [stdout] 469 | ... 1); CloseHandle(chrome_proc_info.hProcess); CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: this `Result` may be an `Err` variant, which should be handled [INFO] [stdout] help: use `let _ = ...` to ignore the resulting value [INFO] [stdout] | [INFO] [stdout] 469 | unsafe { TerminateProcess(chrome_proc_info.hProcess, 1); CloseHandle(chrome_proc_info.hProcess); let _ = CloseHandle(chrome_proc_info.hThread); } [INFO] [stdout] | +++++++ [INFO] [stdout] [INFO] [stdout] [INFO] [stderr] Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.90s [INFO] running `Command { std: "docker" "inspect" "d9bc61b56c9901e6727e86cae97df2b98fc4e2c243fd5e8ec37dd21412e99c3d", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "d9bc61b56c9901e6727e86cae97df2b98fc4e2c243fd5e8ec37dd21412e99c3d", kill_on_drop: false }` [INFO] [stdout] d9bc61b56c9901e6727e86cae97df2b98fc4e2c243fd5e8ec37dd21412e99c3d