Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of file paths in the windows DnD handler #980

Merged
merged 4 commits into from
Jun 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- On Windows, support paths longer than MAX_PATH (260 characters) in `WindowEvent::DroppedFile`
and `WindowEvent::HoveredFile`.
- On Mac, implement `DeviceEvent::Button`.
- Change `Event::Suspended(true / false)` to `Event::Suspended` and `Event::Resumed`.
- On X11, fix sanity check which checks that a monitor's reported width and height (in millimeters) are non-zero when calculating the DPI factor.
Expand Down
26 changes: 14 additions & 12 deletions src/platform_impl/windows/drop_handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{
ffi::OsString,
mem,
os::windows::ffi::OsStringExt,
path::PathBuf,
ptr,
Expand All @@ -11,7 +10,7 @@ use winapi::{
ctypes::c_void,
shared::{
guiddef::REFIID,
minwindef::{DWORD, MAX_PATH, UINT, ULONG},
minwindef::{DWORD, UINT, ULONG},
windef::{HWND, POINTL},
winerror::S_OK,
},
Expand Down Expand Up @@ -171,7 +170,6 @@ impl FileDropHandler {
F: Fn(PathBuf),
{
use winapi::{
ctypes::wchar_t,
shared::{
winerror::{DV_E_FORMATETC, SUCCEEDED},
wtypes::{CLIPFORMAT, DVASPECT_CONTENT},
Expand All @@ -191,7 +189,7 @@ impl FileDropHandler {
tymed: TYMED_HGLOBAL,
};

let mut medium = mem::uninitialized();
let mut medium = std::mem::zeroed();
let get_data_result = (*data_obj).GetData(&mut drop_format, &mut medium);
if SUCCEEDED(get_data_result) {
let hglobal = (*medium.u).hGlobal();
Expand All @@ -200,15 +198,19 @@ impl FileDropHandler {
// The second parameter (0xFFFFFFFF) instructs the function to return the item count
let item_count = DragQueryFileW(hdrop, 0xFFFFFFFF, ptr::null_mut(), 0);

let mut pathbuf: [wchar_t; MAX_PATH] = mem::uninitialized();

for i in 0..item_count {
let character_count =
DragQueryFileW(hdrop, i, pathbuf.as_mut_ptr(), MAX_PATH as UINT) as usize;

if character_count > 0 {
callback(OsString::from_wide(&pathbuf[0..character_count]).into());
}
// Get the length of the path string NOT including the terminating null character.
// Previously, this was using a fixed size array of MAX_PATH length, but the
// Windows API allows longer paths under certain circumstances.
let character_count = DragQueryFileW(hdrop, i, ptr::null_mut(), 0) as usize;
let str_len = character_count + 1;

// Fill path_buf with the null-terminated file name
let mut path_buf = Vec::with_capacity(str_len);
DragQueryFileW(hdrop, i, path_buf.as_mut_ptr(), str_len as UINT);
path_buf.set_len(str_len);

callback(OsString::from_wide(&path_buf[0..character_count]).into());
}

return Some(hdrop);
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl<T: 'static> EventLoop<T> {
}

unsafe {
let mut msg = mem::uninitialized();
let mut msg = mem::zeroed();
let mut msg_unprocessed = false;

'main: loop {
Expand Down Expand Up @@ -507,7 +507,7 @@ impl<T> EventLoopRunner<T> {

// Returns true if the wait time was reached, and false if a message must be processed.
unsafe fn wait_until_time_or_msg(wait_until: Instant) -> bool {
let mut msg = mem::uninitialized();
let mut msg = mem::zeroed();
let now = Instant::now();
if now <= wait_until {
// MsgWaitForMultipleObjects tends to overshoot just a little bit. We subtract 1 millisecond
Expand Down Expand Up @@ -1645,7 +1645,7 @@ unsafe extern "system" fn thread_event_target_callback<T>(
}
};
if in_modal_loop {
let mut msg = mem::uninitialized();
let mut msg = mem::zeroed();
loop {
if 0 == winuser::PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, 0) {
break;
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Window {
}

pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, io::Error> {
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() };
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::zeroed() };
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
let status = unsafe {
winuser::GetMonitorInfoW(
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/windows/raw_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl From<RID_DEVICE_INFO> for RawDeviceInfo {

#[allow(dead_code)]
pub fn get_raw_input_device_info(handle: HANDLE) -> Option<RawDeviceInfo> {
let mut info: RID_DEVICE_INFO = unsafe { mem::uninitialized() };
let mut info: RID_DEVICE_INFO = unsafe { mem::zeroed() };
let info_size = size_of::<RID_DEVICE_INFO>() as UINT;

info.cbSize = info_size;
Expand Down Expand Up @@ -164,7 +164,7 @@ pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> boo
}

pub fn get_raw_input_data(handle: HRAWINPUT) -> Option<RAWINPUT> {
let mut data: RAWINPUT = unsafe { mem::uninitialized() };
let mut data: RAWINPUT = unsafe { mem::zeroed() };
let mut data_size = size_of::<RAWINPUT>() as UINT;
let header_size = size_of::<RAWINPUTHEADER>() as UINT;

Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/windows/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn wchar_ptr_to_string(wchar: *const wchar_t) -> String {
}

pub unsafe fn status_map<T, F: FnMut(&mut T) -> BOOL>(mut fun: F) -> Option<T> {
let mut data: T = mem::uninitialized();
let mut data: T = mem::zeroed();
if fun(&mut data) != 0 {
Some(data)
} else {
Expand All @@ -59,7 +59,7 @@ pub fn get_window_rect(hwnd: HWND) -> Option<RECT> {

pub fn get_client_rect(hwnd: HWND) -> Result<RECT, io::Error> {
unsafe {
let mut rect = mem::uninitialized();
let mut rect = mem::zeroed();
let mut top_left = mem::zeroed();

win_to_err(|| winuser::ClientToScreen(hwnd, &mut top_left))?;
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ impl Window {
}

pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
let mut rect: RECT = unsafe { mem::uninitialized() };
let mut rect: RECT = unsafe { mem::zeroed() };
if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 {
panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit")
}
Expand Down