Tuesday, January 14, 2020

Creating symbolic links on network shares requires the privilege on the remote host

Someone asked on Super User how to create symbolic links on network shares. Trying to create one with mklink, even after adjusting symlink evaluation settings with fsutil, failed with an access-denied error. This is because Windows requires a privilege to create a symbolic link, both on the computer issuing the command and the one hosting the network share. That is, the user one connects to the share host as must hold the "create symbolic links" privilege on that host. The privilege can be assigned in the Local Security Policy snap-in (secpol.msc).

Saturday, January 11, 2020

Atrophied shutdown.exe feature: the /unexpected switch

While disassembling shutdown.exe for reasons, I noticed special handling of the /i (interactive switch). That was expected based on the documentation's note that it must be the first switch, but after those checks there was also special handling of an /unexpected switch. Supplying it, at least on my machine, always results in this message:

Failed to open UI.

I can't find any documentation of an "unexpected" switch and it's not clear to me what it would do.

Thursday, January 9, 2020

EA Async Gradle plugin

A couple weeks ago I came across EA Async, which transforms Java methods containing "await" calls into a series of asynchronous, non-blocking tasks. This makes it easier to write nice asynchronous code for the JVM. EA Async can perform the transformation at runtime via a Java agent, at build time via a command-line utility, or at build time via a Maven plugin. Using a build system plugin integrates the transformation into the normal development workflow, which is very convenient. Of course, since there's only a Maven plugin, only users of the Maven build system got this benefit.

I like Gradle, another very widely used build system. So yesterday and today I went ahead with writing a Gradle plugin for EA Async. It was a little tricky to build a Gradle plugin with their Maven project, but once I got it compiling it was fairly straightforward thanks to my work on other Gradle plugins. There was a subtlety in taking advantage of the transformer's support for custom CompletionStage implementations. Their class files needed to be accessible through the classloader passed to the transformer, so I had to involve the compilation task's classpath and its output directory to make sure the CompletionStage implementations in the target project were recognized.

I made a pull request today which was merged. The plugin will probably be published in the next EA Async release.

Wednesday, January 8, 2020

Building Gradle plugins with Maven

Today I started writing a Gradle plugin module for a project that uses Maven as its build system. I know it's possible, with some fiddling, to involve a Gradle build in a Maven setup, but this project is managed by someone else and I wanted to stay with their preferred technology as much as possible.

Since Gradle plugins are ultimately just JARs, it's possible to compile them with Maven. Of course, this loses Gradle's convenient facilitation of writing Gradle plugins. Specifically, you need to add various dependencies yourself rather than just using gradleApi(). These <dependency>s generally look like:

<groupId>org.gradle</groupId>
<artifactId>gradle-something</artifactId>
<version>5.6.4</version>
<scope>provided</scope>

I'm currently using version 5.6.4 because it's the latest version of the Gradle 5 series, which supported by Android Studio and used by a lot of projects. The "provided" scope makes it used only for compilation, never bundled with the plugin. You may also need a reference to Groovy.

The various types are spread across quite a few artifacts. For a pretty straightforward plugin (doing some extra stuff with the results of Java compilation), I needed dependencies on gradle-core, gradle-core-api, gradle-base-services, gradle-model-core, gradle-language-jvm, gradle-language-java, gradle-platform-jvm, gradle-plugins, and gradle-tooling-api. To determine which artifact provides a class the compiler can't find, you can search the Gradle monorepository.

For adding the plugin metadata, the properties file can go in the same place under resources/META-INF that it would with a Gradle build.

Tuesday, January 7, 2020

Policy Plus - More list UI fixes

The list policy element might be the most finicky part of Policy Plus. Today I received an issue report from a user stating that adding entries to a list in a certain policy failed to make the policy Enabled. That specific policy had no affected Registry entries of its own, only a key populated by the list element. Since the list element was set to clear all existing values, it was always interpreted as evidence in favor of the Disabled policy state. I corrected this by also checking for list entries, which are evidence in favor of the Enabled state.

While investigating that specific policy, I found a problem in the Element Inspector. Even though the list element had a prefix attribute (albeit an empty one), the inspector said "no prefix." I corrected the conditional.

Monday, January 6, 2020

Windows RAID will be extremely slow when resynchronizing

A while ago I was called in to look at a server that was performing very slowly. Disk-bound operations were primarily affected. This server uses Windows RAID for redundancy and the mirror was in the process of resynchronizing. (It had recently lost power unexpectedly.) I suspect it was checking the entire volume for consistency, which uses a lot of I/O and slows down everything else trying to use the disk.

Sunday, January 5, 2020

Policy Plus - REG file tolerance

I got a report from a Policy Plus user that the Import REG feature could not handle comments. This is true; I wrote the REG parser for exactly the format emitted by the Registry Editor. Even whitespace differences could cause parse failures. So to make it easier to manually write REG files used by Policy Plus, I adjusted that parser. Comments and extra blank lines are now allowed.

I also happened to notice that searching for a certain policy made the search dialog say it found a hit but not actually display a result. Apparently I had only put the list-updating code in the progress-update, not completion, handler. So up to 19 policies could never be shown in the search results. I fixed that with a tweak to the search dialog.