@@ -119,6 +119,45 @@ impl Library {
119119 }
120120 }
121121
122+ /// Load a module that is already loaded by the program.
123+ ///
124+ /// This function returns a `Library` corresponding to a module with the given name that is
125+ /// already mapped into the address space of the process. If the module isn't found an error is
126+ /// returned.
127+ ///
128+ /// If the `filename` does not include a full path and there are multiple different loaded
129+ /// modules corresponding to the `filename`, it is impossible to predict which module handle
130+ /// will be returned. For more information refer to [MSDN].
131+ ///
132+ /// If the `filename` specifies a library filename without path and with extension omitted,
133+ /// `.dll` extension is implicitly added. This behaviour may be suppressed by appending a
134+ /// trailing `.` to the `filename`.
135+ ///
136+ /// This is equivalent to `GetModuleHandleExW(0, filename, _)`.
137+ ///
138+ /// [MSDN]: https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexw
139+ pub fn open_already_loaded < P : AsRef < OsStr > > ( filename : P ) -> Result < Library , crate :: Error > {
140+ let wide_filename: Vec < u16 > = filename. as_ref ( ) . encode_wide ( ) . chain ( Some ( 0 ) ) . collect ( ) ;
141+
142+ let ret = unsafe {
143+ let mut handle: HMODULE = std:: ptr:: null_mut ( ) ;
144+ with_get_last_error ( |source| crate :: Error :: GetModuleHandleExW { source } , || {
145+ // Make sure no winapi calls as a result of drop happen inside this closure, because
146+ // otherwise that might change the return value of the GetLastError.
147+ let result = libloaderapi:: GetModuleHandleExW ( 0 , wide_filename. as_ptr ( ) , & mut handle) ;
148+ if result == 0 {
149+ None
150+ } else {
151+ Some ( Library ( handle) )
152+ }
153+ } ) . map_err ( |e| e. unwrap_or ( crate :: Error :: GetModuleHandleExWUnknown ) )
154+ } ;
155+
156+ drop ( wide_filename) ; // Drop wide_filename here to ensure it doesn’t get moved and dropped
157+ // inside the closure by mistake. See comment inside the closure.
158+ ret
159+ }
160+
122161 /// Find and load a module, additionally adjusting behaviour with flags.
123162 ///
124163 /// See [`Library::new`] for documentation on handling of the `filename` argument. See the
0 commit comments