@@ -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