1
1
/*
2
- * Copyright (c) 2019, 2024 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2019, 2025 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -56,36 +56,56 @@ public enum WixTool {
56
56
this .minimalVersion = minimalVersion ;
57
57
}
58
58
59
- static final class ToolInfo {
59
+ interface ToolInfo {
60
+ Path path ();
61
+ DottedVersion version ();
62
+ }
63
+
64
+ interface CandleInfo extends ToolInfo {
65
+ boolean fips ();
66
+ }
60
67
61
- ToolInfo (Path path , String version ) {
62
- this .path = path ;
63
- this .version = DottedVersion .lazy (version );
68
+ private record DefaultToolInfo (Path path , DottedVersion version ) implements ToolInfo {
69
+ DefaultToolInfo {
70
+ Objects .requireNonNull (path );
71
+ Objects .requireNonNull (version );
64
72
}
65
73
66
- final Path path ;
67
- final DottedVersion version ;
74
+ DefaultToolInfo (Path path , String version ) {
75
+ this (path , DottedVersion .lazy (version ));
76
+ }
77
+ }
78
+
79
+ private record DefaultCandleInfo (Path path , DottedVersion version , boolean fips ) implements CandleInfo {
80
+ DefaultCandleInfo {
81
+ Objects .requireNonNull (path );
82
+ Objects .requireNonNull (version );
83
+ }
84
+
85
+ DefaultCandleInfo (ToolInfo info , boolean fips ) {
86
+ this (info .path (), info .version (), fips );
87
+ }
68
88
}
69
89
70
90
static WixToolset createToolset () throws ConfigException {
71
91
Function <List <ToolLookupResult >, Map <WixTool , ToolInfo >> conv = lookupResults -> {
72
92
return lookupResults .stream ().filter (ToolLookupResult ::isValid ).collect (Collectors .
73
93
groupingBy (lookupResult -> {
74
- return lookupResult .getInfo ().version .toString ();
94
+ return lookupResult .info ().version () .toString ();
75
95
})).values ().stream ().filter (sameVersionLookupResults -> {
76
96
Set <WixTool > sameVersionTools = sameVersionLookupResults .stream ().map (
77
- ToolLookupResult ::getTool ).collect (Collectors .toSet ());
97
+ ToolLookupResult ::tool ).collect (Collectors .toSet ());
78
98
if (sameVersionTools .equals (Set .of (Candle3 )) || sameVersionTools .equals (Set .of (
79
99
Light3 ))) {
80
100
// There is only one tool from WiX v3 toolset of some version available. Discard it.
81
101
return false ;
82
102
} else {
83
103
return true ;
84
104
}
85
- }).flatMap (List ::stream ).collect (Collectors .toMap (ToolLookupResult ::getTool ,
86
- ToolLookupResult ::getInfo , (ToolInfo x , ToolInfo y ) -> {
105
+ }).flatMap (List ::stream ).collect (Collectors .toMap (ToolLookupResult ::tool ,
106
+ ToolLookupResult ::info , (ToolInfo x , ToolInfo y ) -> {
87
107
return Stream .of (x , y ).sorted (Comparator .comparing ((ToolInfo toolInfo ) -> {
88
- return toolInfo .version .toComponentsString ();
108
+ return toolInfo .version () .toComponentsString ();
89
109
}).reversed ()).findFirst ().get ();
90
110
}));
91
111
};
@@ -99,8 +119,8 @@ static WixToolset createToolset() throws ConfigException {
99
119
};
100
120
101
121
var toolsInPath = Stream .of (values ()).map (tool -> {
102
- return new ToolLookupResult (tool , null );
103
- }).toList ();
122
+ return ToolLookupResult . lookup (tool , Optional . empty () );
123
+ }).filter ( Optional :: isPresent ). map ( Optional :: get ). toList ();
104
124
105
125
// Try to build a toolset from tools in the PATH first.
106
126
var toolset = createToolset .apply (toolsInPath );
@@ -111,9 +131,9 @@ static WixToolset createToolset() throws ConfigException {
111
131
// Look up for WiX tools in known locations.
112
132
var toolsInKnownWiXDirs = findWixInstallDirs ().stream ().map (dir -> {
113
133
return Stream .of (values ()).map (tool -> {
114
- return new ToolLookupResult (tool , dir );
134
+ return ToolLookupResult . lookup (tool , Optional . of ( dir ) );
115
135
});
116
- }).flatMap (Function .identity ()).toList ();
136
+ }).flatMap (Function .identity ()).filter ( Optional :: isPresent ). map ( Optional :: get ). toList ();
117
137
118
138
// Build a toolset found in the PATH and in known locations.
119
139
var allFoundTools = Stream .of (toolsInPath , toolsInKnownWiXDirs ).flatMap (List ::stream ).filter (
@@ -128,8 +148,8 @@ static WixToolset createToolset() throws ConfigException {
128
148
var toolOldVerErr = allFoundTools .stream ().map (lookupResult -> {
129
149
if (lookupResult .versionTooOld ) {
130
150
return new ConfigException (MessageFormat .format (I18N .getString (
131
- "message.wrong-tool-version" ), lookupResult .getInfo ().path ,
132
- lookupResult .getInfo ().version , lookupResult .getTool ().minimalVersion ),
151
+ "message.wrong-tool-version" ), lookupResult .info ().path () ,
152
+ lookupResult .info ().version () , lookupResult .tool ().minimalVersion ),
133
153
I18N .getString ("error.no-wix-tools.advice" ));
134
154
} else {
135
155
return null ;
@@ -144,11 +164,18 @@ static WixToolset createToolset() throws ConfigException {
144
164
}
145
165
}
146
166
147
- private static class ToolLookupResult {
167
+ private record ToolLookupResult (WixTool tool , ToolInfo info , boolean versionTooOld ) {
168
+
169
+ ToolLookupResult {
170
+ Objects .requireNonNull (tool );
171
+ Objects .requireNonNull (info );
172
+ }
148
173
149
- ToolLookupResult (WixTool tool , Path lookupDir ) {
174
+ static Optional <ToolLookupResult > lookup (WixTool tool , Optional <Path > lookupDir ) {
175
+ Objects .requireNonNull (tool );
176
+ Objects .requireNonNull (lookupDir );
150
177
151
- final Path toolPath = Optional . ofNullable ( lookupDir ) .map (p -> p .resolve (
178
+ final Path toolPath = lookupDir .map (p -> p .resolve (
152
179
tool .toolFileName )).orElse (tool .toolFileName );
153
180
154
181
final boolean [] tooOld = new boolean [1 ];
@@ -165,7 +192,19 @@ private static class ToolLookupResult {
165
192
final Function <Stream <String >, String > versionParser ;
166
193
167
194
if (Set .of (Candle3 , Light3 ).contains (tool )) {
168
- validator .setCommandLine ("/?" );
195
+ final String printVersionArg ;
196
+ if (tool == Candle3 ) {
197
+ // Add '-fips' to make "candle.exe" print help message and return
198
+ // 0 exit code instead of returning error exit code and printing
199
+ // "error CNDL0308 : The Federal Information Processing Standard (FIPS) appears to be enabled on the machine..."
200
+ // error message if FIPS is enabled.
201
+ // If FIPS is disabled, passing '-fips' parameter still makes
202
+ // "candle.exe" print help message and return 0 exit code.
203
+ printVersionArg = "-fips" ;
204
+ } else {
205
+ printVersionArg = "-?" ;
206
+ }
207
+ validator .setCommandLine (printVersionArg );
169
208
versionParser = output -> {
170
209
String firstLineOfOutput = output .findFirst ().orElse ("" );
171
210
int separatorIdx = firstLineOfOutput .lastIndexOf (' ' );
@@ -186,36 +225,35 @@ private static class ToolLookupResult {
186
225
return parsedVersion [0 ];
187
226
});
188
227
189
- this .tool = tool ;
190
228
if (validator .validate () == null ) {
191
229
// Tool found
192
- this .versionTooOld = tooOld [0 ];
193
- this .info = new ToolInfo (toolPath , parsedVersion [0 ]);
230
+ ToolInfo info = new DefaultToolInfo (toolPath , parsedVersion [0 ]);
231
+ if (tool == Candle3 ) {
232
+ // Detect FIPS mode
233
+ var fips = false ;
234
+ try {
235
+ final var exec = Executor .of (toolPath .toString (), "-?" ).setQuiet (true ).saveOutput (true );
236
+ final var exitCode = exec .execute ();
237
+ if (exitCode != 0 /* 308 */ ) {
238
+ final var output = exec .getOutput ();
239
+ if (!output .isEmpty () && output .get (0 ).contains ("error CNDL0308" )) {
240
+ fips = true ;
241
+ }
242
+ }
243
+ } catch (IOException ex ) {
244
+ Log .verbose (ex );
245
+ }
246
+ info = new DefaultCandleInfo (info , fips );
247
+ }
248
+ return Optional .of (new ToolLookupResult (tool , info , tooOld [0 ]));
194
249
} else {
195
- this .versionTooOld = false ;
196
- this .info = null ;
250
+ return Optional .empty ();
197
251
}
198
252
}
199
253
200
- WixTool getTool () {
201
- return tool ;
202
- }
203
-
204
- ToolInfo getInfo () {
205
- return info ;
206
- }
207
-
208
254
boolean isValid () {
209
- return info != null && !versionTooOld ;
255
+ return !versionTooOld ;
210
256
}
211
-
212
- boolean isVersionTooOld () {
213
- return versionTooOld ;
214
- }
215
-
216
- private final WixTool tool ;
217
- private final ToolInfo info ;
218
- private final boolean versionTooOld ;
219
257
}
220
258
221
259
private static Path getSystemDir (String envVar , String knownDir ) {
0 commit comments