Merge pull request #28 from microsoft/com-ptr-initialization

Mark ComPtr::new as unsafe
This commit is contained in:
Hadrian 2019-08-29 15:52:58 +01:00 коммит произвёл GitHub
Родитель 768e7cb9d7 cf0108e1f8
Коммит 475ebdada5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 23 добавлений и 23 удалений

Просмотреть файл

@ -201,9 +201,7 @@ fn get_class_object(iid: &IID) -> Result<ComPtr<IClassFactory>, HRESULT> {
return Err(hr); return Err(hr);
} }
Ok(ComPtr::new( unsafe { Ok(ComPtr::new(class_factory)) }
std::ptr::NonNull::new(class_factory as *mut c_void).unwrap(),
))
} }
// TODO: accept server options // TODO: accept server options
@ -222,9 +220,7 @@ fn create_instance<T: ComInterface + ?Sized>(clsid: &IID) -> Result<ComPtr<T>, H
return Err(hr); return Err(hr);
} }
Ok(ComPtr::new( unsafe { Ok(ComPtr::new(instance)) }
std::ptr::NonNull::new(instance as *mut c_void).unwrap(),
))
} }
fn uninitialize() { fn uninitialize() {

Просмотреть файл

@ -87,7 +87,7 @@ unsafe extern "stdcall" fn ilocalfilemanager_query_interface(
ppv: *mut *mut c_void, ppv: *mut *mut c_void,
) -> HRESULT { ) -> HRESULT {
let lfm = this as *mut LocalFileManager; let lfm = this as *mut LocalFileManager;
let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new(NonNull::new((*lfm).iunk_to_use as *mut c_void).unwrap()); let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new((*lfm).iunk_to_use as *mut c_void);
let hr = iunk_to_use.query_interface(riid, ppv); let hr = iunk_to_use.query_interface(riid, ppv);
forget(iunk_to_use); forget(iunk_to_use);
@ -96,7 +96,7 @@ unsafe extern "stdcall" fn ilocalfilemanager_query_interface(
unsafe extern "stdcall" fn ilocalfilemanager_add_ref(this: *mut IUnknownVPtr) -> u32 { unsafe extern "stdcall" fn ilocalfilemanager_add_ref(this: *mut IUnknownVPtr) -> u32 {
let lfm = this as *mut LocalFileManager; let lfm = this as *mut LocalFileManager;
let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new(NonNull::new((*lfm).iunk_to_use as *mut c_void).unwrap()); let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new((*lfm).iunk_to_use as *mut c_void);
let hr = iunk_to_use.add_ref(); let hr = iunk_to_use.add_ref();
forget(iunk_to_use); forget(iunk_to_use);
@ -105,7 +105,7 @@ unsafe extern "stdcall" fn ilocalfilemanager_add_ref(this: *mut IUnknownVPtr) ->
unsafe extern "stdcall" fn ilocalfilemanager_release(this: *mut IUnknownVPtr) -> u32 { unsafe extern "stdcall" fn ilocalfilemanager_release(this: *mut IUnknownVPtr) -> u32 {
let lfm = this as *mut LocalFileManager; let lfm = this as *mut LocalFileManager;
let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new(NonNull::new((*lfm).iunk_to_use as *mut c_void).unwrap()); let mut iunk_to_use : ComPtr<IUnknown> = ComPtr::new((*lfm).iunk_to_use as *mut c_void);
let hr = iunk_to_use.release(); let hr = iunk_to_use.release();
forget(iunk_to_use); forget(iunk_to_use);

Просмотреть файл

@ -52,8 +52,7 @@ impl IClassFactory for LocalFileManagerClass {
// Here, we create a ComPtr since it is the only way to call IUnknown methods. We also add_ref here, as // Here, we create a ComPtr since it is the only way to call IUnknown methods. We also add_ref here, as
// ComPtr will call release at the end of this scope. // ComPtr will call release at the end of this scope.
let mut non_delegating_unk : ComPtr<IUnknown> = ComPtr::new(NonNull::new(&lfm.non_delegating_unk as *const _ as *mut c_void).unwrap()); let mut non_delegating_unk : ComPtr<IUnknown> = ComPtr::new(&lfm.non_delegating_unk as *const _ as *mut c_void);
// non_delegating_unk.add_ref();
// As an aggregable object, we have to add_ref through the // As an aggregable object, we have to add_ref through the
// non-delegating IUnknown on creation. Otherwise, we might // non-delegating IUnknown on creation. Otherwise, we might

Просмотреть файл

@ -28,7 +28,7 @@ pub struct WindowsFileManager {
impl Drop for WindowsFileManager { impl Drop for WindowsFileManager {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
let mut lfm_iunknown : ComPtr<IUnknown> = ComPtr::new(NonNull::new(self.lfm_iunknown as *mut c_void).unwrap()); let mut lfm_iunknown : ComPtr<IUnknown> = ComPtr::new(self.lfm_iunknown as *mut c_void);
lfm_iunknown.release(); lfm_iunknown.release();
Box::from_raw(self.inner_one as *mut IFileManagerVTable); Box::from_raw(self.inner_one as *mut IFileManagerVTable);
@ -53,7 +53,7 @@ impl IUnknown for WindowsFileManager {
*ppv = self as *const _ as *mut c_void; *ppv = self as *const _ as *mut c_void;
} else if IsEqualGUID(riid, &IID_ILOCAL_FILE_MANAGER) { } else if IsEqualGUID(riid, &IID_ILOCAL_FILE_MANAGER) {
let mut lfm_iunknown : ComPtr<IUnknown> = ComPtr::new(NonNull::new(self.lfm_iunknown as *mut c_void).unwrap()); let mut lfm_iunknown : ComPtr<IUnknown> = ComPtr::new(self.lfm_iunknown as *mut c_void);
let hr = lfm_iunknown.query_interface(riid, ppv); let hr = lfm_iunknown.query_interface(riid, ppv);
if failed(hr) { if failed(hr) {
return E_NOINTERFACE; return E_NOINTERFACE;

Просмотреть файл

@ -113,9 +113,7 @@ fn get_class_object(iid: &IID) -> Result<ComPtr<IClassFactory>, HRESULT> {
return Err(hr); return Err(hr);
} }
Ok(ComPtr::new( unsafe { Ok(ComPtr::new(class_factory)) }
std::ptr::NonNull::new(class_factory as *mut c_void).unwrap(),
))
} }
// TODO: accept server options // TODO: accept server options
@ -134,9 +132,7 @@ fn create_instance<T: ComInterface + ?Sized>(clsid: &IID) -> Result<ComPtr<T>, H
return Err(hr); return Err(hr);
} }
Ok(ComPtr::new( unsafe { Ok(ComPtr::new(instance)) }
std::ptr::NonNull::new(instance as *mut c_void).unwrap(),
))
} }
fn uninitialize() { fn uninitialize() {

Просмотреть файл

@ -13,9 +13,18 @@ pub struct ComPtr<T: ComInterface + ?Sized> {
} }
impl<T: ComInterface + ?Sized> ComPtr<T> { impl<T: ComInterface + ?Sized> ComPtr<T> {
pub fn new(ptr: NonNull<c_void>) -> Self { /// Creates a new ComPtr that comforms to the interface T
///
/// # Safety
///
/// `ptr` must point to a valid VTable for the Interface T
///
/// # Panics
///
/// Panics if `ptr` is null
pub unsafe fn new(ptr: *mut c_void) -> ComPtr<T> {
ComPtr { ComPtr {
ptr, ptr: NonNull::new(ptr).expect("ptr was null"),
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -44,7 +53,7 @@ impl<T: ComInterface + ?Sized> ComPtr<T> {
assert!(hr == E_NOINTERFACE); assert!(hr == E_NOINTERFACE);
return None; return None;
} }
Some(ComPtr::new(std::ptr::NonNull::new(ppv as *mut c_void)?)) unsafe { Some(ComPtr::new(ppv)) }
} }
} }

Просмотреть файл

@ -25,7 +25,7 @@ impl ComPtr<IClassFactory> {
// TODO: decide what failures are possible // TODO: decide what failures are possible
return None; return None;
} }
Some(ComPtr::new(std::ptr::NonNull::new(ppv as *mut c_void)?)) unsafe { Some(ComPtr::new(ppv)) }
} }
} }