| 738 | |
| 739 | #[pyfunction] |
| 740 | fn QueryValueEx(key: HKEYArg, name: String, vm: &VirtualMachine) -> PyResult<PyRef<PyTuple>> { |
| 741 | let hkey = key.0; |
| 742 | let wide_name = name.to_wide_with_nul(); |
| 743 | let mut buf_size: u32 = 0; |
| 744 | let res = unsafe { |
| 745 | Registry::RegQueryValueExW( |
| 746 | hkey, |
| 747 | wide_name.as_ptr(), |
| 748 | core::ptr::null_mut(), |
| 749 | core::ptr::null_mut(), |
| 750 | core::ptr::null_mut(), |
| 751 | &mut buf_size, |
| 752 | ) |
| 753 | }; |
| 754 | // Handle ERROR_MORE_DATA by using a default buffer size |
| 755 | if res == ERROR_MORE_DATA || buf_size == 0 { |
| 756 | buf_size = 256; |
| 757 | } else if res != 0 { |
| 758 | return Err(os_error_from_windows_code(vm, res as i32)); |
| 759 | } |
| 760 | |
| 761 | let mut ret_buf = vec![0u8; buf_size as usize]; |
| 762 | let mut typ = 0; |
| 763 | let mut ret_size: u32; |
| 764 | |
| 765 | // Loop to handle ERROR_MORE_DATA |
| 766 | loop { |
| 767 | ret_size = buf_size; |
| 768 | let res = unsafe { |
| 769 | Registry::RegQueryValueExW( |
| 770 | hkey, |
| 771 | wide_name.as_ptr(), |
| 772 | core::ptr::null_mut(), |
| 773 | &mut typ, |
| 774 | ret_buf.as_mut_ptr(), |
| 775 | &mut ret_size, |
| 776 | ) |
| 777 | }; |
| 778 | |
| 779 | if res != ERROR_MORE_DATA { |
| 780 | if res != 0 { |
| 781 | return Err(os_error_from_windows_code(vm, res as i32)); |
| 782 | } |
| 783 | break; |
| 784 | } |
| 785 | |
| 786 | // Double buffer size and retry |
| 787 | buf_size *= 2; |
| 788 | ret_buf.resize(buf_size as usize, 0); |
| 789 | } |
| 790 | |
| 791 | // Only pass the bytes actually returned by the API |
| 792 | let obj = reg_to_py(vm, &ret_buf[..ret_size as usize], typ)?; |
| 793 | // Return tuple (value, type) |
| 794 | Ok(vm.ctx.new_tuple(vec![obj, vm.ctx.new_int(typ).into()])) |
| 795 | } |
| 796 | |
| 797 | #[pyfunction] |