Skip to content

Commit 78fda72

Browse files
jiang1997youknowone
authored andcommitted
feat: _winapi.GetModuleFileName
1 parent d121f5e commit 78fda72

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

vm/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ schannel = "0.1.19"
113113
widestring = "0.5.1"
114114

115115
[target.'cfg(windows)'.dependencies.windows]
116-
version = "0.39"
116+
version = "0.39.0"
117117
features = [
118-
"Win32_UI_Shell",
118+
"Win32_UI_Shell", "Win32_System_LibraryLoader", "Win32_Foundation"
119119
]
120120

121121
[target.'cfg(windows)'.dependencies.winapi]

vm/src/stdlib/winapi.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ mod _winapi {
1010
stdlib::os::errno_err,
1111
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
1212
};
13+
use std::ffi::{OsStr, OsString};
14+
use std::os::windows::prelude::*;
1315
use std::ptr::{null, null_mut};
1416
use winapi::shared::winerror;
1517
use winapi::um::{
1618
fileapi, handleapi, namedpipeapi, processenv, processthreadsapi, synchapi, winbase,
1719
winnt::HANDLE,
1820
};
21+
use windows::{
22+
core::PCWSTR,
23+
Win32::Foundation::{HINSTANCE, MAX_PATH},
24+
Win32::System::LibraryLoader::{GetModuleFileNameW, LoadLibraryW},
25+
};
1926

2027
#[pyattr]
2128
use winapi::{
@@ -402,4 +409,56 @@ mod _winapi {
402409
})
403410
.map(drop)
404411
}
412+
413+
pub trait ToWideString {
414+
fn to_wide(&self) -> Vec<u16>;
415+
fn to_wides_with_nul(&self) -> Vec<u16>;
416+
}
417+
impl<T> ToWide for T
418+
where
419+
T: AsRef<OsStr>,
420+
{
421+
fn to_wide(&self) -> Vec<u16> {
422+
self.as_ref().encode_wide().collect()
423+
}
424+
fn to_wide_null(&self) -> Vec<u16> {
425+
self.as_ref().encode_wide().chain(Some(0)).collect()
426+
}
427+
}
428+
pub trait FromWide
429+
where
430+
Self: Sized,
431+
{
432+
fn from_wides_until_nul(wide: &[u16]) -> Self;
433+
}
434+
impl FromWide for OsString {
435+
fn from_wide_null(wide: &[u16]) -> OsString {
436+
let len = wide.iter().take_while(|&&c| c != 0).count();
437+
OsString::from_wide(&wide[..len])
438+
}
439+
}
440+
441+
#[pyfunction]
442+
fn LoadLibrary(path: PyStrRef, vm: &VirtualMachine) -> PyResult<isize> {
443+
let path = path.as_str().to_wide_null();
444+
let handle = unsafe { LoadLibraryW(PCWSTR::from_raw(path.as_ptr())).unwrap() };
445+
if handle.is_invalid() {
446+
return Err(vm.new_runtime_error("LoadLibrary failed".to_owned()));
447+
}
448+
Ok(handle.0)
449+
}
450+
451+
#[pyfunction]
452+
fn GetModuleFileName(handle: isize, vm: &VirtualMachine) -> PyResult<String> {
453+
let mut path: Vec<u16> = vec![0; MAX_PATH as usize];
454+
let handle = HINSTANCE(handle);
455+
456+
let length = unsafe { GetModuleFileNameW(handle, &mut path) };
457+
if length == 0 {
458+
return Err(vm.new_runtime_error("GetModuleFileName failed".to_owned()));
459+
}
460+
461+
let (path, _) = path.split_at(length as usize);
462+
Ok(String::from_utf16(&path).unwrap())
463+
}
405464
}

0 commit comments

Comments
 (0)