@@ -13,6 +13,7 @@ use windows::Win32::Foundation::{
1313 CloseHandle , GetLastError , ERROR_SUCCESS , ERROR_WMI_INSTANCE_NOT_FOUND , HANDLE ,
1414 INVALID_HANDLE_VALUE , WIN32_ERROR ,
1515} ;
16+ use windows:: Win32 :: Security :: SE_SYSTEM_PROFILE_NAME ;
1617use windows:: Win32 :: Security :: {
1718 AdjustTokenPrivileges , LookupPrivilegeValueW , SE_PRIVILEGE_ENABLED , TOKEN_ADJUST_PRIVILEGES ,
1819 TOKEN_PRIVILEGES ,
@@ -30,7 +31,6 @@ use windows::Win32::System::Diagnostics::Etw::{
3031 WNODE_FLAG_TRACED_GUID ,
3132} ;
3233use windows:: Win32 :: System :: SystemInformation :: { GetVersionExA , OSVERSIONINFOA } ;
33- use windows:: Win32 :: System :: SystemServices :: SE_SYSTEM_PROFILE_NAME ;
3434use windows:: Win32 :: System :: Threading :: {
3535 GetCurrentProcess , GetCurrentThread , OpenProcess , OpenProcessToken , SetThreadPriority ,
3636 WaitForSingleObject , CREATE_SUSPENDED , PROCESS_ALL_ACCESS , THREAD_PRIORITY_TIME_CRITICAL ,
@@ -88,9 +88,12 @@ impl Drop for TraceContext {
8888 fn drop ( & mut self ) {
8989 // SAFETY: TraceContext invariants ensure these are valid
9090 unsafe {
91- let ret = CloseHandle ( self . target_process_handle ) ;
92- if ret. 0 == 0 {
93- panic ! ( "TraceContext::CloseHandle error:{:?}" , get_last_error( "" ) ) ;
91+ if let Err ( error) = CloseHandle ( self . target_process_handle ) {
92+ panic ! (
93+ "TraceContext::CloseHandle error: {:?} ({})" ,
94+ error. message( ) ,
95+ error. code( )
96+ ) ;
9497 }
9598 }
9699 }
@@ -112,43 +115,27 @@ pub enum Error {
112115 /// Error waiting for child, timed out
113116 WaitOnChildErrTimeout ,
114117 /// A call to a windows API function returned an error and we didn't know how to handle it
115- Other ( WIN32_ERROR , String , & ' static str ) ,
118+ Other ( windows_core :: Error ) ,
116119 /// We require Windows 7 or greater
117120 UnsupportedOsVersion ,
118121 /// This should never happen
119122 UnknownError ,
120123}
124+
121125type Result < T > = std:: result:: Result < T , Error > ;
126+
127+ impl From < windows_core:: Error > for Error {
128+ fn from ( err : windows_core:: Error ) -> Self {
129+ Error :: Other ( err)
130+ }
131+ }
132+
122133impl From < std:: io:: Error > for Error {
123134 fn from ( err : std:: io:: Error ) -> Self {
124135 Error :: Write ( err)
125136 }
126137}
127138
128- fn get_last_error ( extra : & ' static str ) -> Error {
129- const BUF_LEN : usize = 1024 ;
130- let mut buf = [ 0u8 ; BUF_LEN ] ;
131- let code = unsafe { GetLastError ( ) } ;
132- let chars_written = unsafe {
133- FormatMessageA (
134- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS ,
135- None ,
136- code. 0 ,
137- 0 ,
138- PSTR ( buf. as_mut_ptr ( ) ) ,
139- BUF_LEN as u32 ,
140- None ,
141- )
142- } ;
143- assert ! ( chars_written != 0 ) ;
144- let code_str = unsafe {
145- std:: ffi:: CStr :: from_ptr ( buf. as_ptr ( ) . cast ( ) )
146- . to_str ( )
147- . unwrap_or ( "Invalid utf8 in error" )
148- } ;
149- Error :: Other ( code, code_str. to_string ( ) , extra)
150- }
151-
152139/// A wrapper around `OpenProcess` that returns a handle with all access rights
153140unsafe fn handle_from_process_id ( process_id : u32 ) -> Result < HANDLE > {
154141 match OpenProcess ( PROCESS_ALL_ACCESS , false , process_id) {
@@ -171,33 +158,24 @@ fn acquire_privileges() -> Result<()> {
171158 let mut privs = TOKEN_PRIVILEGES :: default ( ) ;
172159 privs. PrivilegeCount = 1 ;
173160 privs. Privileges [ 0 ] . Attributes = SE_PRIVILEGE_ENABLED ;
174- if unsafe {
175- LookupPrivilegeValueW ( None , SE_SYSTEM_PROFILE_NAME , & mut privs. Privileges [ 0 ] . Luid ) . 0 == 0
176- } {
177- return Err ( get_last_error ( "acquire_privileges LookupPrivilegeValueA" ) ) ;
178- }
161+ unsafe { LookupPrivilegeValueW ( None , SE_SYSTEM_PROFILE_NAME , & mut privs. Privileges [ 0 ] . Luid ) } ?;
179162 let mut pt = HANDLE :: default ( ) ;
180- if unsafe { OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ADJUST_PRIVILEGES , & mut pt) . 0 == 0 } {
181- return Err ( get_last_error ( "OpenProcessToken" ) ) ;
182- }
163+ unsafe { OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ADJUST_PRIVILEGES , & mut pt) } ?;
183164 let adjust = unsafe { AdjustTokenPrivileges ( pt, false , Some ( addr_of ! ( privs) ) , 0 , None , None ) } ;
184- if adjust. 0 == 0 {
185- let err = Err ( get_last_error ( "AdjustTokenPrivileges" ) ) ;
165+ if let Err ( err) = adjust {
186166 unsafe {
187167 CloseHandle ( pt) ;
188168 }
189- return err;
190- }
191- let ret = unsafe { CloseHandle ( pt) } ;
192- if ret. 0 == 0 {
193- return Err ( get_last_error ( "acquire_privileges CloseHandle" ) ) ;
169+ return Err ( err) ;
194170 }
171+ let ret = unsafe { CloseHandle ( pt) } ?;
195172 let status = unsafe { GetLastError ( ) } ;
196173 if status != ERROR_SUCCESS {
197174 return Err ( Error :: NotAnAdmin ) ;
198175 }
199176 Ok ( ( ) )
200177}
178+
201179/// SAFETY: is_suspended must only be true if `target_process` is suspended
202180unsafe fn trace_from_process_id (
203181 target_process_id : u32 ,
@@ -206,10 +184,8 @@ unsafe fn trace_from_process_id(
206184) -> Result < TraceContext > {
207185 let mut winver_info = OSVERSIONINFOA :: default ( ) ;
208186 winver_info. dwOSVersionInfoSize = size_of :: < OSVERSIONINFOA > ( ) as u32 ;
209- let ret = GetVersionExA ( & mut winver_info) ;
210- if ret. 0 == 0 {
211- return Err ( get_last_error ( "TraceSetInformation interval" ) ) ;
212- }
187+ GetVersionExA ( & mut winver_info) ?;
188+
213189 // If we're not win7 or more, return unsupported
214190 // https://docs.microsoft.com/en-us/windows/win32/sysinfo/operating-system-version
215191 if winver_info. dwMajorVersion < 6
@@ -228,7 +204,7 @@ unsafe fn trace_from_process_id(
228204 // TODO: Parameter?
229205 interval. Interval = ( 1000000000 / 8000 ) / 100 ;
230206 let ret = TraceSetInformation (
231- None ,
207+ CONTROLTRACE_HANDLE :: default ( ) ,
232208 // The value is supported on Windows 8, Windows Server 2012, and later.
233209 TraceSampledProfileIntervalInfo ,
234210 addr_of ! ( interval) . cast ( ) ,
@@ -298,7 +274,7 @@ unsafe fn trace_from_process_id(
298274 {
299275 let mut event_trace_props_copy = event_trace_props. clone ( ) ;
300276 let control_stop_retcode = ControlTraceA (
301- None ,
277+ CONTROLTRACE_HANDLE :: default ( ) ,
302278 kernel_logger_name_with_nul_pcstr,
303279 addr_of_mut ! ( event_trace_props_copy) as * mut _ ,
304280 EVENT_TRACE_CONTROL_STOP ,
@@ -484,7 +460,7 @@ unsafe fn trace_from_process_id(
484460 log. Anonymous2 . EventRecordCallback = Some ( event_record_callback) ;
485461
486462 let trace_processing_handle = OpenTraceA ( & mut log) ;
487- if trace_processing_handle. 0 == INVALID_HANDLE_VALUE . 0 as u64 {
463+ if trace_processing_handle == INVALID_HANDLE_VALUE {
488464 return Err ( get_last_error ( "OpenTraceA processing" ) ) ;
489465 }
490466
0 commit comments