1 // Licensed under the Apache License, Version 2.0 2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. 4 // All files in the project carrying such notice may not be copied, modified, or distributed 5 // except according to those terms. 6 use error::{Error, Result}; 7 use std::{ 8 ops::Deref, 9 os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle}, 10 ptr::null_mut, 11 }; 12 use winapi::{ 13 um::{ 14 handleapi::{CloseHandle, DuplicateHandle}, 15 processthreadsapi::GetCurrentProcess, 16 winnt::{DUPLICATE_SAME_ACCESS, HANDLE}, 17 }, 18 shared::minwindef::FALSE, 19 }; 20 21 pub struct Handle(HANDLE); 22 impl Handle { 23 // Takes ownership of the handle new(handle: HANDLE) -> Handle24 pub unsafe fn new(handle: HANDLE) -> Handle { 25 Handle(handle) 26 } close(self) -> Result<()>27 pub fn close(self) -> Result<()> { 28 match unsafe { CloseHandle(self.into_raw_handle()) } { 29 0 => Error::last(), 30 _ => Ok(()), 31 } 32 } 33 // Duplicates the handle without taking ownership duplicate_from(handle: HANDLE) -> Result<Handle>34 pub unsafe fn duplicate_from(handle: HANDLE) -> Result<Handle> { 35 let mut new_handle = null_mut(); 36 let res = DuplicateHandle( 37 GetCurrentProcess(), handle, GetCurrentProcess(), 38 &mut new_handle, 0, FALSE, DUPLICATE_SAME_ACCESS, 39 ); 40 match res { 41 0 => Error::last(), 42 _ => Ok(Handle(new_handle)), 43 } 44 } 45 } 46 impl AsRawHandle for Handle { as_raw_handle(&self) -> HANDLE47 fn as_raw_handle(&self) -> HANDLE { 48 self.0 49 } 50 } 51 impl Deref for Handle { 52 type Target = HANDLE; deref(&self) -> &HANDLE53 fn deref(&self) -> &HANDLE { &self.0 } 54 } 55 impl Drop for Handle { drop(&mut self)56 fn drop(&mut self) { 57 let ret = unsafe { CloseHandle(self.0) }; 58 let err: Result<()> = Error::last(); 59 assert!(ret != 0, "{:?}", err); 60 } 61 } 62 impl FromRawHandle for Handle { from_raw_handle(handle: HANDLE) -> Handle63 unsafe fn from_raw_handle(handle: HANDLE) -> Handle { 64 Handle(handle) 65 } 66 } 67 impl IntoRawHandle for Handle { into_raw_handle(self) -> HANDLE68 fn into_raw_handle(self) -> HANDLE { 69 self.0 70 } 71 } 72