1
+ mod attr_list;
2
+
1
3
use crate :: {
2
4
windows:: {
3
5
pipe:: { self , ReadPipe , WritePipe } ,
@@ -6,6 +8,7 @@ use crate::{
6
8
} ,
7
9
InputSpecificationData , OutputSpecificationData ,
8
10
} ;
11
+ use attr_list:: AttrList ;
9
12
use std:: {
10
13
ffi:: { OsStr , OsString } ,
11
14
mem:: size_of,
@@ -15,15 +18,10 @@ use std::{
15
18
} ,
16
19
} ;
17
20
use winapi:: {
18
- shared:: { minwindef:: TRUE , winerror :: ERROR_INSUFFICIENT_BUFFER } ,
21
+ shared:: minwindef:: TRUE ,
19
22
um:: {
20
- errhandlingapi:: GetLastError ,
21
23
handleapi:: INVALID_HANDLE_VALUE ,
22
- minwinbase:: SECURITY_ATTRIBUTES ,
23
- processthreadsapi:: {
24
- CreateProcessW , DeleteProcThreadAttributeList , InitializeProcThreadAttributeList ,
25
- UpdateProcThreadAttribute , PROCESS_INFORMATION , PROC_THREAD_ATTRIBUTE_LIST ,
26
- } ,
24
+ processthreadsapi:: { CreateProcessW , PROCESS_INFORMATION } ,
27
25
winbase:: {
28
26
CreateFileMappingA , CREATE_UNICODE_ENVIRONMENT , EXTENDED_STARTUPINFO_PRESENT ,
29
27
STARTF_USESTDHANDLES , STARTUPINFOEXW ,
@@ -147,76 +145,22 @@ pub(in crate::windows) struct ChildParams {
147
145
// TODO: upstream to winapi: https://github.com/retep998/winapi-rs/pull/933/
148
146
const MAGIC_PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES : usize = 131081 ;
149
147
150
- struct AlignedMemBlock ( * mut u8 , usize ) ;
151
-
152
- impl AlignedMemBlock {
153
- fn layout ( cnt : usize ) -> std:: alloc:: Layout {
154
- assert ! ( cnt > 0 ) ;
155
- std:: alloc:: Layout :: from_size_align ( cnt, 8 ) . unwrap ( )
156
- }
157
-
158
- fn new ( cnt : usize ) -> AlignedMemBlock {
159
- let ptr = unsafe { std:: alloc:: alloc_zeroed ( Self :: layout ( cnt) ) } ;
160
- AlignedMemBlock ( ptr, cnt)
161
- }
162
-
163
- fn ptr ( & self ) -> * mut u8 {
164
- self . 0
165
- }
166
- }
167
-
168
- impl Drop for AlignedMemBlock {
169
- fn drop ( & mut self ) {
170
- unsafe {
171
- std:: alloc:: dealloc ( self . 0 , Self :: layout ( self . 1 ) ) ;
172
- }
173
- }
174
- }
175
-
176
148
pub ( in crate :: windows) fn spawn (
177
149
sandbox : & WindowsSandbox ,
178
150
stdio : Stdio ,
179
151
params : ChildParams ,
180
152
) -> Result < PROCESS_INFORMATION , Error > {
181
- let proc_thread_attr_list_storage;
182
153
let mut security_capabilities;
154
+ let mut proc_thread_attr_list = AttrList :: new ( 1 ) ?;
183
155
let mut startup_info = unsafe {
184
156
let mut startup_info: STARTUPINFOEXW = std:: mem:: zeroed ( ) ;
185
- let mut proc_thread_attr_list_len = 0 ;
186
- {
187
- InitializeProcThreadAttributeList (
188
- std:: ptr:: null_mut ( ) ,
189
- // we need only one attribute: security capabilities.
190
- 1 ,
191
- 0 ,
192
- & mut proc_thread_attr_list_len,
193
- ) ;
194
- if GetLastError ( ) != ERROR_INSUFFICIENT_BUFFER {
195
- return Err ( Error :: last ( ) ) ;
196
- }
197
- }
198
- proc_thread_attr_list_storage = AlignedMemBlock :: new ( proc_thread_attr_list_len) ;
199
- let proc_thread_attr_list = proc_thread_attr_list_storage. ptr ( ) ;
200
- startup_info. lpAttributeList = proc_thread_attr_list. cast ( ) ;
201
- Cvt :: nonzero ( InitializeProcThreadAttributeList (
202
- startup_info. lpAttributeList ,
203
- 1 ,
204
- 0 ,
205
- & mut proc_thread_attr_list_len,
206
- ) ) ?;
157
+
207
158
security_capabilities = sandbox. profile . get_security_capabilities ( ) ;
208
- Cvt :: nonzero ( UpdateProcThreadAttribute (
209
- startup_info. lpAttributeList ,
210
- // reserved
211
- 0 ,
159
+
160
+ proc_thread_attr_list. add_attr :: < SECURITY_CAPABILITIES > (
212
161
MAGIC_PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES ,
213
- ( & mut security_capabilities as * mut SECURITY_CAPABILITIES ) . cast ( ) ,
214
- std:: mem:: size_of :: < SECURITY_ATTRIBUTES > ( ) ,
215
- // reserved
216
- std:: ptr:: null_mut ( ) ,
217
- // reserved
218
- std:: ptr:: null_mut ( ) ,
219
- ) ) ?;
162
+ & mut security_capabilities,
163
+ ) ?;
220
164
221
165
startup_info. StartupInfo . cb = size_of :: < STARTUPINFOEXW > ( ) as u32 ;
222
166
startup_info. StartupInfo . dwFlags = STARTF_USESTDHANDLES ;
@@ -229,21 +173,24 @@ pub(in crate::windows) fn spawn(
229
173
startup_info. StartupInfo . hStdInput = cvt_handle ( stdio. stdin ) ;
230
174
startup_info. StartupInfo . hStdOutput = cvt_handle ( stdio. stdout ) ;
231
175
startup_info. StartupInfo . hStdError = cvt_handle ( stdio. stderr ) ;
176
+
177
+ startup_info. lpAttributeList = proc_thread_attr_list. borrow_ptr ( ) ;
232
178
startup_info
233
179
} ;
234
180
let creation_flags = CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT ;
235
181
let mut info: PROCESS_INFORMATION = unsafe { std:: mem:: zeroed ( ) } ;
182
+ let application_name: Vec < u16 > = params. exe . encode_wide ( ) . collect ( ) ;
183
+ let mut cmd_line = application_name. clone ( ) ;
184
+ for arg in params. argv {
185
+ quote_arg ( & mut cmd_line, & arg) ;
186
+ }
187
+ let ( mut env, env_status) = encode_env ( & params. env ) ;
188
+ if let EncodeEnvResult :: Partial = env_status {
189
+ tracing:: warn!( "skipped zero chars in provided environment" ) ;
190
+ }
191
+ let cwd: Vec < u16 > = params. cwd . encode_wide ( ) . collect ( ) ;
192
+
236
193
unsafe {
237
- let application_name: Vec < u16 > = params. exe . encode_wide ( ) . collect ( ) ;
238
- let mut cmd_line = application_name. clone ( ) ;
239
- for arg in params. argv {
240
- quote_arg ( & mut cmd_line, & arg) ;
241
- }
242
- let ( mut env, env_status) = encode_env ( & params. env ) ;
243
- if let EncodeEnvResult :: Partial = env_status {
244
- tracing:: warn!( "skipped zero chars in provided environment" ) ;
245
- }
246
- let cwd: Vec < u16 > = params. cwd . encode_wide ( ) . collect ( ) ;
247
194
Cvt :: nonzero ( CreateProcessW (
248
195
application_name. as_ptr ( ) ,
249
196
cmd_line. as_mut_ptr ( ) ,
@@ -259,7 +206,6 @@ pub(in crate::windows) fn spawn(
259
206
( & mut startup_info as * mut STARTUPINFOEXW ) . cast ( ) ,
260
207
& mut info,
261
208
) ) ?;
262
- DeleteProcThreadAttributeList ( startup_info. lpAttributeList ) ;
263
209
}
264
210
Ok ( info)
265
211
}
0 commit comments