@@ -1645,28 +1645,24 @@ impl AsRawHandle for NamedPipeClient {
1645
1645
}
1646
1646
}
1647
1647
1648
- // Helper to set a boolean flag as a bitfield.
1649
- macro_rules! bool_flag {
1650
- ( $f: expr, $t: expr, $flag: expr) => { {
1651
- let current = $f;
1652
-
1653
- if $t {
1654
- $f = current | $flag;
1655
- } else {
1656
- $f = current & !$flag;
1657
- } ;
1658
- } } ;
1659
- }
1660
-
1661
1648
/// A builder structure for construct a named pipe with named pipe-specific
1662
1649
/// options. This is required to use for named pipe servers who wants to modify
1663
1650
/// pipe-related options.
1664
1651
///
1665
1652
/// See [`ServerOptions::create`].
1666
1653
#[ derive( Debug , Clone ) ]
1667
1654
pub struct ServerOptions {
1668
- open_mode : u32 ,
1669
- pipe_mode : u32 ,
1655
+ // dwOpenMode
1656
+ access_inbound : bool ,
1657
+ access_outbound : bool ,
1658
+ first_pipe_instance : bool ,
1659
+ write_dac : bool ,
1660
+ write_owner : bool ,
1661
+ access_system_security : bool ,
1662
+ // dwPipeMode
1663
+ pipe_mode : PipeMode ,
1664
+ reject_remote_clients : bool ,
1665
+ // other options
1670
1666
max_instances : u32 ,
1671
1667
out_buffer_size : u32 ,
1672
1668
in_buffer_size : u32 ,
@@ -1687,8 +1683,14 @@ impl ServerOptions {
1687
1683
/// ```
1688
1684
pub fn new ( ) -> ServerOptions {
1689
1685
ServerOptions {
1690
- open_mode : windows_sys:: PIPE_ACCESS_DUPLEX | windows_sys:: FILE_FLAG_OVERLAPPED ,
1691
- pipe_mode : windows_sys:: PIPE_TYPE_BYTE | windows_sys:: PIPE_REJECT_REMOTE_CLIENTS ,
1686
+ access_inbound : true ,
1687
+ access_outbound : true ,
1688
+ first_pipe_instance : false ,
1689
+ write_dac : false ,
1690
+ write_owner : false ,
1691
+ access_system_security : false ,
1692
+ pipe_mode : PipeMode :: Byte ,
1693
+ reject_remote_clients : true ,
1692
1694
max_instances : windows_sys:: PIPE_UNLIMITED_INSTANCES ,
1693
1695
out_buffer_size : 65536 ,
1694
1696
in_buffer_size : 65536 ,
@@ -1705,14 +1707,7 @@ impl ServerOptions {
1705
1707
///
1706
1708
/// [`dwPipeMode`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
1707
1709
pub fn pipe_mode ( & mut self , pipe_mode : PipeMode ) -> & mut Self {
1708
- let is_msg = matches ! ( pipe_mode, PipeMode :: Message ) ;
1709
- // Pipe mode is implemented as a bit flag 0x4. Set is message and unset
1710
- // is byte.
1711
- bool_flag ! (
1712
- self . pipe_mode,
1713
- is_msg,
1714
- windows_sys:: PIPE_TYPE_MESSAGE | windows_sys:: PIPE_READMODE_MESSAGE
1715
- ) ;
1710
+ self . pipe_mode = pipe_mode;
1716
1711
self
1717
1712
}
1718
1713
@@ -1808,7 +1803,7 @@ impl ServerOptions {
1808
1803
/// # Ok(()) }
1809
1804
/// ```
1810
1805
pub fn access_inbound ( & mut self , allowed : bool ) -> & mut Self {
1811
- bool_flag ! ( self . open_mode , allowed , windows_sys :: PIPE_ACCESS_INBOUND ) ;
1806
+ self . access_inbound = allowed ;
1812
1807
self
1813
1808
}
1814
1809
@@ -1906,7 +1901,7 @@ impl ServerOptions {
1906
1901
/// # Ok(()) }
1907
1902
/// ```
1908
1903
pub fn access_outbound ( & mut self , allowed : bool ) -> & mut Self {
1909
- bool_flag ! ( self . open_mode , allowed , windows_sys :: PIPE_ACCESS_OUTBOUND ) ;
1904
+ self . access_outbound = allowed ;
1910
1905
self
1911
1906
}
1912
1907
@@ -1974,11 +1969,7 @@ impl ServerOptions {
1974
1969
/// [`create`]: ServerOptions::create
1975
1970
/// [`FILE_FLAG_FIRST_PIPE_INSTANCE`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea#pipe_first_pipe_instance
1976
1971
pub fn first_pipe_instance ( & mut self , first : bool ) -> & mut Self {
1977
- bool_flag ! (
1978
- self . open_mode,
1979
- first,
1980
- windows_sys:: FILE_FLAG_FIRST_PIPE_INSTANCE
1981
- ) ;
1972
+ self . first_pipe_instance = first;
1982
1973
self
1983
1974
}
1984
1975
@@ -2060,7 +2051,7 @@ impl ServerOptions {
2060
2051
///
2061
2052
/// [`WRITE_DAC`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
2062
2053
pub fn write_dac ( & mut self , requested : bool ) -> & mut Self {
2063
- bool_flag ! ( self . open_mode , requested , windows_sys :: WRITE_DAC ) ;
2054
+ self . write_dac = requested ;
2064
2055
self
2065
2056
}
2066
2057
@@ -2070,7 +2061,7 @@ impl ServerOptions {
2070
2061
///
2071
2062
/// [`WRITE_OWNER`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
2072
2063
pub fn write_owner ( & mut self , requested : bool ) -> & mut Self {
2073
- bool_flag ! ( self . open_mode , requested , windows_sys :: WRITE_OWNER ) ;
2064
+ self . write_owner = requested ;
2074
2065
self
2075
2066
}
2076
2067
@@ -2080,11 +2071,7 @@ impl ServerOptions {
2080
2071
///
2081
2072
/// [`ACCESS_SYSTEM_SECURITY`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
2082
2073
pub fn access_system_security ( & mut self , requested : bool ) -> & mut Self {
2083
- bool_flag ! (
2084
- self . open_mode,
2085
- requested,
2086
- windows_sys:: ACCESS_SYSTEM_SECURITY
2087
- ) ;
2074
+ self . access_system_security = requested;
2088
2075
self
2089
2076
}
2090
2077
@@ -2095,11 +2082,7 @@ impl ServerOptions {
2095
2082
///
2096
2083
/// [`PIPE_REJECT_REMOTE_CLIENTS`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea#pipe_reject_remote_clients
2097
2084
pub fn reject_remote_clients ( & mut self , reject : bool ) -> & mut Self {
2098
- bool_flag ! (
2099
- self . pipe_mode,
2100
- reject,
2101
- windows_sys:: PIPE_REJECT_REMOTE_CLIENTS
2102
- ) ;
2085
+ self . reject_remote_clients = reject;
2103
2086
self
2104
2087
}
2105
2088
@@ -2245,10 +2228,46 @@ impl ServerOptions {
2245
2228
) -> io:: Result < NamedPipeServer > {
2246
2229
let addr = encode_addr ( addr) ;
2247
2230
2231
+ let pipe_mode = {
2232
+ let mut mode = if matches ! ( self . pipe_mode, PipeMode :: Message ) {
2233
+ windows_sys:: PIPE_TYPE_MESSAGE | windows_sys:: PIPE_READMODE_MESSAGE
2234
+ } else {
2235
+ windows_sys:: PIPE_TYPE_BYTE | windows_sys:: PIPE_READMODE_BYTE
2236
+ } ;
2237
+ if self . reject_remote_clients {
2238
+ mode |= windows_sys:: PIPE_REJECT_REMOTE_CLIENTS ;
2239
+ } else {
2240
+ mode |= windows_sys:: PIPE_ACCEPT_REMOTE_CLIENTS ;
2241
+ }
2242
+ mode
2243
+ } ;
2244
+ let open_mode = {
2245
+ let mut mode = windows_sys:: FILE_FLAG_OVERLAPPED ;
2246
+ if self . access_inbound {
2247
+ mode |= windows_sys:: PIPE_ACCESS_INBOUND ;
2248
+ }
2249
+ if self . access_outbound {
2250
+ mode |= windows_sys:: PIPE_ACCESS_OUTBOUND ;
2251
+ }
2252
+ if self . first_pipe_instance {
2253
+ mode |= windows_sys:: FILE_FLAG_FIRST_PIPE_INSTANCE ;
2254
+ }
2255
+ if self . write_dac {
2256
+ mode |= windows_sys:: WRITE_DAC ;
2257
+ }
2258
+ if self . write_owner {
2259
+ mode |= windows_sys:: WRITE_OWNER ;
2260
+ }
2261
+ if self . access_system_security {
2262
+ mode |= windows_sys:: ACCESS_SYSTEM_SECURITY ;
2263
+ }
2264
+ mode
2265
+ } ;
2266
+
2248
2267
let h = windows_sys:: CreateNamedPipeW (
2249
2268
addr. as_ptr ( ) ,
2250
- self . open_mode ,
2251
- self . pipe_mode ,
2269
+ open_mode,
2270
+ pipe_mode,
2252
2271
self . max_instances ,
2253
2272
self . out_buffer_size ,
2254
2273
self . in_buffer_size ,
@@ -2270,7 +2289,8 @@ impl ServerOptions {
2270
2289
/// See [`ClientOptions::open`].
2271
2290
#[ derive( Debug , Clone ) ]
2272
2291
pub struct ClientOptions {
2273
- desired_access : u32 ,
2292
+ generic_read : bool ,
2293
+ generic_write : bool ,
2274
2294
security_qos_flags : u32 ,
2275
2295
pipe_mode : PipeMode ,
2276
2296
}
@@ -2291,7 +2311,8 @@ impl ClientOptions {
2291
2311
/// ```
2292
2312
pub fn new ( ) -> Self {
2293
2313
Self {
2294
- desired_access : windows_sys:: GENERIC_READ | windows_sys:: GENERIC_WRITE ,
2314
+ generic_read : true ,
2315
+ generic_write : true ,
2295
2316
security_qos_flags : windows_sys:: SECURITY_IDENTIFICATION
2296
2317
| windows_sys:: SECURITY_SQOS_PRESENT ,
2297
2318
pipe_mode : PipeMode :: Byte ,
@@ -2305,7 +2326,7 @@ impl ClientOptions {
2305
2326
/// [`GENERIC_READ`]: https://docs.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
2306
2327
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
2307
2328
pub fn read ( & mut self , allowed : bool ) -> & mut Self {
2308
- bool_flag ! ( self . desired_access , allowed , windows_sys :: GENERIC_READ ) ;
2329
+ self . generic_read = allowed ;
2309
2330
self
2310
2331
}
2311
2332
@@ -2316,7 +2337,7 @@ impl ClientOptions {
2316
2337
/// [`GENERIC_WRITE`]: https://docs.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
2317
2338
/// [`CreateFile`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
2318
2339
pub fn write ( & mut self , allowed : bool ) -> & mut Self {
2319
- bool_flag ! ( self . desired_access , allowed , windows_sys :: GENERIC_WRITE ) ;
2340
+ self . generic_write = allowed ;
2320
2341
self
2321
2342
}
2322
2343
@@ -2434,13 +2455,24 @@ impl ClientOptions {
2434
2455
) -> io:: Result < NamedPipeClient > {
2435
2456
let addr = encode_addr ( addr) ;
2436
2457
2458
+ let desired_access = {
2459
+ let mut access = 0 ;
2460
+ if self . generic_read {
2461
+ access |= windows_sys:: GENERIC_READ ;
2462
+ }
2463
+ if self . generic_write {
2464
+ access |= windows_sys:: GENERIC_WRITE ;
2465
+ }
2466
+ access
2467
+ } ;
2468
+
2437
2469
// NB: We could use a platform specialized `OpenOptions` here, but since
2438
2470
// we have access to windows_sys it ultimately doesn't hurt to use
2439
2471
// `CreateFile` explicitly since it allows the use of our already
2440
2472
// well-structured wide `addr` to pass into CreateFileW.
2441
2473
let h = windows_sys:: CreateFileW (
2442
2474
addr. as_ptr ( ) ,
2443
- self . desired_access ,
2475
+ desired_access,
2444
2476
0 ,
2445
2477
attrs as * mut _ ,
2446
2478
windows_sys:: OPEN_EXISTING ,
@@ -2453,13 +2485,9 @@ impl ClientOptions {
2453
2485
}
2454
2486
2455
2487
if matches ! ( self . pipe_mode, PipeMode :: Message ) {
2456
- let mut mode = windows_sys:: PIPE_READMODE_MESSAGE ;
2457
- let result = windows_sys:: SetNamedPipeHandleState (
2458
- h,
2459
- & mut mode,
2460
- ptr:: null_mut ( ) ,
2461
- ptr:: null_mut ( ) ,
2462
- ) ;
2488
+ let mode = windows_sys:: PIPE_READMODE_MESSAGE ;
2489
+ let result =
2490
+ windows_sys:: SetNamedPipeHandleState ( h, & mode, ptr:: null_mut ( ) , ptr:: null_mut ( ) ) ;
2463
2491
2464
2492
if result == 0 {
2465
2493
return Err ( io:: Error :: last_os_error ( ) ) ;
@@ -2582,53 +2610,3 @@ unsafe fn named_pipe_info(handle: RawHandle) -> io::Result<PipeInfo> {
2582
2610
max_instances,
2583
2611
} )
2584
2612
}
2585
-
2586
- #[ cfg( test) ]
2587
- mod test {
2588
- use self :: windows_sys:: {
2589
- PIPE_READMODE_MESSAGE , PIPE_REJECT_REMOTE_CLIENTS , PIPE_TYPE_BYTE , PIPE_TYPE_MESSAGE ,
2590
- } ;
2591
- use super :: * ;
2592
-
2593
- #[ test]
2594
- fn opts_default_pipe_mode ( ) {
2595
- let opts = ServerOptions :: new ( ) ;
2596
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS ) ;
2597
- }
2598
-
2599
- #[ test]
2600
- fn opts_unset_reject_remote ( ) {
2601
- let mut opts = ServerOptions :: new ( ) ;
2602
- opts. reject_remote_clients ( false ) ;
2603
- assert_eq ! ( opts. pipe_mode & PIPE_REJECT_REMOTE_CLIENTS , 0 ) ;
2604
- }
2605
-
2606
- #[ test]
2607
- fn opts_set_pipe_mode_maintains_reject_remote_clients ( ) {
2608
- let mut opts = ServerOptions :: new ( ) ;
2609
- opts. pipe_mode ( PipeMode :: Byte ) ;
2610
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS ) ;
2611
-
2612
- opts. reject_remote_clients ( false ) ;
2613
- opts. pipe_mode ( PipeMode :: Byte ) ;
2614
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_BYTE ) ;
2615
-
2616
- opts. reject_remote_clients ( true ) ;
2617
- opts. pipe_mode ( PipeMode :: Byte ) ;
2618
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS ) ;
2619
-
2620
- opts. reject_remote_clients ( false ) ;
2621
- opts. pipe_mode ( PipeMode :: Message ) ;
2622
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE ) ;
2623
-
2624
- opts. reject_remote_clients ( true ) ;
2625
- opts. pipe_mode ( PipeMode :: Message ) ;
2626
- assert_eq ! (
2627
- opts. pipe_mode,
2628
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS
2629
- ) ;
2630
-
2631
- opts. pipe_mode ( PipeMode :: Byte ) ;
2632
- assert_eq ! ( opts. pipe_mode, PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS ) ;
2633
- }
2634
- }
0 commit comments