diff --git a/src/runtime/process.rs b/src/runtime/process.rs index 16ce849..1179b47 100644 --- a/src/runtime/process.rs +++ b/src/runtime/process.rs @@ -194,6 +194,42 @@ impl Process { } } + /// Gets the path of a module in the file system. The path is a path that is + /// accessible through the WASI file system, so a Windows path of + /// `C:\foo\bar.dll` would be returned as `/mnt/c/foo/bar.dll`. + #[cfg(feature = "alloc")] + #[inline] + pub fn get_module_path(&self, name: &str) -> Result { + // SAFETY: Calling `process_get_module_path` with a null pointer and 0 + // length will return the required length. We then allocate a buffer + // with the required length and call it again with the buffer. We then + // convert the buffer into a string, which is guaranteed to be valid + // UTF-8. + unsafe { + let mut len = 0; + sys::process_get_module_path( + self.0, + name.as_ptr(), + name.len(), + core::ptr::null_mut(), + &mut len, + ); + let mut buf = alloc::vec::Vec::with_capacity(len); + let success = sys::process_get_module_path( + self.0, + name.as_ptr(), + name.len(), + buf.as_mut_ptr(), + &mut len, + ); + if !success { + return Err(Error {}); + } + buf.set_len(len); + Ok(alloc::string::String::from_utf8_unchecked(buf)) + } + } + /// Gets the address and size of a module in the process. #[inline] pub fn get_module_range(&self, name: &str) -> Result<(Address, u64), Error> { diff --git a/src/runtime/sys.rs b/src/runtime/sys.rs index ff58469..e82023e 100644 --- a/src/runtime/sys.rs +++ b/src/runtime/sys.rs @@ -125,6 +125,24 @@ extern "C" { name_ptr: *const u8, name_len: usize, ) -> Option; + /// Stores the file system path of a module in a process in the buffer + /// given. The pointer to the module name needs to point to valid UTF-8 + /// encoded text with the given length. The path is a path that is + /// accessible through the WASI file system, so a Windows path of + /// `C:\foo\bar.exe` would be returned as `/mnt/c/foo/bar.exe`. Returns + /// `false` if the buffer is too small. After this call, no matter whether + /// it was successful or not, the `buf_len_ptr` will be set to the required + /// buffer size. If `false` is returned and the `buf_len_ptr` got set to 0, + /// the path or the module does not exist or it failed to get read. The path + /// is guaranteed to be valid UTF-8 and is not nul-terminated. + #[cfg(feature = "alloc")] + pub fn process_get_module_path( + process: Process, + name_ptr: *const u8, + name_len: usize, + buf_ptr: *mut u8, + buf_len_ptr: *mut usize, + ) -> bool; /// Stores the file system path of the executable in the buffer given. The /// path is a path that is accessible through the WASI file system, so a /// Windows path of `C:\foo\bar.exe` would be returned as