pub fn handle(&self) -> &Handle { &self.handle }
+ fn is_symlink(&self) -> bool {
+ self.readlink().is_ok()
+ }
+
+ fn readlink(&self) -> io::Result<PathBuf> {
+ let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ let mut bytes = 0;
+
+ unsafe {
+ try!(cvt({
+ c::DeviceIoControl(self.handle.raw(),
+ c::FSCTL_GET_REPARSE_POINT,
+ 0 as *mut _,
+ 0,
+ space.as_mut_ptr() as *mut _,
+ space.len() as libc::DWORD,
+ &mut bytes,
+ 0 as *mut _)
+ }));
+ let buf: *const c::REPARSE_DATA_BUFFER = space.as_ptr() as *const _;
+ if (*buf).ReparseTag != c::IO_REPARSE_TAG_SYMLINK {
+ return Err(io::Error::new(io::ErrorKind::Other, "not a symlink"))
+ }
+ let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
+ &(*buf).rest as *const _ as *const _;
+ let path_buffer = &(*info).PathBuffer as *const _ as *const u16;
+ let subst_off = (*info).SubstituteNameOffset / 2;
+ let subst_ptr = path_buffer.offset(subst_off as isize);
+ let subst_len = (*info).SubstituteNameLength / 2;
+ let subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
+
+ Ok(PathBuf::from(OsString::from_wide(subst)))
+ }
+ }
++
+ pub fn into_handle(self) -> Handle { self.handle }
}
impl FromInner<libc::HANDLE> for File {