@@ -119,6 +119,45 @@ impl Library {
119
119
}
120
120
}
121
121
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
+
122
161
/// Find and load a module, additionally adjusting behaviour with flags.
123
162
///
124
163
/// See [`Library::new`] for documentation on handling of the `filename` argument. See the
0 commit comments