I'm playing around with windows.rs and I would like to create a network link using NetUseAdd function from "Win32_NetworkManagement_NetManagement". I faced an issue and I would like to know how can I convert the c struct to raw pointer for useinfo?
unsafe {
let mut parm_err: Option<*mut u32> = None;
let remote = conver_pwstr("//WIN-HDOB90189BJ/Users/test/Desktop/share//");
let password = conver_pwstr("test");
let username = conver_pwstr("test");
let mut useifo: USE_INFO_2 = USE_INFO_2::default();
useifo.ui2_local = remote;
useifo.ui2_username = username;
useifo.ui2_password = password;
let levelflags: u32 = 2;
NetUseAdd(None, levelflags, useifo, parm_err);
}
NetUseAdd(None, levelflags, useifo, parm_err);
Error: expected *-ptr, found struct windows::Win32::NetworkManagement::NetManagement::USE_INFO_2
Related
I'm trying to iterate through NEAR's RocksDB,
I've downloaded the small backup from s3 and using the code below to iterate through col33 (transactions)
But it doesn't print anything as RocksDB would be empty (but it is not obviously),
could you please point me out what I'm doing wrong?
Thanks
use std::env;
use rocksdb::{ColumnFamilyDescriptor, DB, IteratorMode, Options};
fn col_name(col: i32) -> String {
format!("col{}", col)
}
fn main() {
println!("Hello, RocksDB!");
let args: Vec<String> = env::args().collect();
let path = if args.len() > 1 {
args.get(1).unwrap().clone()
} else {
String::from("./data")
};
println!("data dir={}", &path);
let opts = Options::default();
let mut cfs:Vec<ColumnFamilyDescriptor> = Vec::new();
for col in 33..34 {
cfs.push(
rocksdb::ColumnFamilyDescriptor::new(col_name(col),opts.clone()));
}
let db = DB::open_cf_descriptors_read_only(
&opts,&path, cfs, false,
).unwrap();
let iter = db.iterator(IteratorMode::Start);
for (key, value) in iter {
println!("Saw {:?} {:?}", key, value);
let k = String::from_utf8(key.to_vec()).unwrap();
let v = String::from_utf8(value.to_vec()).unwrap();
println!("Saw {:?} {:?}", k, v);
}
let _ = DB::destroy(&Options::default(), &path);
}
I've found what was wrong,
as Asad Awadia mentioned, I'm using iterator over default column family here.
I've used iterator_cf instead and got some data:
let cf_handle = db.cf_handle("col33").unwrap();
let iter = db.iterator_cf(cf_handle, IteratorMode::Start);
I have a structure like
struct Node {
pub id: String,
pub dis: String,
pub parent: Option<NodeRefNodeRefWeak>,
pub children: Vec<NodeRef>,
}
pub type NodeRef = Rc<RefCell<Node>>;
pub type NodeRefNodeRefWeak = Weak<RefCell<Node>>;
I also have a start of a function that can iterate this structure to
pull out a match on a node id but it has issues.
What I would like is for this function to return the parent node of the whole tree with ONLY the branches that have a match somewhere on the branch.
Children past the search node can be removed.
Ie a function that filters all other nodes out of the tree.
For example with my rust playground link I would like it to return
level0_node_#1 (level0_node_#1)
level1_node_4 (level1_node_4)
level2_node_4_3 (level2_node_4_3)
level3_node_4_3_2 (level3_node_4_3_2)
However, using the recursive approach as below causes real issue with already borrowed errors when trying to remove branches etc.
Is there a way to achieve this filter function?
I have a test in the Rust playground.
fn tree_filter_node_objects<F>(node: &NodeRef, f: F) -> Vec<NodeRef>
where F: Fn(&str) -> bool + Copy {
let mut filtered_nodes: Vec<NodeRef> = vec![];
let mut borrow = node.borrow_mut();
if f(&borrow.id) {
filtered_nodes.push(node.clone());
}
for n in borrow.children.iter() {
let children_filtered = tree_filter_node_objects(n, f);
for c in children_filtered.iter() {
filtered_nodes.push(c.clone());
}
}
filtered_nodes
}
In the end I used this iterative approach.
pub fn tree_filter_node_dfs<F>(root: &NodeRef, f: F) -> Vec<NodeRef>
where F: Fn(&BmosHaystackObject) -> bool + Copy {
let mut filtered_nodes: Vec<NodeRef> = vec![];
let mut cur_node: Option<NodeRef> = Some(root.clone());
let mut last_visited_child: Option<NodeRef> = None;
let mut next_child: Option<NodeRef>;
let mut run_visit: bool = true;
while cur_node.is_some() {
if run_visit {
let n = cur_node.as_ref().unwrap();
if f(&n.borrow().object) {
}
}
if last_visited_child.is_none() {
let children = cur_node.as_ref().unwrap().borrow().children.clone();
if children.len() > 0 {
next_child = Some(children[0].clone());
}
else {
next_child = None;
}
}
else {
next_child = tree_filter_node_get_next_sibling(last_visited_child.as_ref().unwrap());
}
if next_child.is_some() {
last_visited_child = None;
cur_node = next_child;
run_visit = true;
}
else {
last_visited_child = cur_node;
cur_node = tree_node_parent_node(&last_visited_child.clone().unwrap().clone());
run_visit = false;
}
}
filtered_nodes
}
I want to make an HTTP request using the hyper crate. If the user has provided the proxy settings, the request must go through the proxy, otherwise the request will be sent without the proxy.
Here is my approach: -
use hyper::Client;
use hyper::client::HttpConnector;
use hyper_proxy::Intercept;
use hyper_proxy::Proxy;
use hyper_proxy::ProxyConnector;
fn main(){
let proxy_url_opt:Option<String> = Some(String::from("http://ip-address:port"))
let client = match proxy_url_opt { // Line 68
Some(proxy_url)=>{
let uri_str = &proxy_url;
let proxy_uri = uri_str.parse().unwrap();
let mut proxy = Proxy::new(Intercept::All, proxy_uri);
let connector = HttpConnector::new();
let proxy_connector = ProxyConnector::from_proxy(connector, proxy).unwrap();
let client = Client::builder().build(proxy_connector);
client // Line 80
}
None=>{
Client::new() // Line 83
}
};
// while condition {
let response = client.request(request).await?;
// }
}
But this code giving me and error.
match arms have incompatible types
expected struct `hyper_proxy::ProxyConnector`, found struct `hyper::client::connect::http::HttpConnector`
note: expected type `hyper::client::Client<hyper_proxy::ProxyConnector<hyper::client::connect::http::HttpConnector>, _>`
found struct `hyper::client::Client<hyper::client::connect::http::HttpConnector, hyper::body::body::Body>`rustc(E0308)
main.rs(68, 18): `match` arms have incompatible types
main.rs(80, 13): this is found to be of type `hyper::client::Client<hyper_proxy::ProxyConnector<hyper::client::connect::http::HttpConnector>, _>`
main.rs(83, 13): expected struct `hyper_proxy::ProxyConnector`, found struct `hyper::client::connect::http::HttpConnector`
What is the rust way to solve this?
With the support of yorodm I have solved it using an enum. This is how I solved it:-
enum Client {
Proxy(HyperClient<ProxyConnector<HttpConnector>>),
Http(HyperClient<HttpConnector>)
}
impl Client {
pub fn request(&self, mut req: Request<Body>) -> ResponseFuture{
match self {
Client::Proxy(client)=>{
client.request(req)
}
Client::Http(client)=>{
client.request(req)
}
}
}
}
I'm trying to read the Windows event log using EvtQuery and the winapi crate.
I'm getting system error 87 - ERROR_INVALID_PARAMETER
fn to_vec(str: &str) -> Vec<u16> {
return std::ffi::OsStr::new(str)
.encode_wide()
.chain(Some(0).into_iter())
.collect();
}
fn read_log() {
let v = to_vec("System");
let provider = v.as_ptr();
let vv = to_vec("*");
let my_query = vv.as_ptr();
unsafe {
let query_read = winapi::um::winevt::EvtQuery(std::ptr::null_mut(), provider, my_query, 0);
let status = winapi::um::errhandlingapi::GetLastError();
println!("{}", status);
}
}
What am I doing wrong?
The flags parameter of EvtQuery must be one or more values from the EVT_QUERY_FLAGS enumeration.
You are using the literal 0, which is no existing flag:
typedef enum _EVT_QUERY_FLAGS {
EvtQueryChannelPath = 0x1,
EvtQueryFilePath = 0x2,
EvtQueryForwardDirection = 0x100,
EvtQueryReverseDirection = 0x200,
EvtQueryTolerateQueryErrors = 0x1000
} EVT_QUERY_FLAGS;
In your case, you can use EvtQueryChannelPath with the numerical value of 1. This is exposed as EvtQueryChannelPath in winapi.
I'm hoping someone may be able to help i'm using Xcode 8 and swift 3
I have a playground file Xcode 7 swift 2 that involves a Midi callback for Midi Input everything works fine in 7
I tried a conversion to 8 and it brought up errors regarding memory and a few name changes mostly of what i believe to be non serious i also redefined the infinite loop using PlaygroundSupport
However the error i cannot get over involves MyMIDIReadProc at
MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort);
The error says
Cannot convert value of type '(pktList: UnsafePointer, readProcRefCon: UnsafeMutablePointer, srcConnRefCon: UnsafeMutablePointer) -> Void' to expected argument type 'MIDIReadProc' (aka '#convention(c) (UnsafePointer, Optional>, Optional>) -> ()')
My understanding is that it needs a #convention(c) wrapper of some description inserted. I think i'm on the right track because you can wrap a function but my knowledge of where to put it has run out. Again i was hoping some one might be able to advise
Thanks for reading
apologies for any bad language as i'm self taught
Here is the original Xcode 7 code
import Cocoa
import CoreMIDI
import XCPlayground
func getDisplayName(obj: MIDIObjectRef) -> String
{
var param: Unmanaged<CFString>?
var name: String = "Error";
let err: OSStatus = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, ¶m)
if err == OSStatus(noErr)
{
name = param!.takeRetainedValue() as String
}
return name;
}
func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>,
readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void
{
let packetList:MIDIPacketList = pktList.memory;
let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(COpaquePointer(srcConnRefCon)).memory;
print("MIDI Received From Source: \(getDisplayName(srcRef))");
var packet:MIDIPacket = packetList.packet;
for _ in 1...packetList.numPackets
{
let bytes = Mirror(reflecting: packet.data).children;
var dumpStr = "";
// bytes mirror contains all the zero values in the ridiulous packet data tuple
// so use the packet length to iterate.
var i = packet.length;
for (_, attr) in bytes.enumerate()
{
dumpStr += String(format:"$%02X ", attr.value as! UInt8);
--i;
if (i <= 0)
{
break;
}
}
print(dumpStr)
packet = MIDIPacketNext(&packet).memory;
}
}
var midiClient: MIDIClientRef = 0;
var inPort:MIDIPortRef = 0;
var src:MIDIEndpointRef = MIDIGetSource(0);
MIDIClientCreate("MidiTestClient", nil, nil, &midiClient);
MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort);
MIDIPortConnectSource(inPort, src, &src);
// Keep playground running
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true;
And here is the Xcode 8 code converted
var str = "Hello, playground"
import Cocoa
import CoreMIDI
import XCPlayground
import PlaygroundSupport
func getDisplayName(obj: MIDIObjectRef) -> String
{
var param: Unmanaged<CFString>?
var name: String = "Error";
let err: OSStatus = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, ¶m)
if err == OSStatus(noErr)
{
name = param!.takeRetainedValue() as String
}
return name;
}
func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>,
readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void
{
let packetList:MIDIPacketList = pktList.pointee;
let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(OpaquePointer(srcConnRefCon)).pointee;
print("MIDI Received From Source: \(getDisplayName(obj: srcRef))");
var packet:MIDIPacket = packetList.packet;
for _ in 1...packetList.numPackets
{
let bytes = Mirror(reflecting: packet.data).children;
var dumpStr = "";
var i = packet.length;
for (_, attr) in bytes.enumerated()
{
dumpStr += String(format:"$%02X ", attr.value as! UInt8);
i -= 1;
if (i <= 0)
{
break;
}
}
print(dumpStr)
packet = MIDIPacketNext(&packet).pointee;
}
}
var midiClient: MIDIClientRef = 0;
var inPort:MIDIPortRef = 0;
var src:MIDIEndpointRef = MIDIGetSource(0);
MIDIClientCreate("MidiTestClient", nil, nil, &midiClient);
MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort);
MIDIPortConnectSource(inPort, src, &src);
PlaygroundPage.current.needsIndefiniteExecution = true
Pointer types are drastically changed in Swift 3. Many C-based APIs' signatures are changed accordingly.
Following those changes manually would be painful. You can make Swift work for you, with a little modification.
Try changing the function header:
func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>,
readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void
{
to a closure declaration:
let MyMIDIReadProc: MIDIReadProc = {pktList, readProcRefCon, srcConnRefCon in
Swift infers argument types perfectly in this style.
You may need to fix pointer type conversion:
let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(OpaquePointer(srcConnRefCon)).pointee;
to something like this:
//I'm not sure using `!` is safe here...
let srcRef: MIDIEndpointRef = UnsafeMutablePointer(srcConnRefCon!).pointee
(By the way, the equivalent part in your Xcode 7 code is a little bit redundant. You have no need to use intermediate COpaquePointer there.)
In Swift 3, pointers cannot be nil, and nullable pointers are represented with Optionals. You may need many other fixes to work with C-based APIs in Swift 3.
OOPer is pointing (ahem) you in the right direction. Here is a blog post on using Swift 3 Core MIDI along with a working github repo.
Assuming that you're working with CoreMIDI 1.3 or later, you may have more luck using MIDIInputPortCreateWithBlock instead of MIDIInputPortCreate.
This method takes a Swift block as a parameter instead of requiring an #convention(c) function reference, making it more amenable to use within methods belonging to Swift classes, e.g.:
public func midiReadBlock(ptr: UnsafePointer<MIDIPacketList>, _: UnsafeMutableRawPointer?) -> Void {
let list: MIDIPacketList = ptr.pointee
...
}
You may also find these two extensions useful.
This one (derived from here) allows you to iterate directly over a MIDIPacketList using for pkt in list:
extension MIDIPacketList: Sequence {
public func makeIterator() -> AnyIterator<MIDIPacket> {
var iterator: MIDIPacket?
var nextIndex: UInt32 = 0
return AnyIterator {
nextIndex += 1
if nextIndex > self.numPackets { return nil }
if iterator != nil {
iterator = withUnsafePointer(to: &iterator!) { MIDIPacketNext($0).pointee }
} else {
iterator = self.packet;
}
return iterator
}
}
}
and this one adds a method to a MIDIPacket to extract the contents as a [UInt8] instead of having to use the really broken tuple syntax:
extension MIDIPacket {
public var asArray: [UInt8] {
let mirror = Mirror(reflecting: self.data)
let length = Int(self.length)
var result = [UInt8]()
result.reserveCapacity(length)
for (n, child) in mirror.children.enumerated() {
if n == length {
break
}
result.append(child.value as! UInt8)
}
return result
}
}