1- use std:: convert:: TryFrom ;
2- use std:: io:: { Error as IoError , Result as IoResult } ;
3- use std:: mem:: { replace, zeroed} ;
4- use std:: os:: windows:: ffi:: OsStringExt as _;
1+ use std:: io:: Result as IoResult ;
2+ use std:: mem:: replace;
53use std:: time:: Duration ;
6- use std:: os:: windows:: io:: AsRawHandle ;
74
85use async_stream:: stream;
96use tokio:: net:: windows:: named_pipe:: {
107 ClientOptions , NamedPipeClient , NamedPipeServer , ServerOptions ,
118} ;
129use tokio:: time:: sleep;
13- use windows_sys:: Win32 :: Foundation :: { ERROR_MORE_DATA , ERROR_PIPE_BUSY } ;
14- use windows_sys:: Win32 :: Storage :: FileSystem :: * ;
10+ use windows_sys:: Win32 :: Foundation :: ERROR_PIPE_BUSY ;
1511
1612use super :: { Listener , Socket } ;
1713
@@ -20,7 +16,7 @@ impl Listener {
2016 let listener = ServerOptions :: new ( )
2117 . first_pipe_instance ( true )
2218 . create ( addr. as_ref ( ) ) ?;
23- Self :: try_from ( listener)
19+ Ok ( Self :: from ( ( listener, addr ) ) )
2420 }
2521}
2622
@@ -39,19 +35,18 @@ impl Socket {
3935 }
4036}
4137
42- impl TryFrom < NamedPipeServer > for Listener {
43- type Error = IoError ;
44- fn try_from ( mut listener : NamedPipeServer ) -> IoResult < Self > {
45- let name = get_pipe_name ( & listener) ?;
46- Ok ( Self :: new ( stream ! {
38+ impl < T : AsRef < str > > From < ( NamedPipeServer , T ) > for Listener {
39+ fn from ( ( mut listener, addr) : ( NamedPipeServer , T ) ) -> Self {
40+ let addr = addr. as_ref ( ) . to_string ( ) ;
41+ Self :: new ( stream ! {
4742 loop {
4843 yield listener
4944 . connect( )
5045 . await
51- . and_then( |_| ServerOptions :: new( ) . create( & name ) )
46+ . and_then( |_| ServerOptions :: new( ) . create( & addr ) )
5247 . map( |l| replace( & mut listener, l) ) ;
5348 }
54- } ) )
49+ } )
5550 }
5651}
5752
@@ -66,66 +61,3 @@ impl From<NamedPipeClient> for Socket {
6661 Self :: new ( socket)
6762 }
6863}
69-
70- fn get_pipe_name ( pipe : & impl AsRawHandle ) -> IoResult < std:: ffi:: OsString > {
71- let mut info: FILE_NAME_INFO = unsafe { zeroed ( ) } ;
72- let handle = pipe. as_raw_handle ( ) ;
73-
74- let success = unsafe {
75- GetFileInformationByHandleEx (
76- handle as _ ,
77- FileNameInfo ,
78- & mut info as * mut FILE_NAME_INFO as _ ,
79- size_of :: < FILE_NAME_INFO > ( ) as _ ,
80- )
81- } ;
82-
83- // First call to GetFileInformationByHandleEx should fail with ERROR_MORE_DATA.
84- // This gives us the size we need to allocate to store the data.
85- if success == 0 {
86- let err = IoError :: last_os_error ( ) ;
87- if err. raw_os_error ( ) != Some ( ERROR_MORE_DATA as i32 ) {
88- return Err ( err) ;
89- }
90- }
91-
92- // Allocate enough space for a second call to GetFileInformationByHandleEx.
93- let size = size_of :: < FILE_NAME_INFO > ( ) + info. FileNameLength as usize ;
94- let mut info = vec ! [ 0u8 ; size] ;
95-
96- let success = unsafe {
97- GetFileInformationByHandleEx ( handle as _ , FileNameInfo , info. as_mut_ptr ( ) as _ , size as _ )
98- } ;
99-
100- // If the second call fails, bail out.
101- if success == 0 {
102- return Err ( IoError :: last_os_error ( ) ) ;
103- }
104-
105- let info = info. as_ptr ( ) as * const FILE_NAME_INFO ;
106- let info = unsafe { info. as_ref ( ) } . unwrap ( ) ;
107-
108- let name = unsafe {
109- std:: slice:: from_raw_parts ( info. FileName . as_ptr ( ) as _ , ( info. FileNameLength / 2 ) as _ )
110- } ;
111- let name = std:: ffi:: OsString :: from_wide ( name) ;
112- let mut full_name = std:: ffi:: OsString :: from ( r"\\.\pipe" ) ;
113- full_name. extend ( [ name] ) ;
114-
115- Ok ( full_name)
116- }
117-
118- #[ tokio:: test]
119- async fn test_get_pipe_name ( ) {
120- let listener = ServerOptions :: new ( )
121- . first_pipe_instance ( true )
122- . create ( r"\\.\pipe\hello_world" )
123- . unwrap ( ) ;
124-
125- let name = get_pipe_name ( & listener)
126- . unwrap ( )
127- . to_string_lossy ( )
128- . to_string ( ) ;
129-
130- assert_eq ! ( name, r"\\.\pipe\hello_world" ) ;
131- }
0 commit comments