Skip to content

Commit

Permalink
Merge pull request orphan-oss#341 from Lilianne-Blaze/patch3-require-…
Browse files Browse the repository at this point in the history
…admin1

"Require admin rights" option for Windows exes
  • Loading branch information
lukaszlenart authored Jan 15, 2024
2 parents 9e01ec4 + 39b20ec commit c3a9f46
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/main/java/com/akathist/maven/plugins/launch4j/FileUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.akathist.maven.plugins.launch4j;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public final class FileUtils {

public static final int DEF_BUF_SIZE = 4 * 1024;

public static byte[] readResourceAsBytes(String resName) throws IOException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ByteArrayOutputStream baos = new ByteArrayOutputStream(4 * 1024);
InputStream is = cl.getResourceAsStream(resName);

return readAllBytes(is);
}

public static byte[] readBytes(File inFile) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(inFile);
BufferedInputStream bis = new BufferedInputStream(fis);

return readAllBytes(bis);
}

public static byte[] readAllBytes(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte buf[] = new byte[DEF_BUF_SIZE];
int bytesRead = 0;
while ((bytesRead = is.read(buf)) != -1) {
baos.write(buf, 0, bytesRead);
}

return baos.toByteArray();
}

public static void writeBytesIfDiff(File outFile, byte[] outBytes) throws IOException {
if (outFile.exists()) {
byte[] existingBytes = readBytes(outFile);
if (Arrays.equals(outBytes, existingBytes)) {
return;
}
}
writeBytes(outFile, outBytes);
}

public static void writeBytes(File outFile, byte[] outBytes) throws IOException {
try (
FileOutputStream fos = new FileOutputStream(outFile, false);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
bos.write(outBytes);
bos.flush();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
Expand All @@ -78,6 +79,12 @@ public class Launch4jMojo extends AbstractMojo {
@Parameter(defaultValue = "net.sf.launch4j", required = true)
private String launch4jGroupId;

// intentionally non-static non-final so it can be hacked with reflection if someone really needs to
private String DEF_REQADMMAN_RES = "META-INF/resources/manifest-requireAdminRights-v1.xml";

// intentionally non-static non-final so it can be hacked with reflection if someone really needs to
private String DEF_REQADMMAN_FILE = "target/classes/META-INF/manifest-requireAdminRights.xml";

/**
* Maven Session.
*/
Expand Down Expand Up @@ -239,6 +246,12 @@ public class Launch4jMojo extends AbstractMojo {
@Parameter
private File icon;

/**
* Whether the executable should ask for admin rights (Windows only).
*/
@Parameter(defaultValue = "false")
private boolean requireAdminRights;

/**
* Object files to include. Used for custom headers only.
*/
Expand Down Expand Up @@ -351,6 +364,8 @@ private void doExecute() throws MojoExecutionException {
return;
}

processRequireAdminRights();

fillSensibleJreDefaults();

if (!disableVersionInfoDefaults) {
Expand Down Expand Up @@ -506,6 +521,37 @@ private void fillSensibleJreDefaults() throws MojoExecutionException {
}
}

private void processRequireAdminRights() throws MojoExecutionException {
if (requireAdminRights) {
getLog().warn("Modifying the resulting exe to always require Admin rights.");
getLog().warn("Make sure it's necessary. Consider writing your own manifest file.");

if (manifest != null) {
getLog().warn("manifest param is already set, overriding. Make sure that's what's intended.");
}

try {
File metaInfDir = new File(basedir, "target/classes/META-INF");
metaInfDir.mkdir();

File manFile = new File(basedir, DEF_REQADMMAN_FILE);
byte[] manBytes = FileUtils.readResourceAsBytes(DEF_REQADMMAN_RES);

FileUtils.writeBytesIfDiff(manFile, manBytes);

byte[] savedBytes = FileUtils.readBytes(manFile);
if (Arrays.equals(manBytes, savedBytes)) {
getLog().info("Manifest file written to " + manFile);
}

manifest = manFile;
} catch (Exception e) {
getLog().error(e);
throw new MojoExecutionException(e);
}
}
}

/**
* Prepares a little directory for launch4j to do its thing. Launch4j needs a bunch of object files
* (in the w32api and head directories) and the ld and windres binaries (in the bin directory).
Expand Down Expand Up @@ -904,6 +950,7 @@ public String toString() {
", stayAlive=" + stayAlive +
", restartOnCrash=" + restartOnCrash +
", icon=" + icon +
", requireAdminRights=" + requireAdminRights +
", objs=" + objs +
", libs=" + libs +
", vars=" + vars +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public void testPrintOutFulfilledConfiguration() throws Exception {
"stayAlive=false, " +
"restartOnCrash=false, " +
"icon=null, " +
"requireAdminRights=false, " +
"objs=null, " +
"libs=null, " +
"vars=null, " +
Expand Down

0 comments on commit c3a9f46

Please sign in to comment.