(query: PyStrRef, vm: &VirtualMachine)
| 561 | /// by null characters. |
| 562 | #[pyfunction] |
| 563 | fn exec_query(query: PyStrRef, vm: &VirtualMachine) -> PyResult<String> { |
| 564 | let query_str = query.expect_str(); |
| 565 | |
| 566 | if !query_str |
| 567 | .get(..7) |
| 568 | .is_some_and(|s| s.eq_ignore_ascii_case("select ")) |
| 569 | { |
| 570 | return Err(vm.new_value_error("only SELECT queries are supported")); |
| 571 | } |
| 572 | |
| 573 | let query_wide = wide_str(query_str); |
| 574 | |
| 575 | let mut h_thread: HANDLE = null_mut(); |
| 576 | let mut err: u32 = 0; |
| 577 | let mut buffer = [0u16; BUFFER_SIZE]; |
| 578 | let mut offset: u32 = 0; |
| 579 | let mut bytes_read: u32 = 0; |
| 580 | |
| 581 | let mut read_pipe: HANDLE = null_mut(); |
| 582 | let mut write_pipe: HANDLE = null_mut(); |
| 583 | |
| 584 | unsafe { |
| 585 | let init_event = CreateEventW(null(), 1, 0, null()); |
| 586 | let connect_event = CreateEventW(null(), 1, 0, null()); |
| 587 | |
| 588 | if init_event.is_null() |
| 589 | || connect_event.is_null() |
| 590 | || CreatePipe(&mut read_pipe, &mut write_pipe, null(), 0) == 0 |
| 591 | { |
| 592 | err = GetLastError(); |
| 593 | } else { |
| 594 | let thread_data = Box::new(QueryThreadData { |
| 595 | query: query_wide, |
| 596 | write_pipe, |
| 597 | init_event, |
| 598 | connect_event, |
| 599 | }); |
| 600 | let thread_data_ptr = Box::into_raw(thread_data); |
| 601 | |
| 602 | h_thread = CreateThread( |
| 603 | null(), |
| 604 | 0, |
| 605 | Some(query_thread), |
| 606 | thread_data_ptr as *const _ as *mut _, |
| 607 | 0, |
| 608 | null_mut(), |
| 609 | ); |
| 610 | |
| 611 | if h_thread.is_null() { |
| 612 | err = GetLastError(); |
| 613 | // Thread didn't start, so recover data and close write pipe |
| 614 | let data = Box::from_raw(thread_data_ptr); |
| 615 | CloseHandle(data.write_pipe); |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | // gh-112278: Timeout for COM init and WMI connection |
| 620 | if err == 0 { |
nothing calls this directly
no test coverage detected