@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
import static com.sun.jna.platform.win32.WinBase.INVALID_HANDLE_VALUE ;
import static com.sun.jna.platform.win32.WinBase.STILL_ACTIVE ;
import static java.util.Objects.requireNonNull ;
@ -112,7 +113,7 @@ public class ProcessImplForWin32 extends Process {
// System-dependent portion of ProcessBuilderForWindows.start()
static Process start ( String username ,
String password ,
String cmdarray [ ] ,
String [ ] cmdarray ,
java . util . Map < String , String > environment ,
String dir ,
ProcessBuilderForWin32 . Redirect [ ] redirects ,
@ -177,10 +178,10 @@ public class ProcessImplForWin32 extends Process {
private static class LazyPattern {
// Escape-support version:
// "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
// "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)"
private static final Pattern PATTERN =
Pattern . compile ( "[^\\s\"]+|\"[^\"]*\"" ) ;
} ;
}
/ * Parses the command string parameter into the executable name and
* program arguments .
@ -203,7 +204,7 @@ public class ProcessImplForWin32 extends Process {
private static final int VERIFICATION_LEGACY = 3 ;
// See Command shell overview for documentation of special characters.
// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490954(v=technet.10)
private static final char ESCAPE_VERIFICATION [ ] [ ] = {
private static final char [ ] [ ] ESCAPE_VERIFICATION = {
// We guarantee the only command file execution for implicit [cmd.exe] run.
// http://technet.microsoft.com/en-us/library/bb490954.aspx
{ ' ' , '\t' , '<' , '>' , '&' , '|' , '^' } ,
@ -214,7 +215,7 @@ public class ProcessImplForWin32 extends Process {
private static String createCommandLine ( int verificationType ,
final String executablePath ,
final String cmd [ ] )
final String [ ] cmd )
{
StringBuilder cmdbuf = new StringBuilder ( 80 ) ;
@ -309,7 +310,7 @@ public class ProcessImplForWin32 extends Process {
}
if ( ! argIsQuoted ) {
char testEscape [ ] = ESCAPE_VERIFICATION [ verificationType ] ;
char [ ] testEscape = ESCAPE_VERIFICATION [ verificationType ] ;
for ( int i = 0 ; i < testEscape . length ; + + i ) {
if ( arg . indexOf ( testEscape [ i ] ) > = 0 ) {
return true ;
@ -390,14 +391,14 @@ public class ProcessImplForWin32 extends Process {
private static final char BACKSLASH = '\\' ;
private WinNT . HANDLE handle ;
private OutputStream stdin_s tream ;
private InputStream stdout_s tream ;
private InputStream stderr_s tream ;
private OutputStream stdinS tream ;
private InputStream stdoutS tream ;
private InputStream stderrS tream ;
private ProcessImplForWin32 (
String username ,
String password ,
String cmd [ ] ,
String [ ] cmd ,
final String envblock ,
final String path ,
final long [ ] stdHandles ,
@ -472,44 +473,44 @@ public class ProcessImplForWin32 extends Process {
new PrivilegedAction < Void > ( ) {
public Void run ( ) {
if ( stdHandles [ 0 ] = = - 1L )
stdin_s tream = ProcessBuilderForWin32 . NullOutputStream . INSTANCE ;
stdinS tream = ProcessBuilderForWin32 . NullOutputStream . INSTANCE ;
else {
FileDescriptor stdin_f d = new FileDescriptor ( ) ;
setHandle ( stdin_f d , stdHandles [ 0 ] ) ;
stdin_s tream = new BufferedOutputStream (
new FileOutputStream ( stdin_f d ) ) ;
FileDescriptor stdinF d = new FileDescriptor ( ) ;
setHandle ( stdinF d , stdHandles [ 0 ] ) ;
stdinS tream = new BufferedOutputStream (
new FileOutputStream ( stdinF d ) ) ;
}
if ( stdHandles [ 1 ] = = - 1L )
stdout_s tream = ProcessBuilderForWin32 . NullInputStream . INSTANCE ;
stdoutS tream = ProcessBuilderForWin32 . NullInputStream . INSTANCE ;
else {
FileDescriptor stdout_f d = new FileDescriptor ( ) ;
setHandle ( stdout_f d , stdHandles [ 1 ] ) ;
stdout_s tream = new BufferedInputStream (
new FileInputStream ( stdout_f d ) ) ;
FileDescriptor stdoutF d = new FileDescriptor ( ) ;
setHandle ( stdoutF d , stdHandles [ 1 ] ) ;
stdoutS tream = new BufferedInputStream (
new FileInputStream ( stdoutF d ) ) ;
}
if ( stdHandles [ 2 ] = = - 1L )
stderr_s tream = ProcessBuilderForWin32 . NullInputStream . INSTANCE ;
stderrS tream = ProcessBuilderForWin32 . NullInputStream . INSTANCE ;
else {
FileDescriptor stderr_f d = new FileDescriptor ( ) ;
setHandle ( stderr_f d , stdHandles [ 2 ] ) ;
stderr_s tream = new FileInputStream ( stderr_f d ) ;
FileDescriptor stderrF d = new FileDescriptor ( ) ;
setHandle ( stderrF d , stdHandles [ 2 ] ) ;
stderrS tream = new FileInputStream ( stderrF d ) ;
}
return null ; } } ) ;
}
public OutputStream getOutputStream ( ) {
return stdin_s tream ;
return stdinS tream ;
}
public InputStream getInputStream ( ) {
return stdout_s tream ;
return stdoutS tream ;
}
public InputStream getErrorStream ( ) {
return stderr_s tream ;
return stderrS tream ;
}
protected void finalize ( ) {
@ -557,11 +558,12 @@ public class ProcessImplForWin32 extends Process {
public void destroy ( ) { terminateProcess ( handle ) ; }
@Override
public Process destroyForcibly ( ) {
destroy ( ) ;
return this ;
}
@Override
public boolean isAlive ( ) {
return isProcessAlive ( handle ) ;
}
@ -582,7 +584,7 @@ public class ProcessImplForWin32 extends Process {
pjhandles . setValue ( thisProcessEnd ) ;
}
}
Kernel32 . INSTANCE . SetHandleInformation ( phStd . getValue ( ) , Kernel32 . HANDLE_FLAG_INHERIT , Kernel32 . HANDLE_FLAG_INHERIT ) ;
Kernel32 . INSTANCE . SetHandleInformation ( phStd . getValue ( ) , WinBase . HANDLE_FLAG_INHERIT , WinBase . HANDLE_FLAG_INHERIT ) ;
return true ;
}
@ -596,17 +598,17 @@ public class ProcessImplForWin32 extends Process {
private static void prepareIOEHandleState ( WinNT . HANDLE [ ] stdIOE , Boolean [ ] inherit ) {
for ( int i = 0 ; i < HANDLE_STORAGE_SIZE ; + + i ) {
WinNT . HANDLE hstd = stdIOE [ i ] ;
if ( ! Kernel32 . INVALID_HANDLE_VALUE . equals ( hstd ) ) {
if ( ! WinBase . INVALID_HANDLE_VALUE . equals ( hstd ) ) {
inherit [ i ] = Boolean . TRUE ;
Kernel32 . INSTANCE . SetHandleInformation ( hstd , Kernel32 . HANDLE_FLAG_INHERIT , 0 ) ;
Kernel32 . INSTANCE . SetHandleInformation ( hstd , WinBase . HANDLE_FLAG_INHERIT , 0 ) ;
}
}
}
private static void restoreIOEHandleState ( WinNT . HANDLE [ ] stdIOE , Boolean [ ] inherit ) {
for ( int i = HANDLE_STORAGE_SIZE - 1 ; i > = 0 ; - - i ) {
if ( ! Kernel32 . INVALID_HANDLE_VALUE . equals ( stdIOE [ i ] ) ) {
Kernel32 . INSTANCE . SetHandleInformation ( stdIOE [ i ] , Kernel32 . HANDLE_FLAG_INHERIT , inherit [ i ] ? Kernel32 . HANDLE_FLAG_INHERIT : 0 ) ;
if ( ! WinBase . INVALID_HANDLE_VALUE . equals ( stdIOE [ i ] ) ) {
Kernel32 . INSTANCE . SetHandleInformation ( stdIOE [ i ] , WinBase . HANDLE_FLAG_INHERIT , Boolean . TRUE . equals ( inherit [ i ] ) ? WinBase . HANDLE_FLAG_INHERIT : 0 ) ;
}
}
}
@ -621,12 +623,12 @@ public class ProcessImplForWin32 extends Process {
WinNT . HANDLE ret = new WinNT . HANDLE ( Pointer . createConstant ( 0 ) ) ;
WinNT . HANDLE [ ] stdIOE = new WinNT . HANDLE [ ] {
Kernel32 . INVALID_HANDLE_VALUE , Kernel32 . INVALID_HANDLE_VALUE , Kernel32 . INVALID_HANDLE_VALUE ,
WinBase . INVALID_HANDLE_VALUE , WinBase . INVALID_HANDLE_VALUE , WinBase . INVALID_HANDLE_VALUE ,
stdHandles [ 0 ] . getValue ( ) , stdHandles [ 1 ] . getValue ( ) , stdHandles [ 2 ] . getValue ( )
} ;
stdIOE [ 0 ] = Kernel32 . INSTANCE . GetStdHandle ( Kernel32 . STD_INPUT_HANDLE ) ;
stdIOE [ 1 ] = Kernel32 . INSTANCE . GetStdHandle ( Kernel32 . STD_OUTPUT_HANDLE ) ;
stdIOE [ 2 ] = Kernel32 . INSTANCE . GetStdHandle ( Kernel32 . STD_ERROR_HANDLE ) ;
stdIOE [ 0 ] = Kernel32 . INSTANCE . GetStdHandle ( Wincon . STD_INPUT_HANDLE ) ;
stdIOE [ 1 ] = Kernel32 . INSTANCE . GetStdHandle ( Wincon . STD_OUTPUT_HANDLE ) ;
stdIOE [ 2 ] = Kernel32 . INSTANCE . GetStdHandle ( Wincon . STD_ERROR_HANDLE ) ;
Boolean [ ] inherit = new Boolean [ ] {
Boolean . FALSE , Boolean . FALSE , Boolean . FALSE ,
@ -638,17 +640,17 @@ public class ProcessImplForWin32 extends Process {
// input
WinNT . HANDLEByReference hStdInput = new WinNT . HANDLEByReference ( ) ;
WinNT . HANDLEByReference [ ] pipeIn = new WinNT . HANDLEByReference [ ] {
new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) } ;
new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) } ;
// output
WinNT . HANDLEByReference hStdOutput = new WinNT . HANDLEByReference ( ) ;
WinNT . HANDLEByReference [ ] pipeOut = new WinNT . HANDLEByReference [ ] {
new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) } ;
new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) } ;
// error
WinNT . HANDLEByReference hStdError = new WinNT . HANDLEByReference ( ) ;
WinNT . HANDLEByReference [ ] pipeError = new WinNT . HANDLEByReference [ ] {
new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( Kernel32 . INVALID_HANDLE_VALUE ) } ;
new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) , new WinNT . HANDLEByReference ( WinBase . INVALID_HANDLE_VALUE ) } ;
boolean success ;
if ( initHolder ( stdHandles [ 0 ] , pipeIn , OFFSET_READ , hStdInput ) ) {
@ -668,8 +670,8 @@ public class ProcessImplForWin32 extends Process {
if ( success ) {
WTypes . LPSTR lpEnvironment = envblock = = null ? new WTypes . LPSTR ( ) : new WTypes . LPSTR ( envblock ) ;
Kernel32 . PROCESS_INFORMATION pi = new WinBase . PROCESS_INFORMATION ( ) ;
si . dwFlags = Kernel32 . STARTF_USESTDHANDLES ;
WinBase . PROCESS_INFORMATION pi = new WinBase . PROCESS_INFORMATION ( ) ;
si . dwFlags = WinBase . STARTF_USESTDHANDLES ;
if ( ! Advapi32 . INSTANCE . CreateProcessWithLogonW (
username
, null
@ -677,7 +679,7 @@ public class ProcessImplForWin32 extends Process {
, Advapi32 . LOGON_WITH_PROFILE
, null
, cmd
, Kernel32 . CREATE_NO_WINDOW
, WinBase . CREATE_NO_WINDOW
, lpEnvironment . getPointer ( )
, path
, si
@ -709,13 +711,11 @@ public class ProcessImplForWin32 extends Process {
for ( int i = 0 ; i < stdHandles . length ; i + + ) {
handles [ i ] = new WinNT . HANDLEByReference ( new WinNT . HANDLE ( Pointer . createConstant ( stdHandles [ i ] ) ) ) ;
}
if ( cmd ! = null ) {
if ( username ! = null & & password ! = null ) {
ret = processCreate ( username , password , cmd , envblock , path , handles , redirectErrorStream ) ;
}
if ( cmd ! = null & & username ! = null & & password ! = null ) {
ret = processCreate ( username , password , cmd , envblock , path , handles , redirectErrorStream ) ;
}
for ( int i = 0 ; i < stdHandles . length ; i + + ) {
stdHandles [ i ] = handles [ i ] . getPointer ( ) . getLong ( 0 ) ;
}
@ -742,7 +742,9 @@ public class ProcessImplForWin32 extends Process {
}
private static void closeHandle ( WinNT . HANDLE handle ) {
Kernel32Util . closeHandle ( handle ) ;
if ( ! handle . equals ( INVALID_HANDLE_VALUE ) ) {
Kernel32Util . closeHandle ( handle ) ;
}
}
/ * *
@ -753,15 +755,15 @@ public class ProcessImplForWin32 extends Process {
* @return the native HANDLE
* /
private static long openForAtomicAppend ( String path ) throws IOException {
int access = Kernel32 . GENERIC_READ | Kernel32 . GENERIC_WRITE ;
int sharing = Kernel32 . FILE_SHARE_READ | Kernel32 . FILE_SHARE_WRITE ;
int disposition = Kernel32 . OPEN_ALWAYS ;
int flagsAndAttributes = Kernel32 . FILE_ATTRIBUTE_NORMAL ;
int access = WinNT . GENERIC_READ | WinNT . GENERIC_WRITE ;
int sharing = WinNT . FILE_SHARE_READ | WinNT . FILE_SHARE_WRITE ;
int disposition = WinNT . OPEN_ALWAYS ;
int flagsAndAttributes = WinNT . FILE_ATTRIBUTE_NORMAL ;
if ( path = = null | | path . isEmpty ( ) ) {
return - 1 ;
} else {
WinNT . HANDLE handle = Kernel32 . INSTANCE . CreateFile ( path , access , sharing , null , disposition , flagsAndAttributes , null ) ;
if ( handle = = Kernel32 . INVALID_HANDLE_VALUE ) {
if ( handle = = WinBase . INVALID_HANDLE_VALUE ) {
throw new Win32Exception ( Kernel32 . INSTANCE . GetLastError ( ) ) ;
}
return handle . getPointer ( ) . getLong ( 0 ) ;
@ -769,15 +771,15 @@ public class ProcessImplForWin32 extends Process {
}
private static void waitForInterruptibly ( WinNT . HANDLE handle ) {
int result = Kernel32 . INSTANCE . WaitForMultipleObjects ( 1 , new WinNT . HANDLE [ ] { handle } , false , Kernel32 . INFINITE ) ;
if ( result = = Kernel32 . WAIT_FAILED ) {
int result = Kernel32 . INSTANCE . WaitForMultipleObjects ( 1 , new WinNT . HANDLE [ ] { handle } , false , WinBase . INFINITE ) ;
if ( result = = WinBase . WAIT_FAILED ) {
throw new Win32Exception ( Kernel32 . INSTANCE . GetLastError ( ) ) ;
}
}
private static void waitForTimeoutInterruptibly ( WinNT . HANDLE handle , long timeout ) {
int result = Kernel32 . INSTANCE . WaitForMultipleObjects ( 1 , new WinNT . HANDLE [ ] { handle } , false , ( int ) timeout ) ;
if ( result = = Kernel32 . WAIT_FAILED ) {
if ( result = = WinBase . WAIT_FAILED ) {
throw new Win32Exception ( Kernel32 . INSTANCE . GetLastError ( ) ) ;
}
}