CertOpenSystemsStoreW或CertCloseStore的Rust FFI声明有什么问题?

时间:2017-04-17 18:23:50

标签: winapi rust ffi

我正在尝试从Rust调用Win32 API CertOpenSystemsStoreWCertCloseStore函数。当我这样做时,我在CertCloseStore上遇到了访问冲突,所以我想我的某些参数类型的大小有误,但我看不到它。

以下Python代码可以工作(我有相同的工作C ++,但没有很好地包含):

In [1]: import ctypes    
In [2]: c32 = ctypes.windll.crypt32    
In [3]: c32.CertOpenSystemStoreW.argtypes = [ctypes.c_void_p, ctypes.c_wchar_p]    
In [4]: c32.CertOpenSystemStoreW.restype = ctypes.c_void_p    
In [5]: c32.CertCloseStore.argtypes=[ctypes.c_void_p, ctypes.c_ulong]    
In [6]: s = c32.CertOpenSystemStoreW(0, "my")    
In [7]: c32.CertCloseStore(s, 0)
Out[7]: 1

这是失败的Rust:

extern crate libc;
use libc::{c_ulong, c_int, c_void};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::ptr::null;

type HPROVIDER = c_void;
type HCERTSTORE = c_void;
type BOOL = c_int;

#[link(name = "Crypt32")]
extern "stdcall" {
    fn CertOpenSystemStoreW(
        hProv: *const HPROVIDER, szSubsystemProtocol: *const u16) -> HCERTSTORE;
    fn CertCloseStore(
        hCertStore: HCERTSTORE, dwFlags: c_ulong) -> BOOL;
}

fn to_utf16(s: &str) -> Vec<u16> {
    let os_s = OsStr::new(s);
    return os_s.encode_wide().chain(Some(0).into_iter()).collect::<Vec<_>>();
}

fn main() {
    let protocol_utf16 = to_utf16("my");
    let storehandle;
    unsafe {
        storehandle = CertOpenSystemStoreW(null(), protocol_utf16.as_ptr());
    }

    let freeresults;
    unsafe {
        freeresults = CertCloseStore(storehandle, 0);
    }
    println!("{}", freeresults);
}

我正在使用Rust 1.16。

1 个答案:

答案 0 :(得分:1)

嗯,有两个问题:

  1. DWORD是32位,无论你是在64位还是32位窗口(我认为这是有道理的)。所以我的CertCloseStore的第二个参数是错误的。
  2. c_void不是指针类型 - 它只是u8。所以我上面的代码应该类似于type HPROVIDER = *const c_void;(这不是很好,因为它使所有HPROVIDER成为常量,但我没有看到一种方法来执行Rust样式指针typedef而不指定'mut'或'const的')。