@@ -44,11 +44,11 @@ internal sealed class TrustedInstaller
4444
4545 [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
4646 [ return : MarshalAs ( UnmanagedType . Bool ) ]
47- private static extern bool UpdateProcThreadAttribute ( IntPtr lpAttributeList , uint dwFlags , IntPtr Attribute , IntPtr lpValue , IntPtr cbSize , IntPtr lpPreviousValue , IntPtr lpReturnSize ) ;
47+ private static extern bool UpdateProcThreadAttribute ( IntPtr lpAttributeList , uint dwFlags , IntPtr Attribute , IntPtr lpValue , UIntPtr cbSize , IntPtr lpPreviousValue , IntPtr lpReturnSize ) ;
4848
4949 [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
5050 [ return : MarshalAs ( UnmanagedType . Bool ) ]
51- private static extern bool InitializeProcThreadAttributeList ( IntPtr lpAttributeList , int dwAttributeCount , int dwFlags , ref IntPtr lpSize ) ;
51+ private static extern bool InitializeProcThreadAttributeList ( IntPtr lpAttributeList , int dwAttributeCount , int dwFlags , ref UIntPtr lpSize ) ;
5252
5353 [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
5454 private static extern void DeleteProcThreadAttributeList ( IntPtr lpAttributeList ) ;
@@ -63,7 +63,7 @@ internal sealed class TrustedInstaller
6363 private const int SC_STATUS_PROCESS_INFO = 0 ;
6464 private const string ServicesActiveDatabase = "ServicesActive" ;
6565
66- private const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000 ;
66+ private const uint PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000 ;
6767 private const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000 ;
6868
6969 [ StructLayout ( LayoutKind . Sequential ) ]
@@ -244,15 +244,18 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
244244 Exception lastException = null ;
245245 bool impersonated = false ;
246246
247+ UIntPtr lpSize = UIntPtr . Zero ;
248+ InitializeProcThreadAttributeList ( IntPtr . Zero , 1 , 0 , ref lpSize ) ;
249+ if ( lpSize == UIntPtr . Zero )
250+ {
251+ throw new Win32Exception ( "InitializeProcThreadAttributeList returned zero size" ) ;
252+ }
253+
247254 for ( int attempt = 0 ; attempt < 3 ; attempt ++ )
248255 {
249- STARTUPINFOEX siEx = new STARTUPINFOEX ( ) ;
250- IntPtr lpSize = IntPtr . Zero ;
251256 IntPtr lpValueProc = IntPtr . Zero ;
252257 IntPtr parentHandle = IntPtr . Zero ;
253-
254- InitializeProcThreadAttributeList ( IntPtr . Zero , 1 , 0 , ref lpSize ) ;
255- siEx . lpAttributeList = Marshal . AllocHGlobal ( lpSize ) ;
258+ IntPtr attributeList = IntPtr . Zero ;
256259
257260 try
258261 {
@@ -266,12 +269,15 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
266269 throw new Win32Exception ( "Failed to impersonate SYSTEM identity" ) ;
267270 }
268271
269- if ( ! InitializeProcThreadAttributeList ( siEx . lpAttributeList , 1 , 0 , ref lpSize ) )
272+ attributeList = Marshal . AllocHGlobal ( ( IntPtr ) ( long ) lpSize ) ;
273+
274+ if ( ! InitializeProcThreadAttributeList ( attributeList , 1 , 0 , ref lpSize ) )
270275 {
271276 throw new Win32Exception ( Marshal . GetLastWin32Error ( ) ) ;
272277 }
273278
274- parentHandle = OpenProcess ( ProcessAccessFlags . CreateProcess | ProcessAccessFlags . DuplicateHandle , false , parentProcessId ) ;
279+ parentHandle = OpenProcess ( ProcessAccessFlags . CreateProcess | ProcessAccessFlags . DuplicateHandle | ProcessAccessFlags . Synchronize , false , parentProcessId ) ;
280+
275281 if ( parentHandle == IntPtr . Zero )
276282 {
277283 throw new Win32Exception ( Marshal . GetLastWin32Error ( ) ) ;
@@ -280,22 +286,19 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
280286 lpValueProc = Marshal . AllocHGlobal ( IntPtr . Size ) ;
281287 Marshal . WriteIntPtr ( lpValueProc , parentHandle ) ;
282288
283- if ( ! UpdateProcThreadAttribute ( siEx . lpAttributeList , 0 , ( IntPtr ) PROC_THREAD_ATTRIBUTE_PARENT_PROCESS , lpValueProc , ( IntPtr ) IntPtr . Size , IntPtr . Zero , IntPtr . Zero ) )
289+ if ( ! UpdateProcThreadAttribute ( attributeList , 0 , new IntPtr ( unchecked ( PROC_THREAD_ATTRIBUTE_PARENT_PROCESS ) ) , lpValueProc , new UIntPtr ( ( uint ) IntPtr . Size ) , IntPtr . Zero , IntPtr . Zero ) )
284290 {
285291 throw new Win32Exception ( Marshal . GetLastWin32Error ( ) ) ;
286292 }
287293
288- SECURITY_ATTRIBUTES ps = new SECURITY_ATTRIBUTES ( ) ;
289- SECURITY_ATTRIBUTES ts = new SECURITY_ATTRIBUTES ( ) ;
290- ps . nLength = Marshal . SizeOf ( ps ) ;
291- ts . nLength = Marshal . SizeOf ( ts ) ;
294+ STARTUPINFOEX siEx = new STARTUPINFOEX ( ) ;
295+ siEx . StartupInfo . cb = Marshal . SizeOf ( typeof ( STARTUPINFOEX ) ) ;
296+ siEx . StartupInfo . dwFlags = 0x00000001 ;
297+ siEx . StartupInfo . wShowWindow = showWindow ? ( short ) 5 : ( short ) 0 ;
298+ siEx . lpAttributeList = attributeList ;
292299
293- siEx . StartupInfo = new STARTUPINFO
294- {
295- cb = Marshal . SizeOf ( typeof ( STARTUPINFO ) ) ,
296- dwFlags = 0x00000001 ,
297- wShowWindow = showWindow ? ( short ) 5 : ( short ) 0
298- } ;
300+ SECURITY_ATTRIBUTES ps = new SECURITY_ATTRIBUTES { nLength = Marshal . SizeOf ( typeof ( SECURITY_ATTRIBUTES ) ) } ;
301+ SECURITY_ATTRIBUTES ts = new SECURITY_ATTRIBUTES { nLength = Marshal . SizeOf ( typeof ( SECURITY_ATTRIBUTES ) ) } ;
299302
300303 if ( ! CreateProcess ( null , binaryPath , ref ps , ref ts , true , EXTENDED_STARTUPINFO_PRESENT , IntPtr . Zero , null , ref siEx , out PROCESS_INFORMATION pInfo ) )
301304 {
@@ -322,10 +325,10 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
322325 CloseHandle ( parentHandle ) ;
323326 }
324327
325- if ( siEx . lpAttributeList != IntPtr . Zero )
328+ if ( attributeList != IntPtr . Zero )
326329 {
327- DeleteProcThreadAttributeList ( siEx . lpAttributeList ) ;
328- Marshal . FreeHGlobal ( siEx . lpAttributeList ) ;
330+ DeleteProcThreadAttributeList ( attributeList ) ;
331+ Marshal . FreeHGlobal ( attributeList ) ;
329332 }
330333 }
331334 }
0 commit comments