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,
@@ -22,7 +25,7 @@ use winapi::{
22
25
minwinbase:: SECURITY_ATTRIBUTES ,
23
26
processthreadsapi:: {
24
27
CreateProcessW , DeleteProcThreadAttributeList , InitializeProcThreadAttributeList ,
25
- UpdateProcThreadAttribute , PROCESS_INFORMATION , PROC_THREAD_ATTRIBUTE_LIST ,
28
+ PROCESS_INFORMATION , PROC_THREAD_ATTRIBUTE_LIST ,
26
29
} ,
27
30
winbase:: {
28
31
CreateFileMappingA , CREATE_UNICODE_ENVIRONMENT , EXTENDED_STARTUPINFO_PRESENT ,
@@ -147,76 +150,22 @@ pub(in crate::windows) struct ChildParams {
147
150
// TODO: upstream to winapi: https://github.com/retep998/winapi-rs/pull/933/
148
151
const MAGIC_PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES : usize = 131081 ;
149
152
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
153
pub ( in crate :: windows) fn spawn (
177
154
sandbox : & WindowsSandbox ,
178
155
stdio : Stdio ,
179
156
params : ChildParams ,
180
157
) -> Result < PROCESS_INFORMATION , Error > {
181
- let proc_thread_attr_list_storage;
182
158
let mut security_capabilities;
159
+ let mut proc_thread_attr_list = AttrList :: new ( 1 ) ?;
183
160
let mut startup_info = unsafe {
184
161
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
- ) ) ?;
162
+
207
163
security_capabilities = sandbox. profile . get_security_capabilities ( ) ;
208
- Cvt :: nonzero ( UpdateProcThreadAttribute (
209
- startup_info. lpAttributeList ,
210
- // reserved
211
- 0 ,
164
+
165
+ proc_thread_attr_list. add_attr (
212
166
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
- ) ) ?;
167
+ & mut security_capabilities,
168
+ ) ?;
220
169
221
170
startup_info. StartupInfo . cb = size_of :: < STARTUPINFOEXW > ( ) as u32 ;
222
171
startup_info. StartupInfo . dwFlags = STARTF_USESTDHANDLES ;
@@ -229,21 +178,24 @@ pub(in crate::windows) fn spawn(
229
178
startup_info. StartupInfo . hStdInput = cvt_handle ( stdio. stdin ) ;
230
179
startup_info. StartupInfo . hStdOutput = cvt_handle ( stdio. stdout ) ;
231
180
startup_info. StartupInfo . hStdError = cvt_handle ( stdio. stderr ) ;
181
+
182
+ startup_info. lpAttributeList = proc_thread_attr_list. borrow_ptr ( ) ;
232
183
startup_info
233
184
} ;
234
185
let creation_flags = CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT ;
235
186
let mut info: PROCESS_INFORMATION = unsafe { std:: mem:: zeroed ( ) } ;
187
+ let application_name: Vec < u16 > = params. exe . encode_wide ( ) . collect ( ) ;
188
+ let mut cmd_line = application_name. clone ( ) ;
189
+ for arg in params. argv {
190
+ quote_arg ( & mut cmd_line, & arg) ;
191
+ }
192
+ let ( mut env, env_status) = encode_env ( & params. env ) ;
193
+ if let EncodeEnvResult :: Partial = env_status {
194
+ tracing:: warn!( "skipped zero chars in provided environment" ) ;
195
+ }
196
+ let cwd: Vec < u16 > = params. cwd . encode_wide ( ) . collect ( ) ;
197
+
236
198
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
199
Cvt :: nonzero ( CreateProcessW (
248
200
application_name. as_ptr ( ) ,
249
201
cmd_line. as_mut_ptr ( ) ,
@@ -259,7 +211,6 @@ pub(in crate::windows) fn spawn(
259
211
( & mut startup_info as * mut STARTUPINFOEXW ) . cast ( ) ,
260
212
& mut info,
261
213
) ) ?;
262
- DeleteProcThreadAttributeList ( startup_info. lpAttributeList ) ;
263
214
}
264
215
Ok ( info)
265
216
}
0 commit comments