diff --git a/kernel-hal/src/common/user.rs b/kernel-hal/src/common/user.rs index 043fe0ff..9bab1e03 100644 --- a/kernel-hal/src/common/user.rs +++ b/kernel-hal/src/common/user.rs @@ -1,12 +1,12 @@ //! Read/write user space pointer. -use alloc::string::String; -use alloc::vec::Vec; -use core::fmt::{Debug, Formatter}; -use core::marker::PhantomData; -use core::ops::{Deref, DerefMut}; - use crate::VirtAddr; +use alloc::{string::String, vec::Vec}; +use core::{ + fmt::{Debug, Formatter}, + marker::PhantomData, + ops::{Deref, DerefMut}, +}; /// Wapper of raw pointer from user space. #[repr(C)] @@ -68,9 +68,9 @@ unsafe impl Send for UserPtr {} unsafe impl Sync for UserPtr {} impl From for UserPtr { - fn from(x: usize) -> Self { + fn from(ptr: usize) -> Self { UserPtr { - ptr: x as _, + ptr: ptr as _, mark: PhantomData, } } @@ -96,7 +96,7 @@ impl UserPtr { /// `count` is in units of `T`; /// e.g., a count of 3 represents a pointer offset of `3 * size_of::()` bytes. pub fn add(&self, count: usize) -> Self { - UserPtr { + Self { ptr: unsafe { self.ptr.add(count) }, mark: PhantomData, } @@ -120,9 +120,9 @@ impl UserPtr { } impl UserPtr { - /// Always returns a shared reference to the value wrapped in [`Ok`]. - pub fn as_ref(&self) -> Result<&'static T> { - Ok(unsafe { &*self.ptr }) + #[allow(clippy::should_implement_trait)] + pub fn as_ref(&self) -> &'static T { + unsafe { &*self.ptr } } /// Reads the value from self without moving it. @@ -142,56 +142,62 @@ impl UserPtr { } } + /// Forms a slice from a user pointer and a `len`. + pub fn as_slice(&self, len: usize) -> Result<&'static [T]> { + if len == 0 { + Ok(&[]) + } else { + self.check()?; + Ok(unsafe { core::slice::from_raw_parts(self.ptr, len) }) + } + } + /// Copies elements into a new [`Vec`]. /// /// The `len` argument is the number of **elements**, not the number of bytes. pub fn read_array(&self, len: usize) -> Result> { if len == 0 { - return Ok(Vec::default()); + Ok(Vec::default()) + } else { + self.check()?; + let mut ret = Vec::::with_capacity(len); + unsafe { + ret.set_len(len); + ret.as_mut_ptr().copy_from_nonoverlapping(self.ptr, len); + } + Ok(ret) } - self.check()?; - let mut ret = Vec::::with_capacity(len); - unsafe { - ret.set_len(len); - ret.as_mut_ptr().copy_from_nonoverlapping(self.ptr, len); - } - Ok(ret) } } impl UserPtr { - /// Copies chars into a new [`String`]. - /// - /// The `len` argument is the number of **bytes**, not the number of chars. - pub fn read_string(&self, len: usize) -> Result { - self.check()?; - let src = unsafe { core::slice::from_raw_parts(self.ptr, len) }; - let s = core::str::from_utf8(src).map_err(|_| Error::InvalidUtf8)?; - Ok(String::from(s)) + /// Forms a utf-8 string slice from a user pointer and a `len`. + pub fn as_str(&self, len: usize) -> Result<&'static str> { + core::str::from_utf8(self.as_slice(len)?).map_err(|_| Error::InvalidUtf8) } /// Copies an zero-terminated string of c style to a new [`String`]. - pub fn read_cstring(&self) -> Result { - self.check()?; - let len = unsafe { (0usize..).find(|&i| *self.ptr.add(i) == 0).unwrap() }; - self.read_string(len) + pub fn as_c_str(&self) -> Result<&'static str> { + self.as_str(unsafe { (0usize..).find(|&i| *self.ptr.add(i) == 0).unwrap() }) } } -impl UserPtr, P> { +impl UserPtr, P> { /// Copies a group of zero-terminated string into [`String`]s, /// and collect them into a [`Vec`]. pub fn read_cstring_array(&self) -> Result> { self.check()?; - let len = unsafe { - (0usize..) - .find(|&i| self.ptr.add(i).read().is_null()) - .unwrap() - }; - self.read_array(len)? - .into_iter() - .map(|ptr| ptr.read_cstring()) - .collect() + let mut result = Vec::new(); + let mut pptr = self.ptr; + loop { + let sptr = unsafe { pptr.read() }; + if sptr.is_null() { + break; + } + result.push(sptr.as_c_str()?.into()); + pptr = unsafe { pptr.add(1) }; + } + Ok(result) } } @@ -240,7 +246,7 @@ impl UserPtr { #[derive(Debug)] #[repr(C)] -pub struct IoVec { +pub struct IoVec { /// Starting address ptr: UserPtr, /// Number of bytes to transfer @@ -252,7 +258,7 @@ pub type IoVecOut = IoVec; /// A valid IoVecs request from user #[derive(Debug)] -pub struct IoVecs { +pub struct IoVecs { vec: Vec>, } @@ -285,7 +291,7 @@ impl IoVecs

{ pub fn read_to_vec(&self) -> Result> { let mut buf = Vec::new(); for vec in self.vec.iter() { - buf.extend(vec.ptr.read_array(vec.len)?); + buf.extend_from_slice(vec.ptr.as_slice(vec.len)?); } Ok(buf) } diff --git a/kernel-hal/src/libos/vm.rs b/kernel-hal/src/libos/vm.rs index bf40ed25..581fbd83 100644 --- a/kernel-hal/src/libos/vm.rs +++ b/kernel-hal/src/libos/vm.rs @@ -95,7 +95,7 @@ mod tests { use super::*; /// A valid virtual address base to mmap. - const VBASE: VirtAddr = 0x2_00000000; + const VBASE: VirtAddr = 0x0002_0000_0000; #[test] fn map_unmap() { diff --git a/linux-syscall/src/file/dir.rs b/linux-syscall/src/file/dir.rs index ef420dc5..2577a455 100644 --- a/linux-syscall/src/file/dir.rs +++ b/linux-syscall/src/file/dir.rs @@ -1,4 +1,4 @@ -//! Directory operations +//! Directory operations //! //! - getcwd //! - chdir @@ -34,16 +34,16 @@ impl Syscall<'_> { /// Change the current directory. /// - `path` – pointer to string with name of path pub fn sys_chdir(&self, path: UserInPtr) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; info!("chdir: path={:?}", path); let proc = self.linux_process(); - let inode = proc.lookup_inode(&path)?; + let inode = proc.lookup_inode(path)?; let info = inode.metadata()?; if info.type_ != FileType::Dir { return Err(LxError::ENOTDIR); } - proc.change_directory(&path); + proc.change_directory(path); Ok(0) } @@ -56,14 +56,14 @@ impl Syscall<'_> { /// create directory relative to directory file descriptor pub fn sys_mkdirat(&self, dirfd: FileDesc, path: UserInPtr, mode: usize) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; // TODO: check pathname info!( "mkdirat: dirfd={:?}, path={:?}, mode={:#o}", dirfd, path, mode ); - let (dir_path, file_name) = split_path(&path); + let (dir_path, file_name) = split_path(path); let proc = self.linux_process(); let inode = proc.lookup_inode_at(dirfd, dir_path, true)?; if inode.find(file_name).is_ok() { @@ -75,10 +75,10 @@ impl Syscall<'_> { /// Remove a directory. /// - path – pointer to string with directory name pub fn sys_rmdir(&self, path: UserInPtr) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; info!("rmdir: path={:?}", path); - let (dir_path, file_name) = split_path(&path); + let (dir_path, file_name) = split_path(path); let proc = self.linux_process(); let dir_inode = proc.lookup_inode(dir_path)?; let file_inode = dir_inode.find(file_name)?; @@ -141,8 +141,8 @@ impl Syscall<'_> { newpath: UserInPtr, flags: usize, ) -> SysResult { - let oldpath = oldpath.read_cstring()?; - let newpath = newpath.read_cstring()?; + let oldpath = oldpath.as_c_str()?; + let newpath = newpath.as_c_str()?; let flags = AtFlags::from_bits_truncate(flags); info!( "linkat: olddirfd={:?}, oldpath={:?}, newdirfd={:?}, newpath={:?}, flags={:?}", @@ -150,8 +150,8 @@ impl Syscall<'_> { ); let proc = self.linux_process(); - let (new_dir_path, new_file_name) = split_path(&newpath); - let inode = proc.lookup_inode_at(olddirfd, &oldpath, true)?; + let (new_dir_path, new_file_name) = split_path(newpath); + let inode = proc.lookup_inode_at(olddirfd, oldpath, true)?; let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, true)?; new_dir_inode.link(new_file_name, &inode)?; Ok(0) @@ -168,7 +168,7 @@ impl Syscall<'_> { /// remove directory entry relative to directory file descriptor /// The unlinkat() system call operates in exactly the same way as either unlink or rmdir. pub fn sys_unlinkat(&self, dirfd: FileDesc, path: UserInPtr, flags: usize) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; let flags = AtFlags::from_bits_truncate(flags); info!( "unlinkat: dirfd={:?}, path={:?}, flags={:?}", @@ -176,7 +176,7 @@ impl Syscall<'_> { ); let proc = self.linux_process(); - let (dir_path, file_name) = split_path(&path); + let (dir_path, file_name) = split_path(path); let dir_inode = proc.lookup_inode_at(dirfd, dir_path, true)?; let file_inode = dir_inode.find(file_name)?; if file_inode.metadata()?.type_ == FileType::Dir { @@ -199,16 +199,16 @@ impl Syscall<'_> { newdirfd: FileDesc, newpath: UserInPtr, ) -> SysResult { - let oldpath = oldpath.read_cstring()?; - let newpath = newpath.read_cstring()?; + let oldpath = oldpath.as_c_str()?; + let newpath = newpath.as_c_str()?; info!( "renameat: olddirfd={:?}, oldpath={:?}, newdirfd={:?}, newpath={:?}", olddirfd, oldpath, newdirfd, newpath ); let proc = self.linux_process(); - let (old_dir_path, old_file_name) = split_path(&oldpath); - let (new_dir_path, new_file_name) = split_path(&newpath); + let (old_dir_path, old_file_name) = split_path(oldpath); + let (new_dir_path, new_file_name) = split_path(newpath); let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path, false)?; let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path, false)?; old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?; @@ -230,14 +230,14 @@ impl Syscall<'_> { mut base: UserOutPtr, len: usize, ) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; info!( "readlinkat: dirfd={:?}, path={:?}, base={:?}, len={}", dirfd, path, base, len ); let proc = self.linux_process(); - let inode = proc.lookup_inode_at(dirfd, &path, false)?; + let inode = proc.lookup_inode_at(dirfd, path, false)?; if inode.metadata()?.type_ != FileType::SymLink { return Err(LxError::EINVAL); } diff --git a/linux-syscall/src/file/fd.rs b/linux-syscall/src/file/fd.rs index 91f9f3bd..782c3af0 100644 --- a/linux-syscall/src/file/fd.rs +++ b/linux-syscall/src/file/fd.rs @@ -23,7 +23,7 @@ impl Syscall<'_> { mode: usize, ) -> SysResult { let proc = self.linux_process(); - let path = path.read_cstring()?; + let path = path.as_c_str()?; let flags = OpenFlags::from_bits_truncate(flags); info!( "openat: dir_fd={:?}, path={:?}, flags={:?}, mode={:#o}", @@ -31,7 +31,7 @@ impl Syscall<'_> { ); let inode = if flags.contains(OpenFlags::CREATE) { - let (dir_path, file_name) = split_path(&path); + let (dir_path, file_name) = split_path(path); // relative to cwd let dir_inode = proc.lookup_inode_at(dir_fd, dir_path, true)?; match dir_inode.find(file_name) { @@ -47,10 +47,10 @@ impl Syscall<'_> { Err(e) => return Err(LxError::from(e)), } } else { - proc.lookup_inode_at(dir_fd, &path, true)? + proc.lookup_inode_at(dir_fd, path, true)? }; - let file = File::new(inode, flags, path); + let file = File::new(inode, flags, path.into()); let fd = proc.add_file(file)?; Ok(fd.into()) } diff --git a/linux-syscall/src/file/file.rs b/linux-syscall/src/file/file.rs index 811a18d6..0c4ed3d0 100644 --- a/linux-syscall/src/file/file.rs +++ b/linux-syscall/src/file/file.rs @@ -147,10 +147,9 @@ impl Syscall<'_> { /// cause the regular file named by path to be truncated to a size of precisely length bytes. pub fn sys_truncate(&self, path: UserInPtr, len: usize) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; info!("truncate: path={:?}, len={}", path, len); - let proc = self.linux_process(); - proc.lookup_inode(&path)?.resize(len)?; + self.linux_process().lookup_inode(path)?.resize(len)?; Ok(0) } @@ -356,7 +355,7 @@ impl Syscall<'_> { flags: usize, ) -> SysResult { // TODO: check permissions based on uid/gid - let path = path.read_cstring()?; + let path = path.as_c_str()?; let flags = AtFlags::from_bits_truncate(flags); info!( "faccessat: dirfd={:?}, path={:?}, mode={:#o}, flags={:?}", @@ -364,7 +363,7 @@ impl Syscall<'_> { ); let proc = self.linux_process(); let follow = !flags.contains(AtFlags::SYMLINK_NOFOLLOW); - let _inode = proc.lookup_inode_at(dirfd, &path, follow)?; + let _inode = proc.lookup_inode_at(dirfd, path, follow)?; Ok(0) } @@ -395,7 +394,7 @@ impl Syscall<'_> { info!("futimens: fd: {:?}, times: {:?}", fd, times); proc.get_file(fd)?.inode() } else { - let pathname = pathname.read_cstring()?; + let pathname = pathname.as_c_str()?; info!( "utimensat: dirfd: {:?}, pathname: {:?}, times: {:?}, flags: {:#x}", dirfd, pathname, times, flags @@ -407,7 +406,7 @@ impl Syscall<'_> { } else { return Err(LxError::EINVAL); }; - proc.lookup_inode_at(dirfd, &pathname[..], follow)? + proc.lookup_inode_at(dirfd, pathname, follow)? }; let mut metadata = inode.metadata()?; if times[0].nsec != UTIME_OMIT { @@ -439,7 +438,7 @@ impl Syscall<'_> { /// `path` is the pathname of **any file** within the mounted filesystem. /// `buf` is a pointer to a `StatFs` structure. pub fn sys_statfs(&self, path: UserInPtr, mut buf: UserOutPtr) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; info!("statfs: path={:?}, buf={:?}", path, buf); // TODO diff --git a/linux-syscall/src/file/stat.rs b/linux-syscall/src/file/stat.rs index baf090f0..017b1c87 100644 --- a/linux-syscall/src/file/stat.rs +++ b/linux-syscall/src/file/stat.rs @@ -41,7 +41,7 @@ impl Syscall<'_> { mut stat_ptr: UserOutPtr, flags: usize, ) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; let flags = AtFlags::from_bits_truncate(flags); info!( "fstatat: dirfd={:?}, path={:?}, stat_ptr={:?}, flags={:?}", @@ -50,7 +50,7 @@ impl Syscall<'_> { let proc = self.linux_process(); let follow = !flags.contains(AtFlags::SYMLINK_NOFOLLOW); - let inode = proc.lookup_inode_at(dirfd, &path, follow)?; + let inode = proc.lookup_inode_at(dirfd, path, follow)?; let stat = Stat::from(inode.metadata()?); stat_ptr.write(stat)?; Ok(0) diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index dbe8507c..305208c2 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -252,7 +252,7 @@ impl Syscall<'_> { argv: UserInPtr>, envp: UserInPtr>, ) -> SysResult { - let path = path.read_cstring()?; + let path = path.as_c_str()?; let args = argv.read_cstring_array()?; let envs = envp.read_cstring_array()?; info!( @@ -268,7 +268,7 @@ impl Syscall<'_> { // Read program file let proc = self.linux_process(); - let inode = proc.lookup_inode(&path)?; + let inode = proc.lookup_inode(path)?; let data = inode.read_as_vec()?; proc.remove_cloexec_files(); @@ -280,10 +280,10 @@ impl Syscall<'_> { stack_pages: 8, root_inode: proc.root_inode().clone(), }; - let (entry, sp) = loader.load(&vmar, &data, args, envs, path.clone())?; + let (entry, sp) = loader.load(&vmar, &data, args, envs, path.into())?; // Modify exec path - proc.set_execute_path(&path); + proc.set_execute_path(path); // TODO: use right signal // self.zircon_process().signal_set(Signal::SIGNALED); diff --git a/zircon-syscall/src/debuglog.rs b/zircon-syscall/src/debuglog.rs index 59cfa9e5..7aa193b2 100644 --- a/zircon-syscall/src/debuglog.rs +++ b/zircon-syscall/src/debuglog.rs @@ -49,12 +49,12 @@ impl Syscall<'_> { return Err(ZxError::INVALID_ARGS); } let datalen = len.min(224); - let data = buf.read_string(datalen as usize)?; + let data = buf.as_str(datalen as usize)?; let proc = self.thread.proc(); let dlog = proc.get_object_with_rights::(handle_value, Rights::WRITE)?; - dlog.write(Severity::Info, options, self.thread.id(), proc.id(), &data); + dlog.write(Severity::Info, options, self.thread.id(), proc.id(), data); // print to kernel console - kernel_hal::console::console_write_str(&data); + kernel_hal::console::console_write_str(data); if data.as_bytes().last() != Some(&b'\n') { kernel_hal::console::console_write_str("\n"); } diff --git a/zircon-syscall/src/futex.rs b/zircon-syscall/src/futex.rs index 8ee7bbb5..3a0a8a8e 100644 --- a/zircon-syscall/src/futex.rs +++ b/zircon-syscall/src/futex.rs @@ -22,7 +22,7 @@ impl Syscall<'_> { if value_ptr.is_null() || value_ptr.as_addr() % 4 != 0 { return Err(ZxError::INVALID_ARGS); } - let value = value_ptr.as_ref()?; + let value = value_ptr.as_ref(); let proc = self.thread.proc(); let futex = proc.get_futex(value); let new_owner = if new_futex_owner == INVALID_HANDLE { @@ -55,8 +55,8 @@ impl Syscall<'_> { if value_ptr.is_null() || value_ptr.as_addr() % 4 != 0 { return Err(ZxError::INVALID_ARGS); } - let value = value_ptr.as_ref()?; - let requeue = requeue_ptr.as_ref()?; + let value = value_ptr.as_ref(); + let requeue = requeue_ptr.as_ref(); if value_ptr.as_addr() == requeue_ptr.as_addr() { return Err(ZxError::INVALID_ARGS); } @@ -86,7 +86,7 @@ impl Syscall<'_> { if value_ptr.is_null() || value_ptr.as_addr() % 4 != 0 { return Err(ZxError::INVALID_ARGS); } - let value = value_ptr.as_ref()?; + let value = value_ptr.as_ref(); let proc = self.thread.proc(); let futex = proc.get_futex(value); futex.wake(count as usize); @@ -99,7 +99,7 @@ impl Syscall<'_> { if value_ptr.is_null() || value_ptr.as_addr() % 4 != 0 { return Err(ZxError::INVALID_ARGS); } - let value = value_ptr.as_ref()?; + let value = value_ptr.as_ref(); let proc = self.thread.proc(); proc.get_futex(value).wake_single_owner(); Ok(()) diff --git a/zircon-syscall/src/lib.rs b/zircon-syscall/src/lib.rs index 2a67c6bc..11806cbb 100644 --- a/zircon-syscall/src/lib.rs +++ b/zircon-syscall/src/lib.rs @@ -308,7 +308,6 @@ impl Syscall<'_> { // atomic_store_explicit(value_ptr, new_value, memory_order_release) UserInPtr::::from(a0) .as_ref() - .unwrap() .store(a2 as i32, Ordering::Release); let _ = self.sys_futex_wake(a0.into(), a1 as _); let _ = self.sys_handle_close(a3 as _); diff --git a/zircon-syscall/src/object.rs b/zircon-syscall/src/object.rs index d7dc418c..6edcd355 100644 --- a/zircon-syscall/src/object.rs +++ b/zircon-syscall/src/object.rs @@ -125,8 +125,7 @@ impl Syscall<'_> { match property { Property::Name => { let length = buffer_size.min(MAX_NAME_LEN) as usize; - let s = UserInPtr::::from(buffer).read_string(length)?; - object.set_name(&s); + object.set_name(UserInPtr::::from(buffer).as_str(length)?); Ok(()) } Property::ProcessDebugAddr => { diff --git a/zircon-syscall/src/resource.rs b/zircon-syscall/src/resource.rs index 9d4de032..18dec16e 100644 --- a/zircon-syscall/src/resource.rs +++ b/zircon-syscall/src/resource.rs @@ -2,7 +2,7 @@ use {super::*, core::convert::TryFrom, zircon_object::dev::*}; impl Syscall<'_> { #[allow(clippy::too_many_arguments)] - /// Create a resource object for use with other DDK syscalls. + /// Create a resource object for use with other DDK syscalls. pub fn sys_resource_create( &self, parent_rsrc: HandleValue, @@ -17,7 +17,7 @@ impl Syscall<'_> { "resource.create: parent={:#x}, options={:#x}, base={:#X}, size={:#x}", parent_rsrc, options, base, size ); - let name = name.read_string(name_size as usize)?; + let name = name.as_str(name_size as usize)?; info!("name={:?}", name); let proc = self.thread.proc(); let parent_rsrc = proc.get_object_with_rights::(parent_rsrc, Rights::WRITE)?; @@ -25,7 +25,7 @@ impl Syscall<'_> { let flags = ResourceFlags::from_bits(options & 0xFFFF_0000).ok_or(ZxError::INVALID_ARGS)?; parent_rsrc.validate_ranged_resource(kind, base as usize, size as usize)?; parent_rsrc.check_exclusive(flags)?; - let rsrc = Resource::create(&name, kind, base as usize, size as usize, flags); + let rsrc = Resource::create(name, kind, base as usize, size as usize, flags); let handle = proc.add_handle(Handle::new(rsrc, Rights::DEFAULT_RESOURCE)); out.write(handle)?; Ok(()) diff --git a/zircon-syscall/src/task.rs b/zircon-syscall/src/task.rs index 9700a724..f3001921 100644 --- a/zircon-syscall/src/task.rs +++ b/zircon-syscall/src/task.rs @@ -14,7 +14,7 @@ impl Syscall<'_> { mut proc_handle: UserOutPtr, mut vmar_handle: UserOutPtr, ) -> ZxResult { - let name = name.read_string(name_size)?; + let name = name.as_str(name_size)?; info!( "proc.create: job={:#x?}, name={:?}, options={:#x?}", job, name, options, @@ -26,7 +26,7 @@ impl Syscall<'_> { let job = proc .get_object_with_rights::(job, Rights::MANAGE_PROCESS) .or_else(|_| proc.get_object_with_rights::(job, Rights::WRITE))?; - let new_proc = Process::create(&job, &name)?; + let new_proc = Process::create(&job, name)?; let new_vmar = new_proc.vmar(); let proc_handle_value = proc.add_handle(Handle::new(new_proc, Rights::DEFAULT_PROCESS)); let vmar_handle_value = proc.add_handle(Handle::new( @@ -57,7 +57,7 @@ impl Syscall<'_> { options: u32, mut thread_handle: UserOutPtr, ) -> ZxResult { - let name = name.read_string(name_size)?; + let name = name.as_str(name_size)?; info!( "thread.create: proc={:#x?}, name={:?}, options={:#x?}", proc_handle, name, options, @@ -67,7 +67,7 @@ impl Syscall<'_> { } let proc = self.thread.proc(); let process = proc.get_object_with_rights::(proc_handle, Rights::MANAGE_THREAD)?; - let thread = Thread::create(&process, &name)?; + let thread = Thread::create(&process, name)?; let handle = proc.add_handle(Handle::new(thread, Rights::DEFAULT_THREAD)); thread_handle.write(handle)?; Ok(())