@@ -92,21 +92,27 @@ impl Pkcs11Impl {
9292    } 
9393} 
9494
95- impl  Drop  for  Pkcs11Impl  { 
95+ impl  Drop  for  Pkcs11  { 
9696    fn  drop ( & mut  self )  { 
97-         if  let  Err ( e)  = self . finalize ( )  { 
98-             error ! ( "Failed to finalize: {}" ,  e) ; 
97+         if  self . finalize_on_drop  { 
98+             if  let  Err ( e)  = self . impl_ . finalize ( )  { 
99+                 error ! ( "Failed to finalize: {}" ,  e) ; 
100+             } 
99101        } 
100102    } 
101103} 
102104
105+ 
106+ 
103107/// Main PKCS11 context. Should usually be unique per application. 
104108#[ derive( Clone ,  Debug ) ]  
105109pub  struct  Pkcs11  { 
106110    pub ( crate )  impl_ :  Arc < Pkcs11Impl > , 
107111    initialized :  Arc < RwLock < bool > > , 
112+     finalize_on_drop :  bool ,  // NEW FIELD 
108113} 
109114
115+ 
110116impl  Pkcs11  { 
111117    /// Instantiate a new context from the path of a PKCS11 dynamic library implementation. 
112118pub  fn  new < P > ( filename :  P )  -> Result < Self > 
@@ -154,13 +160,15 @@ impl Pkcs11 {
154160                if  list. version . major  >= 3  { 
155161                    let  list30_ptr:  * mut  cryptoki_sys:: CK_FUNCTION_LIST_3_0  =
156162                        ifce. pFunctionList  as  * mut  cryptoki_sys:: CK_FUNCTION_LIST_3_0 ; 
157-                     return  Ok ( Pkcs11  { 
158-                         impl_ :  Arc :: new ( Pkcs11Impl  { 
159-                             _pkcs11_lib :  pkcs11_lib, 
160-                             function_list :  FunctionList :: V3_0 ( * list30_ptr) , 
161-                         } ) , 
162-                         initialized :  Arc :: new ( RwLock :: new ( false ) ) , 
163-                     } ) ; 
163+                 return  Ok ( Pkcs11  { 
164+                     impl_ :  Arc :: new ( Pkcs11Impl  { 
165+                         _pkcs11_lib :  pkcs11_lib, 
166+                         function_list :  FunctionList :: V3_0 ( * list30_ptr) , 
167+                     } ) , 
168+                     initialized :  Arc :: new ( RwLock :: new ( false ) ) , 
169+                     finalize_on_drop :  true , 
170+                 } ) ; 
171+ 
164172                } 
165173                /* fall back to the 2.* API */ 
166174            } 
@@ -179,7 +187,9 @@ impl Pkcs11 {
179187                function_list :  FunctionList :: V2 ( v2tov3 ( * list_ptr) ) , 
180188            } ) , 
181189            initialized :  Arc :: new ( RwLock :: new ( false ) ) , 
190+             finalize_on_drop :  true , 
182191        } ) 
192+ 
183193    } 
184194
185195    /// Initialize the PKCS11 library 
@@ -217,6 +227,16 @@ impl Pkcs11 {
217227pub  fn  is_fn_supported ( & self ,  function :  Function )  -> bool  { 
218228        is_fn_supported ( self ,  function) 
219229    } 
230+     /// Create a `Pkcs11` instance that does NOT automatically call `C_Finalize` when dropped. 
231+ /// This is useful in environments (e.g., C++ wrappers) where PKCS#11 is initialized externally. 
232+ pub  fn  new_no_finalize < P :  AsRef < Path > > ( library_path :  P )  -> Result < Self >  { 
233+         let  pkcs11_lib = unsafe  {  cryptoki_sys:: Pkcs11 :: new ( library_path. as_ref ( ) )  } ?; 
234+ 
235+         let  mut  instance = unsafe  {  Self :: _new ( pkcs11_lib) ? } ; 
236+         instance. finalize_on_drop  = false ; 
237+         Ok ( instance) 
238+     } 
239+ 
220240} 
221241
222242/// This would be great to be From/Into, but it would have to live inside of the cryptoki-sys 
0 commit comments