@@ -11,7 +11,6 @@ use windows::{
1111 INTERNET_PER_CONN_PROXY_BYPASS , INTERNET_PER_CONN_PROXY_SERVER , InternetSetOptionW ,
1212 PROXY_TYPE_AUTO_DETECT , PROXY_TYPE_AUTO_PROXY_URL , PROXY_TYPE_DIRECT , PROXY_TYPE_PROXY ,
1313 } ,
14- System :: Memory :: { GetProcessHeap , HEAP_NONE , HEAP_ZERO_MEMORY , HeapAlloc , HeapFree } ,
1514 } ,
1615 core:: { PCWSTR , PWSTR } ,
1716} ;
@@ -307,51 +306,53 @@ fn get_ras_connections() -> Result<Vec<String>> {
307306 ) ;
308307
309308 log:: debug!( "get allocate buffer size result code: {result_code}" ) ;
310- if result_code == ERROR_BUFFER_TOO_SMALL {
311- // Allocate the memory needed for the array of RAS entry names.
312- let buffer_ptr = HeapAlloc ( GetProcessHeap ( ) ?, HEAP_ZERO_MEMORY , buffer_size as usize ) ;
313- if buffer_ptr. is_null ( ) {
314- log:: error!( "HeapAlloc failed!" ) ;
315- return Ok ( connections) ;
316- }
317- let lp_ras_entry_name = buffer_ptr as * mut RASENTRYNAMEW ;
318- // The first RASENTRYNAME structure in the array must contain the structure size
319- ( * lp_ras_entry_name) . dwSize = std:: mem:: size_of :: < RASENTRYNAMEW > ( ) as u32 ;
320-
321- // 获取所有 RAS 列表
322- let result_code = RasEnumEntriesW (
323- PCWSTR :: null ( ) ,
324- PCWSTR :: null ( ) ,
325- Some ( lp_ras_entry_name) ,
326- & mut buffer_size,
327- & mut entry_count,
328- ) ;
329- // 如果函数成功,则返回值 ERROR_SUCCESS, 但是该 API 返回 u32, 参照对比 ERROR_SUCCESS 后,该值应该为 0
330- log:: debug!( "get RAS entries result code: {result_code}" ) ;
331- if result_code == 0 && entry_count > 0 {
332- for i in 0 ..entry_count as isize {
333- let entry = & * lp_ras_entry_name. offset ( i) ;
334- let name_arr = entry. szEntryName ;
335- // 去除宽字符多余的 0,以便更好的打印 RAS 名称
336- let len = name_arr. iter ( ) . position ( |& x| x == 0 ) . unwrap_or ( 0 ) ;
337- let name = String :: from_utf16_lossy ( & name_arr[ ..len] ) ;
338- connections. push ( name) ;
339- }
340- log:: debug!(
341- "找到 {} 个拨号连接/VPN, {:?}" ,
342- connections. len( ) ,
343- connections
344- ) ;
309+
310+ if result_code != ERROR_BUFFER_TOO_SMALL {
311+ if entry_count >= 1 {
312+ log:: error!( "The operation failed to acquire the buffer size" ) ;
313+ } else {
314+ log:: debug!( "There were no RAS entry names found" ) ;
345315 }
346- // Deallocate memory for the connection buffer
347- HeapFree ( GetProcessHeap ( ) ?, HEAP_NONE , Some ( buffer_ptr) ) ?;
348316 return Ok ( connections) ;
349317 }
350318
351- if entry_count >= 1 {
352- log:: error!( "The operation failed to acquire the buffer size" ) ;
353- } else {
354- log:: debug!( "There were no RAS entry names found" ) ;
319+ let entry_capacity = buffer_size as usize / std:: mem:: size_of :: < RASENTRYNAMEW > ( ) ;
320+ if entry_capacity == 0 {
321+ return Ok ( connections) ;
322+ }
323+
324+ // 使用 Vec 管理缓冲区内存,避免手动堆分配
325+ let mut entries: Vec < RASENTRYNAMEW > = Vec :: with_capacity ( entry_capacity) ;
326+ for _ in 0 ..entry_capacity {
327+ entries. push ( std:: mem:: zeroed ( ) ) ;
328+ }
329+ // The first RASENTRYNAME structure in the array must contain the structure size
330+ entries[ 0 ] . dwSize = std:: mem:: size_of :: < RASENTRYNAMEW > ( ) as u32 ;
331+
332+ // 获取所有 RAS 列表
333+ let result_code = RasEnumEntriesW (
334+ PCWSTR :: null ( ) ,
335+ PCWSTR :: null ( ) ,
336+ Some ( entries. as_mut_ptr ( ) ) ,
337+ & mut buffer_size,
338+ & mut entry_count,
339+ ) ;
340+ // 如果函数成功,则返回值 ERROR_SUCCESS, 但是该 API 返回 u32, 参照对比 ERROR_SUCCESS 后,该值应该为 0
341+ log:: debug!( "get RAS entries result code: {result_code}" ) ;
342+
343+ if result_code == 0 && entry_count > 0 {
344+ for entry in entries. iter ( ) . take ( entry_count as usize ) {
345+ let name_arr = entry. szEntryName ;
346+ // 去除宽字符多余的 0,以便更好的打印 RAS 名称
347+ let len = name_arr. iter ( ) . position ( |& x| x == 0 ) . unwrap_or ( 0 ) ;
348+ let name = String :: from_utf16_lossy ( & name_arr[ ..len] ) ;
349+ connections. push ( name) ;
350+ }
351+ log:: debug!(
352+ "找到 {} 个拨号连接/VPN, {:?}" ,
353+ connections. len( ) ,
354+ connections
355+ ) ;
355356 }
356357 }
357358
0 commit comments